From 3a713dd1ed90e5aa941dc0b57ec2f08f94d10d1b Mon Sep 17 00:00:00 2001 From: milek7 Date: Thu, 3 Aug 2017 12:28:15 +0200 Subject: [PATCH] minimize calls to opengl by caching uniforms (is it worth it, though?) --- renderer.cpp | 28 ++++++++++++++-------- shader.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++-------- shader.h | 27 ++++++++++++++++------ 3 files changed, 93 insertions(+), 27 deletions(-) diff --git a/renderer.cpp b/renderer.cpp index 8b1de0e7..f6d7117b 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -659,14 +659,15 @@ opengl_renderer::Render( TGroundNode *Node ) { } // setup //m7todo: set diffuse color - shader.set_material(Node->Specular.x * m_specularopaquescalefactor, glm::vec3(0.0f)); + shader.set_material({Node->Specular.x * m_specularopaquescalefactor, glm::vec3(0.0f)}); Bind( Node->TextureID ); // render + active_shader->update(); m_geometry.draw( Node->Piece->geometry ); - shader.set_material(0.0f, glm::vec3(0.0f)); + shader.set_material({0.0f, glm::vec3(0.0f)}); return true; } @@ -804,14 +805,14 @@ void opengl_renderer::Render(TSubModel *Submodel) { active_shader->copy_gl_mvp(); Render(Submodel, OpenGLMatrices.data(GL_MODELVIEW)); - shader.set_material(0.0f, glm::vec3(0.0f)); + shader.set_material({0.0f, glm::vec3(0.0f)}); } void opengl_renderer::Render_Alpha(TSubModel *Submodel) { active_shader->copy_gl_mvp();; Render_Alpha(Submodel, OpenGLMatrices.data(GL_MODELVIEW)); - shader.set_material(0.0f, glm::vec3(0.0f)); + shader.set_material({0.0f, glm::vec3(0.0f)}); } void @@ -846,8 +847,10 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) { Bind( Submodel->TextureID ); } - shader.set_material(Submodel->f4Specular.x * m_speculartranslucentscalefactor, - Global::fLuminance < Submodel->fLight ? glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a : glm::vec3(0.0f)); + shader.set_material({Submodel->f4Specular.x * m_speculartranslucentscalefactor, + Global::fLuminance < Submodel->fLight ? glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a : glm::vec3(0.0f)}); + + active_shader->update(); // main draw call m_geometry.draw( Submodel->m_geometry ); @@ -949,6 +952,8 @@ opengl_renderer::Render( TTrack *Track ) { Track->EnvironmentSet(); + active_shader->update(); + if( Track->TextureID1 != 0 ) { Bind( Track->TextureID1 ); m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) ); @@ -1125,6 +1130,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) { GfxRenderer.Bind( 0 ); // render + active_shader->update(); m_geometry.draw( Node->Piece->geometry ); // post-render cleanup @@ -1144,14 +1150,15 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) { } // setup //m7todo: set diffuse color - shader.set_material(Node->Specular.x * m_speculartranslucentscalefactor, glm::vec3(0.0f)); + shader.set_material({Node->Specular.x * m_speculartranslucentscalefactor, glm::vec3(0.0f)}); + active_shader->update(); Bind( Node->TextureID ); // render m_geometry.draw( Node->Piece->geometry ); - shader.set_material(0.0f, glm::vec3(0.0f)); + shader.set_material({0.0f, glm::vec3(0.0f)}); return true; } @@ -1306,9 +1313,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) { Bind( Submodel->TextureID ); } - shader.set_material(Submodel->f4Specular.x * m_speculartranslucentscalefactor, - Global::fLuminance < Submodel->fLight ? glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a : glm::vec3(0.0f)); + shader.set_material({Submodel->f4Specular.x * m_speculartranslucentscalefactor, + Global::fLuminance < Submodel->fLight ? glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a : glm::vec3(0.0f)}); + active_shader->update(); // main draw call m_geometry.draw(Submodel->m_geometry); } diff --git a/shader.cpp b/shader.cpp index a3fbd329..7dcd6743 100644 --- a/shader.cpp +++ b/shader.cpp @@ -141,17 +141,43 @@ void gl_program_mvp::copy_gl_mvp() void gl_program_mvp::set_mv(const glm::mat4 &m) { - if (mvn_uniform != -1) + if (m != mv) { - glm::mat3 mvn = glm::mat3(glm::transpose(glm::inverse(m))); - glUniformMatrix3fv(mvn_uniform, 1, GL_FALSE, glm::value_ptr(mvn)); + mv = m; + mv_dirty = true; } - glUniformMatrix4fv(mv_uniform, 1, GL_FALSE, glm::value_ptr(m)); } void gl_program_mvp::set_p(const glm::mat4 &m) { - glUniformMatrix4fv(p_uniform, 1, GL_FALSE, glm::value_ptr(m)); + if (m != p) + { + p = m; + p_dirty = true; + } +} + +void gl_program_mvp::update() +{ + if (current_program != this) + return; + + if (mv_dirty) + { + if (mvn_uniform != -1) + { + glm::mat3 mvn = glm::mat3(glm::transpose(glm::inverse(mv))); + glUniformMatrix3fv(mvn_uniform, 1, GL_FALSE, glm::value_ptr(mvn)); + } + glUniformMatrix4fv(mv_uniform, 1, GL_FALSE, glm::value_ptr(mv)); + mv_dirty = false; + } + + if (p_dirty) + { + glUniformMatrix4fv(p_uniform, 1, GL_FALSE, glm::value_ptr(p)); + mv_dirty = false; + } } gl_program_light::gl_program_light(std::vector v) : gl_program_mvp(v) @@ -180,15 +206,34 @@ void gl_program_light::set_lightview(const glm::mat4 &lightview) glUniformMatrix4fv(lightview_uniform, 1, GL_FALSE, glm::value_ptr(lightview)); } -void gl_program_light::set_material(float specular, const glm::vec3 &emission, const glm::vec4 &color) +void gl_program_light::set_material(const material_s &mat) { if (current_program != this) return; - glUniform1f(specular_uniform, specular); - glUniform3fv(emission_uniform, 1, glm::value_ptr(emission)); - if (color_uniform != -1) - glUniform4fv(color_uniform, 1, glm::value_ptr(color)); + if (std::memcmp(&material, &mat, sizeof(material_s))) + { + material_dirty = true; + material = mat; + } +} + +void gl_program_light::update() +{ + if (current_program != this) + return; + + gl_program_mvp::update(); + + if (material_dirty) + { + glUniform1f(specular_uniform, material.specular); + glUniform3fv(emission_uniform, 1, glm::value_ptr(material.emission)); + if (color_uniform != -1) + glUniform4fv(color_uniform, 1, glm::value_ptr(material.color)); + + material_dirty = false; + } } template diff --git a/shader.h b/shader.h index 9607b075..e2540329 100644 --- a/shader.h +++ b/shader.h @@ -41,6 +41,9 @@ class gl_program_mvp : public gl_program GLint mvn_uniform; GLuint p_uniform; + glm::mat4 mv, p; + bool mv_dirty, p_dirty; + public: gl_program_mvp() = default; gl_program_mvp(std::vector); @@ -48,6 +51,7 @@ public: void set_mv(const glm::mat4 &); void set_p(const glm::mat4 &); void copy_gl_mvp(); + virtual void update(); }; // layout std140 @@ -119,17 +123,26 @@ public: class gl_program_light : public gl_program_mvp { + GLuint lightview_uniform; + GLuint specular_uniform; + GLuint emission_uniform; + GLuint color_uniform; + + struct material_s + { + float specular; + glm::vec3 emission; + glm::vec4 color; + } material; + + bool material_dirty; + public: gl_program_light() = default; gl_program_light(std::vector); void set_lightview(const glm::mat4 &lightview); - void set_material(float specular, const glm::vec3 &emission, const glm::vec4 &color = glm::vec4(0.0f)); + void set_material(const material_s &mat); void bind_ubodata(GLuint point); - -private: - GLuint lightview_uniform; - GLuint specular_uniform; - GLuint emission_uniform; - GLuint color_uniform; + void update(); };