medfall

A super great game engine
Log | Files | Refs

commit d3711e465ff5c913f6a5935e0765bc7ec58a6c7a
parent c8072885e0efdb9c074a4457d4bf170e8c6212ba
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat Oct  7 11:57:18 +0300

Some cleanup

Diffstat:
renderer.cc | 437++++++++++++++++++++++++++++++++++++++-----------------------------------------
renderer.h | 4----
2 files changed, 208 insertions(+), 233 deletions(-)
diff --git a/renderer.cc b/renderer.cc @@ -83,30 +83,6 @@ static FramebufferObject previous_fbo; static u32 previous_viewport_width; static u32 previous_viewport_height; -static void bind_fb( FB fb ) { - if( fb.fbo != previous_fbo ) { - glBindFramebuffer( GL_DRAW_FRAMEBUFFER, fb.fbo ); - previous_fbo = fb.fbo; - - u32 viewport_width, viewport_height; - if( fb.fbo == 0 ) { - v2u32 window_size = get_window_size(); - viewport_width = window_size.x; - viewport_height = window_size.y; - } - else { - viewport_width = fb.width; - viewport_height = fb.height; - } - - if( viewport_width != previous_viewport_width || viewport_height != previous_viewport_height ) { - previous_viewport_width = viewport_width; - previous_viewport_height = viewport_height; - glViewport( 0, 0, viewport_width, viewport_height ); - } - } -} - void renderer_init() { glGenBuffers( 1, &uniforms ); glBindBuffer( GL_UNIFORM_BUFFER, uniforms ); @@ -147,8 +123,188 @@ void renderer_begin_frame() { uniforms_offset = 0; } -static void renderer_draw_mesh_( const Mesh & mesh, const RenderState & state ); -static void renderer_draw_instances_( const Mesh & mesh, const RenderState & state, u32 num_instances, VB instance_data ); +static GLenum depthfunc_to_glenum( DepthFunc depth_func ) { + switch( depth_func ) { + case DEPTHFUNC_LESS: return GL_LESS; + case DEPTHFUNC_EQUAL: return GL_EQUAL; + case DEPTHFUNC_ALWAYS: return GL_ALWAYS; + case DEPTHFUNC_DISABLED: return GL_ALWAYS; + } + + FATAL( "unsupported DepthFunc: {}", depth_func ); + return GL_INVALID_ENUM; +} + +static GLenum primitivetype_to_glenum( PrimitiveType primitive_type ) { + switch( primitive_type ) { + case PRIMITIVETYPE_TRIANGLES: return GL_TRIANGLES; + case PRIMITIVETYPE_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP; + case PRIMITIVETYPE_POINTS: return GL_POINTS; + case PRIMITIVETYPE_LINES: return GL_LINES; + } + + FATAL( "unsupported PrimitiveType: {}", primitive_type ); + return GL_INVALID_ENUM; +} + +static bool operator!=( UniformBinding a, UniformBinding b ) { + return a.offset != b.offset || a.size != b.size; +} + +static void set_render_state( const RenderState & state ) { + if( state.shader != previous_render_state.shader ) { + glUseProgram( state.shader ); + } + + // uniforms + for( GLuint i = 0; i < RENDERER_MAX_UNIFORMS; i++ ) { + if( state.uniforms[ i ] != previous_render_state.uniforms[ i ] ) { + UniformBinding binding = state.uniforms[ i ]; + if( binding.size == 0 ) { + glBindBufferBase( GL_UNIFORM_BUFFER, i, 0 ); + } + else { + glBindBufferRange( GL_UNIFORM_BUFFER, i, uniforms, binding.offset, binding.size ); + } + } + } + + // textures + for( GLuint i = 0; i < RENDERER_MAX_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++ ) { + 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 + 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 != previous_render_state.cull_face ) { + if( state.cull_face == CULLFACE_DISABLED ) { + glDisable( GL_CULL_FACE ); + } + else { + if( previous_render_state.cull_face == CULLFACE_DISABLED ) { + 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 != previous_render_state.depth_func ) { + if( state.depth_func == DEPTHFUNC_DISABLED ) { + glDisable( GL_DEPTH_TEST ); + } + else { + if( previous_render_state.depth_func == DEPTHFUNC_DISABLED ) { + glEnable( GL_DEPTH_TEST ); + } + glDepthFunc( depthfunc_to_glenum( state.depth_func ) ); + } + } + + // alpha blending + 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 != previous_render_state.wireframe ) { + if( state.wireframe ) { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + glEnable( GL_POLYGON_OFFSET_LINE ); + glPolygonOffset( -1, -1 ); + } + else { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glDisable( GL_POLYGON_OFFSET_LINE ); + } + } + + previous_render_state = state; +} + +static void bind_fb( FB fb ) { + if( fb.fbo != previous_fbo ) { + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, fb.fbo ); + previous_fbo = fb.fbo; + + u32 viewport_width, viewport_height; + if( fb.fbo == 0 ) { + v2u32 window_size = get_window_size(); + viewport_width = window_size.x; + viewport_height = window_size.y; + } + else { + viewport_width = fb.width; + viewport_height = fb.height; + } + + if( viewport_width != previous_viewport_width || viewport_height != previous_viewport_height ) { + previous_viewport_width = viewport_width; + previous_viewport_height = viewport_height; + glViewport( 0, 0, viewport_width, viewport_height ); + } + } +} + +static void drawcall_single( const Mesh & mesh, const RenderState & state ) { + set_render_state( state ); + + glBindVertexArray( mesh.vao ); + GLenum primitive = primitivetype_to_glenum( mesh.primitive_type ); + if( mesh.indices != 0 ) { + glDrawElements( primitive, mesh.num_vertices, GL_UNSIGNED_INT, 0 ); + } + else { + glDrawArrays( primitive, 0, mesh.num_vertices ); + } + glBindVertexArray( 0 ); +} + +static void drawcall_instanced( const Mesh & mesh, const RenderState & state, u32 num_instances, VB instance_data ) { + set_render_state( state ); + + glBindVertexArray( mesh.vao ); + glBindBuffer( GL_ARRAY_BUFFER, instance_data ); + + for( int i = 0; i < 4; i++ ) { + GLuint loc = ATTR_MODEL_TO_WORLD_COL0 + i; + glEnableVertexAttribArray( loc ); + glVertexAttribPointer( loc, 4, GL_FLOAT, GL_FALSE, sizeof( m4 ), ( GLvoid * ) ( i * sizeof( v4 ) ) ); + glVertexAttribDivisor( loc, 1 ); + } + + GLenum primitive = primitivetype_to_glenum( mesh.primitive_type ); + if( mesh.indices != 0 ) { + glDrawElementsInstanced( primitive, mesh.num_vertices, GL_UNSIGNED_INT, 0, checked_cast< s32 >( num_instances ) ); + } + else { + glDrawArraysInstanced( primitive, 0, mesh.num_vertices, checked_cast< s32 >( num_instances ) ); + } + + glBindVertexArray( 0 ); +} void renderer_end_frame() { ASSERT( !in_pass ); @@ -169,10 +325,10 @@ void renderer_end_frame() { for( const DrawCall & dc : draw_calls.slice( pass.begin, pass.one_past_end ) ) { if( dc.num_instances == 0 ) { - renderer_draw_mesh_( dc.mesh, dc.render_state ); + drawcall_single( dc.mesh, dc.render_state ); } else { - renderer_draw_instances_( dc.mesh, dc.render_state, dc.num_instances, dc.instance_data ); + drawcall_instanced( dc.mesh, dc.render_state, dc.num_instances, dc.instance_data ); } } } @@ -216,33 +372,6 @@ void renderer_end_frame() { } } -u32 renderer_num_draw_calls() { - return draw_calls_this_frame; -} - -u32 renderer_num_vertices() { - return vertices_this_frame; -} - -UniformBinding renderer_upload_uniforms( const void * data, size_t size, size_t alignment ) { - alignment = max( alignment, ubo_offset_alignment ); - - UniformBinding binding; - binding.offset = checked_cast< u32 >( align_power_of_2( uniforms_offset, alignment ) ); - binding.size = checked_cast< u32 >( size ); - - size_t new_uniforms_offset = binding.offset + binding.size; - ASSERT( new_uniforms_offset < UNIFORM_BUFFER_SIZE ); - - // memset so we don't leave any gaps. good for write combined memory! - memset( uniforms_buffer + uniforms_offset, 0, binding.offset - uniforms_offset ); - memcpy( uniforms_buffer + binding.offset, data, size ); - - uniforms_offset = new_uniforms_offset; - - return binding; -} - void renderer_begin_pass( FB render_target, ClearColourBool clear_colour, ClearDepthBool clear_depth ) { ASSERT( !in_pass ); in_pass = true; @@ -273,26 +402,35 @@ void renderer_end_pass() { render_passes.append( current_render_pass ); } +u32 renderer_num_draw_calls() { + return draw_calls_this_frame; +} + +u32 renderer_num_vertices() { + return vertices_this_frame; +} + Texture renderer_blue_noise() { return blue_noise; } -void renderer_begin_frame( ClearColourBool clear_colour, ClearDepthBool clear_depth ) { - GLbitfield clear_mask = 0; - if( clear_colour == RENDERER_CLEAR_COLOUR_DO ) { - clear_mask |= GL_COLOR_BUFFER_BIT; - } - if( clear_depth == RENDERER_CLEAR_DEPTH_DO ) { - clear_mask |= GL_DEPTH_BUFFER_BIT; - } - if( clear_mask != 0 ) { - glClear( clear_mask ); - } +UniformBinding renderer_upload_uniforms( const void * data, size_t size, size_t alignment ) { + alignment = max( alignment, ubo_offset_alignment ); - GLenum error = glGetError(); - if( error != GL_NO_ERROR ) { - printf( "glGetError: %d\n", error ); - } + UniformBinding binding; + binding.offset = checked_cast< u32 >( align_power_of_2( uniforms_offset, alignment ) ); + binding.size = checked_cast< u32 >( size ); + + size_t new_uniforms_offset = binding.offset + binding.size; + ASSERT( new_uniforms_offset < UNIFORM_BUFFER_SIZE ); + + // memset so we don't leave any gaps. good for write combined memory! + memset( uniforms_buffer + uniforms_offset, 0, binding.offset - uniforms_offset ); + memcpy( uniforms_buffer + binding.offset, data, size ); + + uniforms_offset = new_uniforms_offset; + + return binding; } static GLenum bufferusage_to_glenum( BufferUsage usage ) { @@ -841,127 +979,6 @@ void renderer_delete_mesh( const Mesh & mesh ) { deletes.append( command ); } -static GLenum depthfunc_to_glenum( DepthFunc depth_func ) { - switch( depth_func ) { - case DEPTHFUNC_LESS: return GL_LESS; - case DEPTHFUNC_EQUAL: return GL_EQUAL; - case DEPTHFUNC_ALWAYS: return GL_ALWAYS; - case DEPTHFUNC_DISABLED: return GL_ALWAYS; - } - - FATAL( "unsupported DepthFunc: {}", depth_func ); - return GL_INVALID_ENUM; -} - -static GLenum primitivetype_to_glenum( PrimitiveType primitive_type ) { - switch( primitive_type ) { - case PRIMITIVETYPE_TRIANGLES: return GL_TRIANGLES; - case PRIMITIVETYPE_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP; - case PRIMITIVETYPE_POINTS: return GL_POINTS; - case PRIMITIVETYPE_LINES: return GL_LINES; - } - - FATAL( "unsupported PrimitiveType: {}", primitive_type ); - return GL_INVALID_ENUM; -} - -static bool operator!=( UniformBinding a, UniformBinding b ) { - return a.offset != b.offset || a.size != b.size; -} - -static void set_render_state( const RenderState & state ) { - if( state.shader != previous_render_state.shader ) { - glUseProgram( state.shader ); - } - - // uniforms - for( GLuint i = 0; i < RENDERER_MAX_UNIFORMS; i++ ) { - if( state.uniforms[ i ] != previous_render_state.uniforms[ i ] ) { - UniformBinding binding = state.uniforms[ i ]; - if( binding.size == 0 ) { - glBindBufferBase( GL_UNIFORM_BUFFER, i, 0 ); - } - else { - glBindBufferRange( GL_UNIFORM_BUFFER, i, uniforms, binding.offset, binding.size ); - } - } - } - - // textures - for( GLuint i = 0; i < RENDERER_MAX_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++ ) { - 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 - 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 != previous_render_state.cull_face ) { - if( state.cull_face == CULLFACE_DISABLED ) { - glDisable( GL_CULL_FACE ); - } - else { - if( previous_render_state.cull_face == CULLFACE_DISABLED ) { - 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 != previous_render_state.depth_func ) { - if( state.depth_func == DEPTHFUNC_DISABLED ) { - glDisable( GL_DEPTH_TEST ); - } - else { - if( previous_render_state.depth_func == DEPTHFUNC_DISABLED ) { - glEnable( GL_DEPTH_TEST ); - } - glDepthFunc( depthfunc_to_glenum( state.depth_func ) ); - } - } - - // alpha blending - 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 != previous_render_state.wireframe ) { - if( state.wireframe ) { - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - glEnable( GL_POLYGON_OFFSET_LINE ); - glPolygonOffset( -1, -1 ); - } - else { - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glDisable( GL_POLYGON_OFFSET_LINE ); - } - } - - previous_render_state = state; -} - void renderer_draw_mesh( const Mesh & mesh, const RenderState & render_state ) { ASSERT( in_frame && in_pass ); @@ -993,41 +1010,3 @@ void renderer_draw_instances( const Mesh & mesh, const RenderState & render_stat draw_calls_this_frame++; vertices_this_frame += mesh.num_vertices * num_instances; } - -static void renderer_draw_mesh_( const Mesh & mesh, const RenderState & state ) { - set_render_state( state ); - - glBindVertexArray( mesh.vao ); - GLenum primitive = primitivetype_to_glenum( mesh.primitive_type ); - if( mesh.indices != 0 ) { - glDrawElements( primitive, mesh.num_vertices, GL_UNSIGNED_INT, 0 ); - } - else { - glDrawArrays( primitive, 0, mesh.num_vertices ); - } - glBindVertexArray( 0 ); -} - -static void renderer_draw_instances_( const Mesh & mesh, const RenderState & state, u32 num_instances, VB instance_data ) { - set_render_state( state ); - - glBindVertexArray( mesh.vao ); - glBindBuffer( GL_ARRAY_BUFFER, instance_data ); - - for( int i = 0; i < 4; i++ ) { - GLuint loc = ATTR_MODEL_TO_WORLD_COL0 + i; - glEnableVertexAttribArray( loc ); - glVertexAttribPointer( loc, 4, GL_FLOAT, GL_FALSE, sizeof( m4 ), ( GLvoid * ) ( i * sizeof( v4 ) ) ); - glVertexAttribDivisor( loc, 1 ); - } - - GLenum primitive = primitivetype_to_glenum( mesh.primitive_type ); - if( mesh.indices != 0 ) { - glDrawElementsInstanced( primitive, mesh.num_vertices, GL_UNSIGNED_INT, 0, checked_cast< s32 >( num_instances ) ); - } - else { - glDrawArraysInstanced( primitive, 0, mesh.num_vertices, checked_cast< s32 >( num_instances ) ); - } - - glBindVertexArray( 0 ); -} diff --git a/renderer.h b/renderer.h @@ -206,10 +206,6 @@ Texture renderer_blue_noise(); UniformBinding renderer_upload_uniforms( const void * data, size_t size, size_t alignment ); -// void renderer_begin_frame( ClearColourBool clear_colour = RENDERER_CLEAR_COLOUR_DO, ClearDepthBool clear_depth = RENDERER_CLEAR_DEPTH_DO ); -// TODO: define render passes that have clear/undefined input framebuffers -#define renderer_clear renderer_begin_frame - VB renderer_new_vb( const void * data = NULL, u32 len = 0, BufferUsage usage = BUFFERUSAGE_STATIC ); void renderer_delete_vb( VB vb );