Create a class for Renderable objects

This commit is contained in:
Kienan Stewart 2020-02-25 01:58:20 -05:00
parent 997a50eb72
commit c3c9ab5ede
7 changed files with 226 additions and 36 deletions

View File

@ -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();

180
src/client/renderable.hpp Normal file
View File

@ -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_

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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