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 ) {