Create a class for Renderable objects
This commit is contained in:
parent
997a50eb72
commit
c3c9ab5ede
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include "common/shaderloader.hpp"
|
#include "common/shaderloader.hpp"
|
||||||
|
|
||||||
|
#include "renderable.hpp"
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
static Logger logger;
|
static Logger logger;
|
||||||
static MessageBus messager(&logger);
|
static MessageBus messager(&logger);
|
||||||
|
@ -79,22 +81,15 @@ int main(int argc, char** argv)
|
||||||
int height = 0, width = 0;
|
int height = 0, width = 0;
|
||||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||||
float fov = 45.0;
|
float fov = 45.0;
|
||||||
// Triangle example
|
|
||||||
// @see http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/
|
// Required before OpenGL Calls.
|
||||||
GLuint VertexArrayID;
|
GLuint vertex_array;
|
||||||
glGenVertexArrays(1, &VertexArrayID);
|
glGenVertexArrays(1, &vertex_array);
|
||||||
glBindVertexArray(VertexArrayID);
|
glBindVertexArray(vertex_array);
|
||||||
GLuint vertexbuffer;
|
|
||||||
// An array of 3 vectors which represents 3 vertices
|
Renderable::Object triangle = Renderable::Object(Renderable::triangle_data, sizeof(Renderable::triangle_data));
|
||||||
static const GLfloat g_vertex_buffer_data[] = {
|
Renderable::Object cube = Renderable::Object(Renderable::cube_data, sizeof(Renderable::cube_data), Renderable::cube_color, sizeof(Renderable::cube_color));
|
||||||
-1.0f, -1.0f, 0.0f,
|
cube.set_position(glm::vec3(0.f, 0.f, -5.f));
|
||||||
1.0f, -1.0f, 0.0f,
|
|
||||||
0.0f, 1.0f, 0.0f,
|
|
||||||
};
|
|
||||||
glGenBuffers(1, &vertexbuffer);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data),
|
|
||||||
g_vertex_buffer_data, GL_STATIC_DRAW);
|
|
||||||
static Console console(&messager);
|
static Console console(&messager);
|
||||||
bool show_console = false;
|
bool show_console = false;
|
||||||
|
|
||||||
|
@ -107,6 +102,9 @@ int main(int argc, char** argv)
|
||||||
static struct ShaderRegistry shader_registry;
|
static struct ShaderRegistry shader_registry;
|
||||||
loadShadersFromFile(shader_list, &shader_registry);
|
loadShadersFromFile(shader_list, &shader_registry);
|
||||||
static std::vector<RegisteredShaderProgram> shader_program_registry;
|
static std::vector<RegisteredShaderProgram> shader_program_registry;
|
||||||
|
// @BUG This is a temporary hack. When shader_program_registry is grown, the existing
|
||||||
|
// entries lose data.
|
||||||
|
shader_program_registry.reserve(10);
|
||||||
loadShaderProgramsFromFile("shaders/shader_programs.txt", &shader_registry, &shader_program_registry);
|
loadShaderProgramsFromFile("shaders/shader_programs.txt", &shader_registry, &shader_program_registry);
|
||||||
messager.registerCallback(&debug_messagebus_callback);
|
messager.registerCallback(&debug_messagebus_callback);
|
||||||
int window_height, window_width;
|
int window_height, window_width;
|
||||||
|
@ -134,6 +132,7 @@ int main(int argc, char** argv)
|
||||||
// Camera movement?
|
// Camera movement?
|
||||||
double cv_x = 0.f;
|
double cv_x = 0.f;
|
||||||
double cv_y = 0.f;
|
double cv_y = 0.f;
|
||||||
|
// This is "kind of" a pan, since it translates the point being looked at by the same value.
|
||||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
|
||||||
cv_x += camera_velocity * dt;
|
cv_x += camera_velocity * dt;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +150,7 @@ int main(int argc, char** argv)
|
||||||
auto ncla = glm::translate(glm::mat4(1.0f), camera_translation) * glm::vec4(camera_looking_at[0], camera_looking_at[1], camera_looking_at[2], 1.0f);
|
auto ncla = glm::translate(glm::mat4(1.0f), camera_translation) * glm::vec4(camera_looking_at[0], camera_looking_at[1], camera_looking_at[2], 1.0f);
|
||||||
camera_position = glm::vec3(ncp[0], ncp[1], ncp[2]);
|
camera_position = glm::vec3(ncp[0], ncp[1], ncp[2]);
|
||||||
camera_looking_at = glm::vec3(ncla[0], ncla[1], ncla[2]);
|
camera_looking_at = glm::vec3(ncla[0], ncla[1], ncla[2]);
|
||||||
|
|
||||||
view = glm::lookAt(camera_position, camera_looking_at, glm::vec3(0,1,0));
|
view = glm::lookAt(camera_position, camera_looking_at, glm::vec3(0,1,0));
|
||||||
|
|
||||||
// Process messages
|
// Process messages
|
||||||
|
@ -170,27 +170,15 @@ int main(int argc, char** argv)
|
||||||
glfwGetWindowSize(window, &window_width, &window_height);
|
glfwGetWindowSize(window, &window_width, &window_height);
|
||||||
projection = glm::perspective(glm::radians(fov), (float) window_width / (float) window_height,
|
projection = glm::perspective(glm::radians(fov), (float) window_width / (float) window_height,
|
||||||
0.1f, 100.0f);
|
0.1f, 100.0f);
|
||||||
mvp_matrix = projection * view * model_default;
|
glm::mat4 vp = projection * view;
|
||||||
// @see https://blog.conan.io/2019/06/26/An-introduction-to-the-Dear-ImGui-library.html
|
// @see https://blog.conan.io/2019/06/26/An-introduction-to-the-Dear-ImGui-library.html
|
||||||
// 1st attribute buffer : vertices
|
// 1st attribute buffer : vertices
|
||||||
GLuint p = find_shader_program_by_name("default", &shader_program_registry);
|
GLuint p = find_shader_program_by_name("default", &shader_program_registry);
|
||||||
glUseProgram(p);
|
triangle.render(vp, p);
|
||||||
GLuint matrix_id = glGetUniformLocation(p, "MVP");
|
|
||||||
glUniformMatrix4fv(matrix_id, 1, GL_FALSE, &mvp_matrix[0][0]);
|
// Draw a cube?
|
||||||
glEnableVertexAttribArray(0);
|
p = find_shader_program_by_name("color", &shader_program_registry);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
cube.render(vp, p);
|
||||||
glVertexAttribPointer(
|
|
||||||
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
|
||||||
3, // size
|
|
||||||
GL_FLOAT, // type
|
|
||||||
GL_FALSE, // normalized?
|
|
||||||
0, // stride
|
|
||||||
(void*)0 // array buffer offset
|
|
||||||
);
|
|
||||||
// Draw the triangle !
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
|
|
||||||
glDisableVertexAttribArray(0);
|
|
||||||
glUseProgram(0);
|
|
||||||
|
|
||||||
// Start the Dear ImGui frame
|
// Start the Dear ImGui frame
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
#ifndef _RENDERABLE_H_
|
||||||
|
#define _RENDERABLE_H_
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
namespace Renderable {
|
||||||
|
class Object {
|
||||||
|
public:
|
||||||
|
Object(const GLfloat * vertex_data, int vd_size, const GLfloat * color_data = 0, int cd_size = 0) {
|
||||||
|
this->vertex_buffer_data = (GLfloat *) vertex_data;
|
||||||
|
this->vertex_buffer_data_size = vd_size;
|
||||||
|
this->colour_buffer_data = (GLfloat *) color_data;
|
||||||
|
this->colour_buffer_data_size = cd_size;
|
||||||
|
this->init();
|
||||||
|
}
|
||||||
|
void init() {
|
||||||
|
if (this->vertex_buffer != 0) {
|
||||||
|
// @TODO: Delete OpenGL buffer
|
||||||
|
}
|
||||||
|
if (this->vertex_buffer_data != 0) {
|
||||||
|
glGenBuffers(1, &this->vertex_buffer);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, this->vertex_buffer_data_size,
|
||||||
|
this->vertex_buffer_data, GL_STATIC_DRAW);
|
||||||
|
printf("Vertex_buffer: %d (%d, %d)\n", this->vertex_buffer, this->vertex_buffer_data_size,
|
||||||
|
this->vertex_buffer_data_size / sizeof(GLfloat) / 3);
|
||||||
|
}
|
||||||
|
if (this->colour_buffer != 0) {
|
||||||
|
// @TODO: Delete OpenGL buffer
|
||||||
|
}
|
||||||
|
if (this->colour_buffer_data != 0) {
|
||||||
|
glGenBuffers(1, &this->colour_buffer);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, this->colour_buffer);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(this->colour_buffer_data),
|
||||||
|
this->colour_buffer_data, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void render(glm::mat4 vp, GLuint shader_program = 0) {
|
||||||
|
if (this->vertex_buffer == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glUseProgram(shader_program);
|
||||||
|
glm::mat4 mvp = vp * this->get_model_matrix();
|
||||||
|
GLuint matrix_id = glGetUniformLocation(shader_program, "MVP");
|
||||||
|
glUniformMatrix4fv(matrix_id, 1, GL_FALSE, &mvp[0][0]);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer);
|
||||||
|
glVertexAttribPointer(
|
||||||
|
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
||||||
|
3, // size
|
||||||
|
GL_FLOAT, // type
|
||||||
|
GL_FALSE, // normalized?
|
||||||
|
0, // stride
|
||||||
|
(void*)0 // array buffer offset
|
||||||
|
);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, this->vertex_buffer_data_size / sizeof(GLfloat) / 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
|
||||||
|
if (this->colour_buffer == 0) {
|
||||||
|
glDisableVertexAttribArray(0);
|
||||||
|
glUseProgram(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, this->colour_buffer);
|
||||||
|
glVertexAttribPointer(
|
||||||
|
1, // attribute. No particular reason for 1, but must match the layout in the shader.
|
||||||
|
3, // size
|
||||||
|
GL_FLOAT, // type
|
||||||
|
GL_FALSE, // normalized?
|
||||||
|
0, // stride
|
||||||
|
(void*)0 // array buffer offset
|
||||||
|
);
|
||||||
|
glDisableVertexAttribArray(0);
|
||||||
|
glDisableVertexAttribArray(1);
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
void set_position(glm::vec3 position) {
|
||||||
|
this->translation = glm::translate(glm::mat4(1.f), position);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
glm::mat4 get_model_matrix() {
|
||||||
|
return translation * rotation * scale;
|
||||||
|
}
|
||||||
|
GLuint vertex_buffer = 0;
|
||||||
|
GLuint colour_buffer = 0;
|
||||||
|
GLfloat *colour_buffer_data = 0;
|
||||||
|
int colour_buffer_data_size = 0;
|
||||||
|
GLfloat *vertex_buffer_data = 0;
|
||||||
|
int vertex_buffer_data_size = 0;
|
||||||
|
glm::mat4 translation = glm::mat4(1.f);
|
||||||
|
glm::mat4 scale = glm::mat4(1.f);
|
||||||
|
glm::mat4 rotation = glm::mat4(1.f);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GLfloat cube_data[] = {
|
||||||
|
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f, // triangle 1 : end
|
||||||
|
1.0f, 1.0f,-1.0f, // triangle 2 : begin
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f, // triangle 2 : end
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f
|
||||||
|
};
|
||||||
|
static const GLfloat cube_color[] = {
|
||||||
|
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f, // triangle 1 : end
|
||||||
|
1.0f, 1.0f,-1.0f, // triangle 2 : begin
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f, // triangle 2 : end
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f,-1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f,-1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f, 1.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GLfloat triangle_data[] = {
|
||||||
|
-1.0f, -1.0f, 0.0f,
|
||||||
|
1.0f, -1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _RENDERABLE_H_
|
|
@ -203,7 +203,7 @@ int loadShaderProgramsFromFile(const char* file_path, struct ShaderRegistry *sha
|
||||||
// Skipping, line is a comment
|
// Skipping, line is a comment
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char *line_copy = (char*) calloc(size, sizeof(char*));
|
char *line_copy = (char*) calloc(size + 1, sizeof(char*));
|
||||||
strncpy(line_copy, line, size);
|
strncpy(line_copy, line, size);
|
||||||
printf("%s\n", line_copy);
|
printf("%s\n", line_copy);
|
||||||
|
|
||||||
|
@ -277,6 +277,7 @@ int loadShadersFromFile(const char* file_path, struct ShaderRegistry *registry)
|
||||||
char *line;
|
char *line;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
const char *delim = ",";
|
const char *delim = ",";
|
||||||
|
printf("Loading shaders listed in '%s'\n", file_path);
|
||||||
fp = fopen(file_path, "r");
|
fp = fopen(file_path, "r");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -296,7 +297,7 @@ int loadShadersFromFile(const char* file_path, struct ShaderRegistry *registry)
|
||||||
// Skipping, line is a comment
|
// Skipping, line is a comment
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char *line_copy = (char*) malloc((size) * sizeof(char*));
|
char *line_copy = (char*) malloc((size+1) * sizeof(char*));
|
||||||
strncpy(line_copy, line, size);
|
strncpy(line_copy, line, size);
|
||||||
// Format <name>,<type>,<filepath>
|
// Format <name>,<type>,<filepath>
|
||||||
name = strtok(line_copy, delim);
|
name = strtok(line_copy, delim);
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 300 es
|
||||||
|
layout(location = 0) in vec3 vertexPosition_modelspace;
|
||||||
|
layout(location = 1) in vec3 vertexColor;
|
||||||
|
uniform mat4 MVP;
|
||||||
|
out mediump vec3 fragmentColor;
|
||||||
|
void main(){
|
||||||
|
gl_Position.xyz = vertexPosition_modelspace;
|
||||||
|
gl_Position.w = 1.0;
|
||||||
|
gl_Position = MVP * gl_Position;
|
||||||
|
fragmentColor = vertexColor;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#version 300 es
|
||||||
|
// the precision mediump is required in 3.0es
|
||||||
|
in mediump vec3 fragmentColor;
|
||||||
|
out mediump vec3 color;
|
||||||
|
void main(){
|
||||||
|
color = fragmentColor;
|
||||||
|
}
|
|
@ -7,4 +7,6 @@
|
||||||
# or compute.
|
# or compute.
|
||||||
#
|
#
|
||||||
defaultVertexShader,vertex,defaultVertexShader.glsl
|
defaultVertexShader,vertex,defaultVertexShader.glsl
|
||||||
|
colorVertexShader,vertex,colorVertexShader.glsl
|
||||||
fragmentRed,fragment,fragmentRed.glsl
|
fragmentRed,fragment,fragmentRed.glsl
|
||||||
|
fragmentColour,fragment,fragmentColour.glsl
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
# Each line is a program. <program_name>:<shader1>,<shader2>,...<shaderN>
|
# Each line is a program. <program_name>:<shader1>,<shader2>,...<shaderN>
|
||||||
#
|
#
|
||||||
default:defaultVertexShader,fragmentRed
|
default:defaultVertexShader,fragmentRed
|
||||||
|
color:colorVertexShader,fragmentColour
|
||||||
|
|
Loading…
Reference in New Issue