From a8b8e2f42151337ae9c338d981e821c1b521b0e3 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Sun, 15 Jul 2018 16:58:45 -0400 Subject: [PATCH] give model matrix control to shaders --- src/renderer.h | 85 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/src/renderer.h b/src/renderer.h index 5df4941..ecb54d5 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -29,10 +29,12 @@ const char * VERTEX_SHADER_CODE = "in vec3 vertexPosition_modelspace;\n" "in vec3 vertexColor;\n" "out vec3 fragmentColor;\n" - "uniform mat4 MVP;\n" + "uniform mat4 model;\n" + "uniform mat4 view;\n" + "uniform mat4 projection;\n" "void main()\n" "{\n" - " gl_Position = MVP * vec4(vertexPosition_modelspace, 1);\n" + " gl_Position = projection * view * model * vec4(vertexPosition_modelspace, 1);\n" " fragmentColor = vertexColor;\n" "}"; @@ -108,8 +110,11 @@ typedef struct gl_render_group gl_buffer vertex_buffer; gl_buffer color_buffer; GLuint program_id = 0; - GLuint matrix_id = 0; // NOTE: reference to a vertex shader's MVP matrix uniform + GLuint model_matrix_id = 0; + GLuint view_matrix_id = 0; + GLuint projection_matrix_id = 0; GLuint vertex_array_id = 0; + Entity* entity = nullptr; } gl_render_group; gl_matrix_info g_scene_matrices; @@ -133,7 +138,8 @@ void freeBuffers(); // forward declarations -bool initShaderProgram(gl_render_group &rg, const char * vertex_code, const char * frag_code, const char * mat_id); +bool initShaderProgram(gl_render_group &rg, const char * vertex_code, const char * frag_code, + const char* model_name, const char* view_name, const char* projection_name); // enable debug output https://www.khronos.org/opengl/wiki/OpenGL_Error void openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); @@ -211,11 +217,21 @@ initRenderer(SDL_Handles &handles, v2i vpDims) // hide VRAM debug messages glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE); - // TODO: check for errors when compiling shaders - initShaderProgram(g_filled_hex_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, "MVP"); - initShaderProgram(g_hex_line_render_group, VERTEX_SHADER_CODE, LINE_FRAGMENT_SHADER_CODE, "MVP"); - initShaderProgram(g_debug_render_group, VERTEX_SHADER_CODE, DEBUG_FRAGMENT_SHADER_CODE, "MVP"); - initShaderProgram(g_entity_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, "MVP"); + if (!initShaderProgram( + g_filled_hex_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, + "model", "view", "projection") + || !initShaderProgram( + g_hex_line_render_group, VERTEX_SHADER_CODE, LINE_FRAGMENT_SHADER_CODE, + "model", "view", "projection") + || !initShaderProgram( + g_debug_render_group, VERTEX_SHADER_CODE, DEBUG_FRAGMENT_SHADER_CODE, + "model", "view", "projection") + || !initShaderProgram( + g_entity_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, + "model", "view", "projection")) + { + return false; + } return true; } @@ -262,9 +278,11 @@ getUnprojectedCoords(int32 x, int32 y, int32 vp_width, int32 vp_height) return v; } -// NOTE: mat_id should match the matrix variable name in the shader source +// NOTE: model_name, view_name, and projection_name should match the matrix variable +// names in the shader source bool -initShaderProgram(gl_render_group &rg, const char * vertex_code, const char * frag_code, const char * mat_id) +initShaderProgram(gl_render_group &rg, const char * vertex_code, const char * frag_code, + const char* model_name, const char* view_name, const char* projection_name) { glGenVertexArrays(1, &rg.vertex_array_id); glBindVertexArray(rg.vertex_array_id); @@ -281,14 +299,33 @@ initShaderProgram(gl_render_group &rg, const char * vertex_code, const char * fr glAttachShader(rg.program_id, fragment_shader_id); glLinkProgram(rg.program_id); - rg.matrix_id = glGetUniformLocation(rg.program_id, mat_id); + rg.model_matrix_id = glGetUniformLocation(rg.program_id, model_name); + rg.view_matrix_id = glGetUniformLocation(rg.program_id, view_name); + rg.projection_matrix_id = glGetUniformLocation(rg.program_id, projection_name); glDetachShader(rg.program_id, vertex_shader_id); glDetachShader(rg.program_id, fragment_shader_id); glDeleteShader(vertex_shader_id); glDeleteShader(fragment_shader_id); - // TODO: check for errors when compiling shaders + // check for errors + GLint isLinked = 0; + glGetProgramiv(rg.program_id, GL_LINK_STATUS, &isLinked); + if (isLinked == GL_FALSE) { + GLint maxLength = 0; + glGetProgramiv(rg.program_id, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + GLchar infoLog[maxLength]; + glGetProgramInfoLog(rg.program_id, maxLength, &maxLength, &infoLog[0]); + LOG(ERROR) << infoLog << "\n"; + + // The program is useless now. So delete it. + glDeleteProgram(rg.program_id); + + return false; + } + return true; } @@ -413,7 +450,8 @@ createScene(std::vector* hexes, Entity* entities, uint32 entity_count) /////////////// // TODO: Testing Entities/assimp model loading - // g_entity_render_group + g_entity_render_group.entity = &entities[0]; + entities[0].model_transform = glm::scale(glm::mat4(1), glm::vec3(10, 10, 10)); uint entity_buf_len = entities[0].num_vertices * 3; GLfloat* entity_buf = (GLfloat*) std::calloc(entity_buf_len, sizeof(GLfloat)); @@ -423,7 +461,7 @@ createScene(std::vector* hexes, Entity* entities, uint32 entity_count) uint vertex_index = 0; uint vertex_prop_index = 0; GLfloat entity_test_color[3]; - convertColor(entity_test_color, 0x565656FF); + convertColor(entity_test_color, 0xF46000FF); for (uint j = 0; j < entity_buf_len; j++) { const glm::vec3& vertex = entities[0].vertices[vertex_index]; @@ -447,6 +485,10 @@ createScene(std::vector* hexes, Entity* entities, uint32 entity_count) GL_DYNAMIC_DRAW, entity_buf)) return false; + if (!initGLBufferObject(&g_entity_render_group.color_buffer, entity_buf_len, + GL_DYNAMIC_DRAW, entity_color_buf)) + return false; + std::free(entity_buf); std::free(entity_color_buf); entity_buf = entity_color_buf = nullptr; @@ -692,8 +734,17 @@ void drawRenderGroup(gl_render_group* rg, GLenum draw_mode, bool update_vertex_data = false) { glUseProgram(rg->program_id); - // Send our transformation to the currently bound shader, in the "g_MVP" uniform - glUniformMatrix4fv(rg->matrix_id, 1, GL_FALSE, &g_scene_matrices.MVP[0][0]); + + // Send our transformation to the currently bound shader + glm::mat4 model_matrix; + if (rg->entity) + model_matrix = rg->entity->model_transform; + else + model_matrix = g_scene_matrices.model; + + glUniformMatrix4fv(rg->model_matrix_id, 1, GL_FALSE, &model_matrix[0][0]); + glUniformMatrix4fv(rg->view_matrix_id, 1, GL_FALSE, &g_scene_matrices.view[0][0]); + glUniformMatrix4fv(rg->projection_matrix_id, 1, GL_FALSE, &g_scene_matrices.projection[0][0]); // 1st attribute buffer : vertices glEnableVertexAttribArray(0);