medfall

A super great game engine
Log | Files | Refs

commit fd7f9735c5ebf983b5f8cae9270e3b48b3c51e56
parent 6f0be43695f47b80396772406d5e289c6c243b8f
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat, 25 Nov 2017 23:03:44 +0200

Combine filler arms into one mesh to save 21 draw calls

Diffstat:
clipmap.cc | 116++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 59 insertions(+), 57 deletions(-)

diff --git a/clipmap.cc b/clipmap.cc @@ -23,8 +23,7 @@ struct ClipmapTerrain { struct { Mesh tile; Mesh empty_tile; - Mesh horizontal_filler; - Mesh vertical_filler; + Mesh filler; Mesh trim; Mesh cross; Mesh seam; @@ -268,56 +267,73 @@ GAME_INIT( game_init ) { clipmap.gpu.empty_tile = renderer_new_mesh( mesh_config ); } - // generate filler meshes + // generate filler mesh { MEMARENA_SCOPED_CHECKPOINT( &mem->persistent_arena ); - array< v3 > horizontal_vertices = alloc_array< v3 >( &mem->persistent_arena, PATCH_VERT_RESOLUTION * 2 ); - array< v3 > vertical_vertices = alloc_array< v3 >( &mem->persistent_arena, PATCH_VERT_RESOLUTION * 2 ); + array< v3 > vertices = alloc_array< v3 >( &mem->persistent_arena, PATCH_VERT_RESOLUTION * 8 ); + size_t n = 0; + u32 offset = PATCH_RESOLUTION; for( u32 i = 0; i < PATCH_VERT_RESOLUTION; i++ ) { - horizontal_vertices[ i * 2 + 0 ] = v3( i, 0, 0 ); - horizontal_vertices[ i * 2 + 1 ] = v3( i, 1, 0 ); - - vertical_vertices[ i * 2 + 0 ] = v3( 0, i, 0 ); - vertical_vertices[ i * 2 + 1 ] = v3( 1, i, 0 ); + vertices[ n++ ] = v3( offset + i + 1, 0, 0 ); + vertices[ n++ ] = v3( offset + i + 1, 1, 0 ); } - array< u32 > horizontal_indices = alloc_array< u32 >( &mem->persistent_arena, PATCH_RESOLUTION * 6 ); - array< u32 > vertical_indices = alloc_array< u32 >( &mem->persistent_arena, PATCH_RESOLUTION * 6 ); + for( u32 i = 0; i < PATCH_VERT_RESOLUTION; i++ ) { + vertices[ n++ ] = v3( 1, offset + i + 1, 0 ); + vertices[ n++ ] = v3( 0, offset + i + 1, 0 ); + } - for( u32 i = 0; i < PATCH_RESOLUTION; i++ ) { - u32 bl = i * 2 + 0; - u32 br = i * 2 + 1; - u32 tl = i * 2 + 2; - u32 tr = i * 2 + 3; + for( u32 i = 0; i < PATCH_VERT_RESOLUTION; i++ ) { + vertices[ n++ ] = v3( -float( offset + i ), 1, 0 ); + vertices[ n++ ] = v3( -float( offset + i ), 0, 0 ); + } - horizontal_indices[ i * 6 + 0 ] = br; - horizontal_indices[ i * 6 + 1 ] = bl; - horizontal_indices[ i * 6 + 2 ] = tr; - horizontal_indices[ i * 6 + 3 ] = bl; - horizontal_indices[ i * 6 + 4 ] = tl; - horizontal_indices[ i * 6 + 5 ] = tr; + for( u32 i = 0; i < PATCH_VERT_RESOLUTION; i++ ) { + vertices[ n++ ] = v3( 0, -float( offset + i ), 0 ); + vertices[ n++ ] = v3( 1, -float( offset + i ), 0 ); } - memcpy( vertical_indices.ptr(), horizontal_indices.ptr(), horizontal_indices.num_bytes() ); + ASSERT( n == vertices.n ); - for( size_t i = 0; i < vertical_indices.n; i += 6 ) { - swap( vertical_indices[ i + 0 ], vertical_indices[ i + 1 ] ); - swap( vertical_indices[ i + 4 ], vertical_indices[ i + 5 ] ); + array< u32 > indices = alloc_array< u32 >( &mem->persistent_arena, PATCH_RESOLUTION * 24 ); + n = 0; + + for( u32 i = 0; i < PATCH_RESOLUTION * 4; i++ ) { + // the arms shouldn't be connected to each other + u32 arm = i / PATCH_RESOLUTION; + + u32 bl = ( arm + i ) * 2 + 0; + u32 br = ( arm + i ) * 2 + 1; + u32 tl = ( arm + i ) * 2 + 2; + u32 tr = ( arm + i ) * 2 + 3; + + if( arm % 2 == 0 ) { + indices[ n++ ] = br; + indices[ n++ ] = bl; + indices[ n++ ] = tr; + indices[ n++ ] = bl; + indices[ n++ ] = tl; + indices[ n++ ] = tr; + } + else { + indices[ n++ ] = br; + indices[ n++ ] = bl; + indices[ n++ ] = tl; + indices[ n++ ] = br; + indices[ n++ ] = tl; + indices[ n++ ] = tr; + } } - MeshConfig horizontal_mesh_config; - horizontal_mesh_config.positions = renderer_new_vb( horizontal_vertices ); - horizontal_mesh_config.indices = renderer_new_ib( horizontal_indices ); - horizontal_mesh_config.num_vertices = horizontal_indices.n; - clipmap.gpu.horizontal_filler = renderer_new_mesh( horizontal_mesh_config ); - - MeshConfig vertical_mesh_config; - vertical_mesh_config.positions = renderer_new_vb( vertical_vertices ); - vertical_mesh_config.indices = renderer_new_ib( vertical_indices ); - vertical_mesh_config.num_vertices = vertical_indices.n; - clipmap.gpu.vertical_filler = renderer_new_mesh( vertical_mesh_config ); + ASSERT( n == indices.n ); + + MeshConfig mesh_config; + mesh_config.positions = renderer_new_vb( vertices ); + mesh_config.indices = renderer_new_ib( indices ); + mesh_config.num_vertices = indices.n; + clipmap.gpu.filler = renderer_new_mesh( mesh_config ); } // generate trim mesh @@ -814,25 +830,11 @@ GAME_FRAME( game_frame ) { } } - // draw fillers - for( u32 i = 0; i < 2; i++ ) { - // horizontal - { - v2 tile_tl = base + v2( i * 3, 2 ) * tile_size + v2( i * scale, 0 ); - - render_state.uniforms[ UNIFORMS_MODEL ] = rotation_uniforms[ 0 ]; - render_state.uniforms[ UNIFORMS_CLIPMAP ] = renderer_uniforms( tile_tl, scale ); - renderer_draw_mesh( clipmap.gpu.horizontal_filler, render_state ); - } - - // vertical - { - v2 tile_tl = base + v2( 2, i * 3 ) * tile_size + v2( 0, i * scale ); - - render_state.uniforms[ UNIFORMS_MODEL ] = rotation_uniforms[ 0 ]; - render_state.uniforms[ UNIFORMS_CLIPMAP ] = renderer_uniforms( tile_tl, scale ); - renderer_draw_mesh( clipmap.gpu.vertical_filler, render_state ); - } + // draw filler + { + render_state.uniforms[ UNIFORMS_MODEL ] = rotation_uniforms[ 0 ]; + render_state.uniforms[ UNIFORMS_CLIPMAP ] = renderer_uniforms( snapped_pos, scale ); + renderer_draw_mesh( clipmap.gpu.filler, render_state ); } if( l != NUM_LODS - 1 ) {