medfall

A super great game engine
Log | Files | Refs

commit 92f344287d4a46ea5de470d9c4d01b242066a1e0
parent db8e4b6f4ceed06212ab285bb64cc3e13d23fc6c
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat May 20 14:54:11 +0300

Add broken BTT junk so it's not in my git status

Diffstat:
mod_btt.cc | 133++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 91 insertions(+), 42 deletions(-)
diff --git a/mod_btt.cc b/mod_btt.cc @@ -1,5 +1,6 @@ #include "game.h" #include "intrinsics.h" +#include "int_conversions.h" #include "immediate.h" #include "skybox.h" #include "profiler.h" @@ -7,8 +8,8 @@ #include "linear_algebra.h" #include "lz4.h" -#define TERRAIN_NAME "mountains512.png" - +// #define TERRAIN_NAME "mountains512.png" +#define TERRAIN_NAME "grad.png" static const char * vert_src = GLSL( in vec3 position; @@ -42,7 +43,7 @@ static const char * frag_src = GLSL( uniform sampler2D horizons; void main() { - vec3 normal = normalize( texture( normals, smooth_position.xy / dimensions ).xyz ); + vec3 normal = normalize( texture( normals, smooth_position.xy / dimensions ).xyz * 2.0 - 1.0 ); float horizon = texture( horizons, smooth_position.xy / dimensions ).r; // ground colour @@ -71,12 +72,15 @@ static const char * frag_src = GLSL( // sunlight + sky ambient lighting // TODO: use formula for area of a chord? float sun_visible_fraction = smoothstep( 0, 0.2, sun - horizon ); + sun_visible_fraction += 5.0; + sun_visible_fraction = min( 1.0, sun_visible_fraction ); vec3 sun_direction = normalize( vec3( -1, 0, sun ) ); float sunlight_lambert = max( 0, dot( normal, sun_direction ) ); vec3 sunlight = sun_visible_fraction * sunlight_lambert * vec3( 0.9, 0.9, 0.5 ); vec3 ambient = vec3( 0.02, 0.02, 0.15 ); colour = vec4( ( sunlight + ambient ) * ground, 1.0 ); + colour = vec4( ( normal + 1.0 ) / 2.0, 1.0 ); } ); @@ -143,7 +147,41 @@ v3 angles_to_vector( v3 angles ) { // } // } -static float * horizons; +static void compute_normals( const array2d< u8 > heightmap, array2d< v3 > normals ) { + ASSERT( heightmap.w == normals.w && heightmap.h == normals.h ); + + // estimate the gradient at each point by doing central differences on + // each axis, then cross the tangent and bitangent to find the normal + for( size_t y = 0; y < heightmap.h; y++ ) { + for( size_t x = 0; x < heightmap.w; x++ ) { + size_t x_plus_one = x + 1; + size_t x_minus_one = x - 1; + size_t y_plus_one = y + 1; + size_t y_minus_one = y - 1; + + if( x == 0 ) x_minus_one = x; + if( x == heightmap.w - 1 ) x_plus_one = x; + if( y == 0 ) y_minus_one = y; + if( y == heightmap.h - 1 ) y_plus_one = y; + + v3 tangent( + checked_cast< float >( x_plus_one - x_minus_one ), + 0, + checked_cast< float >( heightmap( x_plus_one, y ) - heightmap( x_minus_one, y ) ) ); + v3 bitangent( + 0, + checked_cast< float >( y_plus_one - y_minus_one ), + checked_cast< float >( heightmap( x, y_plus_one ) - heightmap( x, y_minus_one ) ) ); + + v3 cp = cross( tangent, bitangent ); + v3 n = normalize( cp ); + normals( x, y ) = ( n + v3( 1, 1, 1 ) ) / 2; + } + } +} + +static array2d< float > horizons; +static array2d< v3 > normals; static HeightmapQuadTree qt; static UB ub_fs, ub_vs; @@ -169,8 +207,9 @@ extern "C" GAME_INIT( game_init ) { ub_vs = renderer_new_ub(); ub_fs = renderer_new_ub(); - int w, h; - u8 * pixels = stbi_load( "terrains/" TERRAIN_NAME, &w, &h, NULL, 1 ); + int w, h, channels; + u8 * pixels = stbi_load( "terrains/" TERRAIN_NAME, &w, &h, &channels, 1 ); + ASSERT( channels == 1 ); heightmap_init( &game->hm, pixels, w, h ); { @@ -180,29 +219,28 @@ extern "C" GAME_INIT( game_init ) { qt = heightmap_build_quadtree( &game->hm, nodes ); } - size_t horizons_size = ( w + 1 ) * ( h + 1 ) * sizeof( float ); - horizons = ( float * ) malloc( horizons_size ); - assert( horizons != NULL ); + horizons = memarena_push_array2d( &mem->persistent_arena, float, w, h ); size_t compressed_horizons_size; u8 * compressed_horizons = file_get_contents( "terrains/" TERRAIN_NAME ".parts/0_0_horizons.lz4", &compressed_horizons_size ); int ok_horizons = LZ4_decompress_safe( ( const char * ) compressed_horizons, - ( char * ) horizons, - compressed_horizons_size, horizons_size ); - assert( ok_horizons > 0 ); - - size_t normals_size = ( w + 1 ) * ( h + 1 ) * sizeof( v3 ); - v3 * normals = ( v3 * ) malloc( normals_size ); - assert( normals != NULL ); - - size_t compressed_normals_size; - u8 * compressed_normals = file_get_contents( "terrains/" TERRAIN_NAME ".parts/0_0_normals.lz4", &compressed_normals_size ); - int ok_normals = LZ4_decompress_safe( - ( const char * ) compressed_normals, - ( char * ) normals, - compressed_normals_size, normals_size ); - assert( ok_normals > 0 ); + ( char * ) horizons.ptr(), + compressed_horizons_size, horizons.num_bytes() ); + ASSERT( ok_horizons > 0 && to_unsigned( ok_horizons ) == horizons.num_bytes() ); + + normals = memarena_push_array2d( &mem->persistent_arena, v3, w, h ); + + // size_t compressed_normals_size; + // u8 * compressed_normals = file_get_contents( "terrains/" TERRAIN_NAME ".parts/0_0_normals.lz4", &compressed_normals_size ); + // int ok_normals = LZ4_decompress_safe( + // ( const char * ) compressed_normals, + // ( char * ) normals.ptr(), + // compressed_normals_size, normals.num_bytes() ); + // ASSERT( ok_normals > 0 && to_unsigned( ok_normals ) == normals.num_bytes() ); + + array2d< u8 > heightmap( pixels, w, h ); + compute_normals( heightmap, normals ); { PROFILE_BLOCK( "Build BTT" ); @@ -210,7 +248,7 @@ extern "C" GAME_INIT( game_init ) { } const OffsetHeightmap ohm = { game->hm, 0, 0 }; - gpubtt_init( &mem->persistent_arena, &game->gpubtt, game->btt, &ohm, normals, horizons ); + gpubtt_init( &mem->persistent_arena, &game->gpubtt, game->btt, &ohm, normals.ptr(), horizons.ptr() ); skybox_init( &game->skybox ); } @@ -327,11 +365,21 @@ extern "C" GAME_FRAME( game_frame ) { { immediate_init( &imm, triangles, ARRAY_COUNT( triangles ) ); - for( size_t i = 0; i < game->hm.width; i++ ) { - v3 origin = v3( i, 1, game->hm.point( i, 1 ).z ); - v3 direction = normalize( v3( -1, 0, horizons[ 1 * game->hm.width + i ] ) ); - v4 white( 1, 1, 1, 1 ); - immediate_arrow( &imm, origin, direction, 2, white ); + // for( size_t i = 0; i < game->hm.width; i++ ) { + // v3 origin = v3( i, 1, game->hm.point( i, 1 ).z ); + // v3 direction = normalize( v3( -1, 0, horizons( i, 1 ) ) ); + // v4 white( 1, 1, 1, 1 ); + // immediate_arrow( &imm, origin, direction, 2, white ); + // } + + for( u32 y = 4; y < game->hm.height; y += 8 ) { + for( u32 x = 4; x < game->hm.width; x += 8 ) { + v3 origin = game->hm.point( x, y ); + v3 direction = normals( x, y ) * 2 - v3( 1, 1, 1 ); + v4 white( 1, 1, 1, 1 ); + immediate_sphere( &imm, origin, 2, white, 4 ); + immediate_sphere( &imm, origin + 3 * direction, 2, white, 4 ); + } } float t; @@ -342,6 +390,7 @@ extern "C" GAME_FRAME( game_frame ) { v3 impact = game->pos + forward * t; immediate_sphere( &imm, impact, 2, v4( 1, 0, 0, 1 ) ); v3 smooth_normal = normalize( bilerp( normals, impact.x, impact.y ) ); + printf( "%.2f %.2f %.2f\n", smooth_normal.x, smooth_normal.y, smooth_normal.z ); immediate_arrow( &imm, impact, smooth_normal, 8, v4( 1, 0, 0, 1 ) ); } else printf( "nope\n" ); @@ -352,18 +401,18 @@ extern "C" GAME_FRAME( game_frame ) { immediate_render( &imm, impact_render_state ); } - { - immediate_init( &imm, triangles, ARRAY_COUNT( triangles ) ); - v3u32 mins = v3u32( 0, 0, qt.nodes[ 0 ].min_z ); - v3u32 maxs = v3u32( qt.dim, qt.dim, qt.nodes[ 0 ].max_z ); - draw_qt( &imm, AABBu32( mins, maxs ), qt.nodes, 0 ); - - RenderState qt_render_state; - qt_render_state.shader = game->test_outline_shader; - qt_render_state.ubs[ UB_VS_HOT ] = ub_vs; - qt_render_state.wireframe = true; - immediate_render( &imm, qt_render_state ); - } + // { + // immediate_init( &imm, triangles, ARRAY_COUNT( triangles ) ); + // v3u32 mins = v3u32( 0, 0, qt.nodes[ 0 ].min_z ); + // v3u32 maxs = v3u32( qt.dim, qt.dim, qt.nodes[ 0 ].max_z ); + // draw_qt( &imm, AABBu32( mins, maxs ), qt.nodes, 0 ); + // + // RenderState qt_render_state; + // qt_render_state.shader = game->test_outline_shader; + // qt_render_state.ubs[ UB_VS_HOT ] = ub_vs; + // qt_render_state.wireframe = true; + // immediate_render( &imm, qt_render_state ); + // } // immediate_init( &imm, triangles, ARRAY_COUNT( triangles ) ); // draw_btt( game->btt.left_root, &game->hm, &imm, glm::ivec2( 0, 0 ), glm::ivec2( 0, game->hm.height - 1 ), glm::ivec2( game->hm.width - 1, game->hm.height - 1 ) );