commit 891254adc8c848cc89a4b907e20dff51126a8c2b parent 8a9d2e56c0408658c3771741731b0cc7fce99f65 Author: Michael Savage <mikejsavage@gmail.com> Date: Sat Dec 24 14:35:10 +0200 Don't issue unnecessary draw calls Diffstat:
gl.cc | | | 5 | ++++- |
renderer.cc | | | 109 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
diff --git a/gl.cc b/gl.cc @@ -117,7 +117,10 @@ GLFWwindow * gl_init() { INFO( "Vendor %s", glGetString( GL_VENDOR ) ); glEnable( GL_DEPTH_TEST ); - glDepthFunc( GL_LEQUAL ); + glDepthFunc( GL_LESS ); + + glEnable( GL_CULL_FACE ); + glCullFace( GL_FRONT ); // TODO glEnable( GL_FRAMEBUFFER_SRGB ); diff --git a/renderer.cc b/renderer.cc @@ -18,30 +18,6 @@ static const GLuint ATTR_TEX_COORD0 = 2; static const GLuint ATTR_TEX_COORD1 = 3; static const GLuint ATTR_COLOUR = 4; -struct OpenGLState { - RenderState render_state; - // VB bound_vbo; - // IB bound_ebo; - UB bound_ub; - Texture bound_texture; -}; - -struct DrawCall { - DrawCallType type; - union { - struct { - void * data; - size_t len; - }; - // or Array< u8 >( data, len ); - - MeshConfig mesh_config; - ShaderConfig shader_config; - TextureConfig texture_config; - RenderState render_state; - }; -}; - void renderer_begin_frame( ClearColourBool clear_colour, ClearDepthBool clear_depth ) { if( clear_colour == CLEARCOLOUR_DO || clear_depth == CLEARDEPTH_DO ) { GLbitfield clear_mask = 0; @@ -477,65 +453,84 @@ static GLenum primitivetype_to_glenum( PrimitiveType primitive_type ) { return 0; } +static RenderState previous_render_state = { }; + void renderer_draw_mesh( const Mesh & mesh, RenderState state ) { - // TODO: check vs OpenGLState if these binds are really necessary - glUseProgram( state.shader ); + if( state.shader != previous_render_state.shader ) { + glUseProgram( state.shader ); + } glBindVertexArray( mesh.vao ); // uniforms for( GLuint i = 0; i < RENDERER_MAX_UBS; i++ ) { - glBindBufferBase( GL_UNIFORM_BUFFER, i, state.ubs[ i ] ); + if( state.ubs[ i ] != previous_render_state.ubs[ i ] ) { + glBindBufferBase( GL_UNIFORM_BUFFER, i, state.ubs[ i ] ); + } } // textures for( GLuint i = 0; i < RENDERER_MAX_TEXTURES; i++ ) { - glActiveTexture( GL_TEXTURE0 + i ); - glBindTexture( GL_TEXTURE_2D, state.textures[ i ] ); + if( state.textures[ i ] != previous_render_state.textures[ i ] ) { + glActiveTexture( GL_TEXTURE0 + i ); + glBindTexture( GL_TEXTURE_2D, state.textures[ i ] ); + } } // texture buffers for( GLuint i = 0; i < RENDERER_MAX_TEXTURE_BUFFERS; i++ ) { - glActiveTexture( GL_TEXTURE0 + i + RENDERER_MAX_TEXTURES ); - glBindTexture( GL_TEXTURE_BUFFER, state.tbs[ i ].texture ); + if( state.tbs[ i ].texture != previous_render_state.tbs[ i ].texture ) { + glActiveTexture( GL_TEXTURE0 + i + RENDERER_MAX_TEXTURES ); + glBindTexture( GL_TEXTURE_BUFFER, state.tbs[ i ].texture ); + } } // depth writing - glDepthMask( state.disable_depth_writes ? GL_FALSE : GL_TRUE ); + if( state.disable_depth_writes != previous_render_state.disable_depth_writes ) { + glDepthMask( state.disable_depth_writes ? GL_FALSE : GL_TRUE ); + } // backface culling - if( state.cull_face == CULLFACE_DISABLED ) { - glDisable( GL_CULL_FACE ); - } - else { - glEnable( GL_CULL_FACE ); - // TODO: current renderer is fucked and this should be the other way around - glCullFace( state.cull_face == CULLFACE_FRONT ? GL_BACK : GL_FRONT ); + if( state.cull_face != previous_render_state.cull_face ) { + if( state.cull_face == CULLFACE_DISABLED ) { + glDisable( GL_CULL_FACE ); + } + else { + glEnable( GL_CULL_FACE ); + // TODO: current renderer is fucked and this should be the other way around + glCullFace( state.cull_face == CULLFACE_FRONT ? GL_BACK : GL_FRONT ); + } } // depth testing - if( state.depth_func == DEPTHFUNC_DISABLED ) { - glDisable( GL_DEPTH_TEST ); - } - else { - glEnable( GL_DEPTH_TEST ); - glDepthFunc( depthfunc_to_glenum( state.depth_func ) ); + if( state.depth_func != previous_render_state.depth_func ) { + if( state.depth_func == DEPTHFUNC_DISABLED ) { + glDisable( GL_DEPTH_TEST ); + } + else { + glEnable( GL_DEPTH_TEST ); + glDepthFunc( depthfunc_to_glenum( state.depth_func ) ); + } } // alpha blending - if( state.enable_alpha_blending ) { - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - } - else { - glDisable( GL_BLEND ); + if( state.enable_alpha_blending != previous_render_state.enable_alpha_blending ) { + if( state.enable_alpha_blending ) { + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + else { + glDisable( GL_BLEND ); + } } // polygon fill mode - if( state.wireframe ) { - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - } - else { - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + if( state.wireframe != previous_render_state.wireframe ) { + if( state.wireframe ) { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + else { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } } GLenum primitive = primitivetype_to_glenum( mesh.primitive_type ); @@ -547,4 +542,6 @@ void renderer_draw_mesh( const Mesh & mesh, RenderState state ) { } glBindVertexArray( 0 ); + + previous_render_state = state; }