|
|
|
@ -22,10 +22,6 @@ render_object * allocateRenderObject(uint buffer_len, uint index_len = 0); |
|
|
|
void freeRenderObject(render_object* ro); |
|
|
|
void freeRenderObject(render_object* ro); |
|
|
|
bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals); |
|
|
|
bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals); |
|
|
|
void sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target); |
|
|
|
void sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target); |
|
|
|
void drawRenderObject(render_group* rg, render_object* ro, |
|
|
|
|
|
|
|
glm::mat4 model_matrix, glm::mat4 view_matrix, glm::mat4 projection_matrix, |
|
|
|
|
|
|
|
rg_point_light* lights, uint num_lights, |
|
|
|
|
|
|
|
bool update_vertex_data, bool update_color_data); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// interface
|
|
|
|
// interface
|
|
|
|
@ -158,10 +154,75 @@ rgDraw(render_group* rg, glm::mat4 model_matrix, |
|
|
|
bool update_vertex_data, bool update_color_data) |
|
|
|
bool update_vertex_data, bool update_color_data) |
|
|
|
{ |
|
|
|
{ |
|
|
|
for (uint i = 0; i < rg->num_objects; i++) { |
|
|
|
for (uint i = 0; i < rg->num_objects; i++) { |
|
|
|
drawRenderObject(rg, rg->render_objects[i], |
|
|
|
render_object* ro = rg->render_objects[i]; |
|
|
|
model_matrix, view_matrix, projection_matrix, |
|
|
|
|
|
|
|
lights, num_lights, |
|
|
|
glUseProgram(rg->shader.program_id); |
|
|
|
update_vertex_data, update_color_data); |
|
|
|
glUniformMatrix4fv(rg->shader.model_matrix_id, 1, GL_FALSE, &model_matrix[0][0]); |
|
|
|
|
|
|
|
glUniformMatrix4fv(rg->shader.view_matrix_id, 1, GL_FALSE, &view_matrix[0][0]); |
|
|
|
|
|
|
|
glUniformMatrix4fv(rg->shader.projection_matrix_id, 1, GL_FALSE, &projection_matrix[0][0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1st attribute buffer : vertices
|
|
|
|
|
|
|
|
glEnableVertexAttribArray(0); |
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, ro->vertex_buffer.buffer_id); |
|
|
|
|
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (update_vertex_data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, ro->vertex_buffer.buffer_len * sizeof(GLfloat), |
|
|
|
|
|
|
|
ro->vertex_buffer.buffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2nd attribute buffer : colors
|
|
|
|
|
|
|
|
if (ro->color_buffer.buffer) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
glEnableVertexAttribArray(1); |
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, ro->color_buffer.buffer_id); |
|
|
|
|
|
|
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (update_color_data) { |
|
|
|
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, ro->color_buffer.buffer_len * sizeof(GLfloat), |
|
|
|
|
|
|
|
ro->color_buffer.buffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3rd attribute buffer: normals
|
|
|
|
|
|
|
|
if (rg->use_normals) { |
|
|
|
|
|
|
|
glEnableVertexAttribArray(2); |
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, ro->normal_buffer.buffer_id); |
|
|
|
|
|
|
|
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glm::mat3 normal_matrix = glm::transpose(glm::inverse(glm::mat3(model_matrix))); |
|
|
|
|
|
|
|
glUniformMatrix3fv(rg->shader.normal_matrix_id, 1, GL_FALSE, &normal_matrix[0][0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: use Uniform Buffer Objects to update light data
|
|
|
|
|
|
|
|
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_uniform_buffer_object.txt
|
|
|
|
|
|
|
|
// https://www.khronos.org/opengl/wiki/Uniform_Buffer_Objects
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glUniform1ui(rg->shader.num_lights_id, num_lights); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < num_lights; i++) { |
|
|
|
|
|
|
|
// TODO: don't do this every frame * every render_group
|
|
|
|
|
|
|
|
std::stringstream ss; |
|
|
|
|
|
|
|
ss << "lights[" << i << "].position"; |
|
|
|
|
|
|
|
int light_pos_loc = glGetUniformLocation(rg->shader.program_id, ss.str().c_str()); |
|
|
|
|
|
|
|
glUniform3fv(light_pos_loc, 1, &lights[i].position[0]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// draw
|
|
|
|
|
|
|
|
if (rg->draw_indexed) { |
|
|
|
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ro->index_buffer.buffer_id); |
|
|
|
|
|
|
|
glDrawElements(rg->draw_mode, ro->index_buffer.buffer_len, GL_UNSIGNED_INT, 0); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
glDrawArrays(rg->draw_mode, 0, ro->vertex_buffer.buffer_len / 3); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cleanup
|
|
|
|
|
|
|
|
glDisableVertexAttribArray(0); |
|
|
|
|
|
|
|
if (ro->color_buffer.buffer) |
|
|
|
|
|
|
|
glDisableVertexAttribArray(1); |
|
|
|
|
|
|
|
if (rg->use_normals) |
|
|
|
|
|
|
|
glDisableVertexAttribArray(2); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -289,77 +350,3 @@ convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
drawRenderObject(render_group* rg, render_object* ro, |
|
|
|
|
|
|
|
glm::mat4 model_matrix, glm::mat4 view_matrix, glm::mat4 projection_matrix, |
|
|
|
|
|
|
|
rg_point_light* lights, uint num_lights, |
|
|
|
|
|
|
|
bool update_vertex_data, bool update_color_data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
glUseProgram(rg->shader.program_id); |
|
|
|
|
|
|
|
glUniformMatrix4fv(rg->shader.model_matrix_id, 1, GL_FALSE, &model_matrix[0][0]); |
|
|
|
|
|
|
|
glUniformMatrix4fv(rg->shader.view_matrix_id, 1, GL_FALSE, &view_matrix[0][0]); |
|
|
|
|
|
|
|
glUniformMatrix4fv(rg->shader.projection_matrix_id, 1, GL_FALSE, &projection_matrix[0][0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1st attribute buffer : vertices
|
|
|
|
|
|
|
|
glEnableVertexAttribArray(0); |
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, ro->vertex_buffer.buffer_id); |
|
|
|
|
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (update_vertex_data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, ro->vertex_buffer.buffer_len * sizeof(GLfloat), |
|
|
|
|
|
|
|
ro->vertex_buffer.buffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2nd attribute buffer : colors
|
|
|
|
|
|
|
|
if (ro->color_buffer.buffer) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
glEnableVertexAttribArray(1); |
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, ro->color_buffer.buffer_id); |
|
|
|
|
|
|
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (update_color_data) { |
|
|
|
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, ro->color_buffer.buffer_len * sizeof(GLfloat), |
|
|
|
|
|
|
|
ro->color_buffer.buffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3rd attribute buffer: normals
|
|
|
|
|
|
|
|
if (rg->use_normals) { |
|
|
|
|
|
|
|
glEnableVertexAttribArray(2); |
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, ro->normal_buffer.buffer_id); |
|
|
|
|
|
|
|
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glm::mat3 normal_matrix = glm::transpose(glm::inverse(glm::mat3(model_matrix))); |
|
|
|
|
|
|
|
glUniformMatrix3fv(rg->shader.normal_matrix_id, 1, GL_FALSE, &normal_matrix[0][0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: use Uniform Buffer Objects to update light data
|
|
|
|
|
|
|
|
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_uniform_buffer_object.txt
|
|
|
|
|
|
|
|
// https://www.khronos.org/opengl/wiki/Uniform_Buffer_Objects
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glUniform1ui(rg->shader.num_lights_id, num_lights); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < num_lights; i++) { |
|
|
|
|
|
|
|
// TODO: don't do this every frame * every render_group
|
|
|
|
|
|
|
|
std::stringstream ss; |
|
|
|
|
|
|
|
ss << "lights[" << i << "].position"; |
|
|
|
|
|
|
|
int light_pos_loc = glGetUniformLocation(rg->shader.program_id, ss.str().c_str()); |
|
|
|
|
|
|
|
glUniform3fv(light_pos_loc, 1, &lights[i].position[0]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// draw
|
|
|
|
|
|
|
|
if (rg->draw_indexed) { |
|
|
|
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ro->index_buffer.buffer_id); |
|
|
|
|
|
|
|
glDrawElements(rg->draw_mode, ro->index_buffer.buffer_len, GL_UNSIGNED_INT, 0); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
glDrawArrays(rg->draw_mode, 0, ro->vertex_buffer.buffer_len / 3); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cleanup
|
|
|
|
|
|
|
|
glDisableVertexAttribArray(0); |
|
|
|
|
|
|
|
if (ro->color_buffer.buffer) |
|
|
|
|
|
|
|
glDisableVertexAttribArray(1); |
|
|
|
|
|
|
|
if (rg->use_normals) |
|
|
|
|
|
|
|
glDisableVertexAttribArray(2); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|