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 );
+ }
+ }
}
}