medfall

A super great game engine
Log | Files | Refs

commit 35da5c7ee43fe692f087b3f9679009ba3dc0dc2a
parent 6e861e0f9e02c341a815ee2e42283c9a94a113e8
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat, 25 Nov 2017 12:57:33 +0200

Clipmap seams!

Diffstat:
clipmap.cc | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 55 insertions(+), 12 deletions(-)

diff --git a/clipmap.cc b/clipmap.cc @@ -447,6 +447,40 @@ GAME_INIT( game_init ) { clipmap.gpu.cross = renderer_new_mesh( mesh_config ); } + // generate seam mesh + { + MEMARENA_SCOPED_CHECKPOINT( &mem->persistent_arena ); + + array< v3 > vertices = alloc_array< v3 >( &mem->persistent_arena, CLIPMAP_VERT_RESOLUTION * 4 ); + + for( u32 i = 0; i < CLIPMAP_VERT_RESOLUTION; i++ ) { + vertices[ CLIPMAP_VERT_RESOLUTION * 0 + i ] = v3( i, 0, 0 ); + vertices[ CLIPMAP_VERT_RESOLUTION * 1 + i ] = v3( CLIPMAP_VERT_RESOLUTION, i, 0 ); + vertices[ CLIPMAP_VERT_RESOLUTION * 2 + i ] = v3( CLIPMAP_VERT_RESOLUTION - i, CLIPMAP_VERT_RESOLUTION, 0 ); + vertices[ CLIPMAP_VERT_RESOLUTION * 3 + i ] = v3( 0, CLIPMAP_VERT_RESOLUTION - i, 0 ); + } + + array< u32 > indices = alloc_array< u32 >( &mem->persistent_arena, CLIPMAP_VERT_RESOLUTION * 6 ); + size_t n = 0; + + for( u32 i = 0; i < CLIPMAP_VERT_RESOLUTION * 4; i += 2 ) { + indices[ n++ ] = i + 1; + indices[ n++ ] = i; + indices[ n++ ] = i + 2; + } + + // make the last triangle wrap around + indices[ indices.n - 1 ] = 0; + + 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.seam = renderer_new_mesh( mesh_config ); + } + // generate skirt mesh { float scale = checked_cast< float >( u32( 1 ) << ( NUM_LODS - 1 ) ); @@ -794,24 +828,33 @@ GAME_FRAME( game_frame ) { } } - // draw trim if( l != NUM_LODS - 1 ) { - float next_scale = checked_cast< float >( u32( 1 ) << ( l + 1 ) ); + float next_scale = scale * 2.0f; v2 next_snapped_pos = floorf( game->pos.xy() / next_scale ) * next_scale; - v2 d = game->pos.xy() - next_snapped_pos; + // draw trim + { + v2 tile_centre = snapped_pos + v2( scale * 0.5f ); + + v2 d = game->pos.xy() - next_snapped_pos; + u32 r = 0; + r |= d.x >= scale ? 0 : 2; + r |= d.y >= scale ? 0 : 1; - u32 r = 0; - r |= d.x >= scale ? 0 : 2; - r |= d.y >= scale ? 0 : 1; + render_state.uniforms[ UNIFORMS_MODEL ] = rotation_uniforms[ r ]; + render_state.uniforms[ UNIFORMS_CLIPMAP ] = renderer_uniforms( tile_centre, scale ); + renderer_draw_mesh( clipmap.gpu.trim, render_state ); + } - v2 tile_centre = snapped_pos + v2( scale * 0.5f ); - render_state.uniforms[ UNIFORMS_MODEL ] = rotation_uniforms[ r ]; - render_state.uniforms[ UNIFORMS_CLIPMAP ] = renderer_uniforms( tile_centre, scale ); - renderer_draw_mesh( clipmap.gpu.trim, render_state ); - } + // draw seam + { + v2 next_base = next_snapped_pos - v2( checked_cast< float >( PATCH_RESOLUTION << ( l + 1 ) ) ); - // TODO draw seam + render_state.uniforms[ UNIFORMS_MODEL ] = rotation_uniforms[ 0 ]; + render_state.uniforms[ UNIFORMS_CLIPMAP ] = renderer_uniforms( next_base, scale ); + renderer_draw_mesh( clipmap.gpu.seam, render_state ); + } + } } }