commit ce7316c5d7c13edb73260b1c59da6869de71cb81 parent 51feb0d3972ac505b5591a068d687d9f0ca92ce4 Author: Michael Savage <mikejsavage@gmail.com> Date: Thu Sep 17 20:17:06 +0100 Use MemoryArena instead of new in Heightmap, fix TerrainManager update being totally wrong Diffstat:
btt.cc | | | 2 | +- |
heightmap.cc | | | 20 | ++++++++++---------- |
heightmap.h | | | 3 | ++- |
hm.cc | | | 2 | +- |
terrain_manager.cc | | | 134 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
terrain_manager.h | | | 10 | ++++++++-- |
diff --git a/btt.cc b/btt.cc @@ -229,7 +229,7 @@ extern "C" GAME_INIT( game_init ) { int w, h; u8 * pixels = stbi_load( "mountains512.png", &w, &h, nullptr, 1 ); - heightmap_init( &state->hm, pixels, w, h, 0, 0, + heightmap_init( &state->hm, &mem->persistent_arena, pixels, w, h, 0, 0, state->test_at_position, state->test_at_normal, state->test_at_lit ); state->btt = btt_from_heightmap( &state->hm, &mem->persistent_arena ); diff --git a/heightmap.cc b/heightmap.cc @@ -8,6 +8,7 @@ #include "intrinsics.h" #include "heightmap.h" +#include "memory_arena.h" #include "stb_image.h" #include "stb_perlin.h" @@ -44,7 +45,7 @@ static glm::vec3 triangle_perp_ccw( const glm::vec3 & a, const glm::vec3 & b, co } void heightmap_init( - Heightmap * const hm, + Heightmap * const hm, MemoryArena * const mem, u8 * const pixels, const u32 width, const u32 height, const float ox, const float oy, const GLint at_pos, const GLint at_normal, const GLint at_lit @@ -53,7 +54,13 @@ void heightmap_init( hm->width = width; hm->height = height; - float * const lit = new GLfloat[ width * height ]; + MemoryArenaCheckpoint cp = memarena_checkpoint( mem ); + + GLfloat * const vertices = memarena_push_many( mem, GLfloat, width * height * 3 ); + GLfloat * const normals = memarena_push_many( mem, GLfloat, width * height * 3 ); + GLuint * const indices = memarena_push_many( mem, GLuint, width * height * 6 ); + GLfloat * const lit = memarena_push_many( mem, GLfloat, width * height ); + for( u32 i = 0; i < width * height; i++ ) { lit[ i ] = 0; } @@ -90,10 +97,6 @@ void heightmap_init( } } - GLfloat * const vertices = new GLfloat[ width * height * 3 ]; - GLfloat * const normals = new GLfloat[ width * height * 3 ]; - GLuint * const indices = new GLuint[ width * height * 6 ]; - for( u32 y = 0; y < height; y++ ) { for( u32 x = 0; x < width; x++ ) { const u32 base = 3 * ( y * width + x ); @@ -151,10 +154,7 @@ void heightmap_init( glBindVertexArray( 0 ); - delete vertices; - delete normals; - delete indices; - delete lit; + memarena_restore( mem, &cp ); } void heightmap_destroy( Heightmap * const hm ) { diff --git a/heightmap.h b/heightmap.h @@ -7,6 +7,7 @@ #include <glm/glm.hpp> #include "intrinsics.h" +#include "memory_arena.h" class Heightmap { public: @@ -32,7 +33,7 @@ struct OffsetHeightmap { float x_offset, y_offset; }; -void heightmap_init( Heightmap * const hm, +void heightmap_init( Heightmap * const hm, MemoryArena * const mem, u8 * const pixels, const u32 width, const u32 height, const float ox, const float oy, // TODO: take rendering out of Heightmap const GLint at_pos, const GLint at_normal, const GLint at_lit ); diff --git a/hm.cc b/hm.cc @@ -91,7 +91,7 @@ static WORK_QUEUE_CALLBACK( testwq ) { extern "C" GAME_INIT( game_init ) { state->pos = glm::vec3( 15000, 3000, 50 ); state->angles = glm::radians( glm::vec3( -90, 45, 0 ) ); - terrain_init( &state->tm, "Srtm_ramp2.world.21600x10800.jpg.parts" ); + terrain_init( &state->tm, "Srtm_ramp2.world.21600x10800.jpg.parts", &mem->persistent_arena ); terrain_teleport( &state->tm, state->pos ); workqueue_init( &state->background_tasks, &mem->persistent_arena, 2 ); diff --git a/terrain_manager.cc b/terrain_manager.cc @@ -1,13 +1,3 @@ -/* - * I use the following naming conventions in this file:: - * TODO: no i dont - * - * - tx/ty are used to denote tile coordinates - * - ptx/pty are used to denote the player's tile coordinates - * - x/y are used to denote local coordinates within a tile - * - wx/wy are used to denote global coordinates - */ - #include <string.h> #include "platform_opengl.h" @@ -17,6 +7,7 @@ #include "intrinsics.h" #include "heightmap.h" #include "terrain_manager.h" +#include "memory_arena.h" #include "work_queue.h" #include "stb_image.h" @@ -69,13 +60,13 @@ static const GLchar * frag_src = GLSL( ); static void terrain_load( - TerrainManager * const tm, const u32 tx, const u32 ty, - const u32 vx, const u32 vy + TerrainManager * const tm, const u32 tile_x, const u32 tile_y, + const u32 view_x, const u32 view_y ) { char path[ 256 ]; - sprintf( path, "%s/%d_%d.tga", tm->dir, tx, ty ); + sprintf( path, "%s/%d_%d.tga", tm->dir, tile_x, tile_y ); - Heightmap * const hm = &tm->tiles[ tx ][ ty ]; + Heightmap * const hm = &tm->tiles[ view_x ][ view_y ]; if( hm->vbo_verts != 0 ) heightmap_destroy( hm ); @@ -89,15 +80,20 @@ static void terrain_load( if( !pixels ) err( 1, "stbi_load failed (%s)", stbi_failure_reason() ); - heightmap_init( hm, pixels, width, height, - tx * TILE_SIZE, ty * TILE_SIZE, + heightmap_init( hm, tm->mem, pixels, width, height, + tile_x * TILE_SIZE, tile_y * TILE_SIZE, tm->at_pos, tm->at_normal, tm->at_lit ); } -void terrain_init( TerrainManager * const tm, const char * const tiles_dir ) { +void terrain_init( + TerrainManager * const tm, const char * const tiles_dir, + MemoryArena * const mem +) { assert( strlen( tiles_dir ) < array_count( tm->dir ) ); strcpy( tm->dir, tiles_dir ); + tm->mem = mem; + char dims_path[ 256 ]; sprintf( dims_path, "%s/dims.txt", tm->dir ); @@ -120,71 +116,95 @@ void terrain_init( TerrainManager * const tm, const char * const tiles_dir ) { } void terrain_teleport( TerrainManager * const tm, const glm::vec3 position ) { - const u32 new_tx = position.x / TILE_SIZE; - const u32 new_ty = position.y / TILE_SIZE; - - // TODO: this is a cheap hack if( !tm->first_teleport ) { - for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { - for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { - heightmap_destroy( &tm->tiles[ tm->last_tx + tx - VIEW_HALF ][ tm->last_ty + ty - VIEW_HALF ] ); + for( u32 vy = 0; vy < VIEW_SIZE; vy++ ) { + for( u32 vx = 0; vx < VIEW_SIZE; vx++ ) { + heightmap_destroy( &tm->tiles[ vx ][ vy ] ); } } } tm->first_teleport = false; - tm->last_tx = new_tx; - tm->last_ty = new_ty; + const u32 player_tile_x = position.x / TILE_SIZE; + const u32 player_tile_y = position.y / TILE_SIZE; + + tm->tile_x = player_tile_x; + tm->tile_y = player_tile_y; - for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { - for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { - terrain_load( tm, new_tx + tx - VIEW_HALF, new_ty + ty - VIEW_HALF, tx, ty ); + for( u32 vy = 0; vy < VIEW_SIZE; vy++ ) { + for( u32 vx = 0; vx < VIEW_SIZE; vx++ ) { + terrain_load( tm, + vx + player_tile_x - VIEW_HALF, vy + player_tile_y - VIEW_HALF, + vx, vy ); } } } +static u32 view_sub( u32 v, u32 o ) { + if( v >= o ) return v - o; + return VIEW_SIZE - ( o - v ); +} + +static u32 view_add( u32 v, u32 o ) { + return ( v + o ) % VIEW_SIZE; +} + void terrain_update( TerrainManager * const tm, const glm::vec3 position ) { - const u32 new_tx = position.x / TILE_SIZE; - const u32 new_ty = position.y / TILE_SIZE; + const u32 player_tile_x = position.x / TILE_SIZE; + const u32 player_tile_y = position.y / TILE_SIZE; - if( new_tx != tm->last_tx ) { - if( new_tx > tm->last_tx ) { + if( player_tile_x != tm->tile_x ) { + if( player_tile_x > tm->tile_x ) { // +x boundary - for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { - terrain_load( tm, tm->last_tx + VIEW_HALF + 1, tm->last_ty + ty - VIEW_HALF, tm->view_left, tm->view_top ); + for( u32 vy = 0; vy < VIEW_SIZE; vy++ ) { + terrain_load( tm, + tm->tile_x + VIEW_HALF + 1, + tm->tile_y + vy - VIEW_HALF, + view_add( tm->view_left, VIEW_SIZE ), + view_add( tm->view_top, vy ) ); } - tm->last_tx++; - tm->view_left = ( tm->view_left + 1 ) % VIEW_SIZE; + tm->tile_x++; + tm->view_left = view_add( tm->view_left, 1 ); } else { // -x boundary - const u32 new_view_left = tm->view_left == 0 ? VIEW_SIZE - 1 : tm->view_left - 1; - for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { - terrain_load( tm, tm->last_tx - VIEW_HALF - 1, tm->last_ty + ty - VIEW_HALF, new_view_left, tm->view_top ); + for( u32 vy = 0; vy < VIEW_SIZE; vy++ ) { + terrain_load( tm, + tm->tile_x - VIEW_HALF - 1, + tm->tile_y + vy - VIEW_HALF, + view_sub( tm->view_left, 1 ), + view_add( tm->view_top, vy ) ); } - tm->last_tx--; - tm->view_left = new_view_left; + tm->tile_x--; + tm->view_left = view_sub( tm->view_left, 1 ); } } - if( new_ty != tm->last_ty ) { - if( new_ty > tm->last_ty ) { + if( player_tile_y != tm->tile_y ) { + if( player_tile_y > tm->tile_y ) { // +y boundary - for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { - terrain_load( tm, tm->last_tx + tx - VIEW_HALF, tm->last_ty + VIEW_HALF + 1, tm->view_left, tm->view_top ); + for( u32 vx = 0; vx < VIEW_SIZE; vx++ ) { + terrain_load( tm, + tm->tile_x + vx - VIEW_HALF, + tm->tile_y + VIEW_HALF + 1, + view_add( tm->view_left, vx ), + view_add( tm->view_top, VIEW_SIZE ) ); } - tm->last_ty++; - tm->view_top = ( tm->view_top + 1 ) % VIEW_SIZE; + tm->tile_y++; + tm->view_top = view_add( tm->view_top, 1 ); } else { // -y boundary - const u32 new_view_top = tm->view_top == 0 ? VIEW_SIZE - 1 : tm->view_top - 1; - for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { - terrain_load( tm, tm->last_tx + tx - VIEW_HALF, tm->last_ty - VIEW_HALF - 1, tm->view_left, new_view_top ); + for( u32 vx = 0; vx < VIEW_SIZE; vx++ ) { + terrain_load( tm, + tm->tile_x + vx - VIEW_HALF, + tm->tile_y - VIEW_HALF - 1, + view_add( tm->view_left, vx ), + view_sub( tm->view_top, 1 ) ); } - tm->last_ty--; - tm->view_top = new_view_top; + tm->tile_y--; + tm->view_top = view_sub( tm->view_top, 1 ); } } } @@ -197,9 +217,9 @@ void terrain_render( const TerrainManager * const tm, const glm::mat4 VP, const glUniformMatrix4fv( tm->un_vp, 1, GL_FALSE, glm::value_ptr( VP ) ); glUniform3fv( tm->un_sun, 1, glm::value_ptr( sun ) ); - for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { - for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { - tm->tiles[ tm->last_tx + tx - VIEW_HALF ][ tm->last_ty + ty - VIEW_HALF ].render(); + for( u32 vy = 0; vy < VIEW_SIZE; vy++ ) { + for( u32 vx = 0; vx < VIEW_SIZE; vx++ ) { + tm->tiles[ vx ][ vy ].render(); } } @@ -210,6 +230,8 @@ float terrain_height( const TerrainManager * const tm, const float x, const floa const u32 tx = x / TILE_SIZE; const u32 ty = y / TILE_SIZE; + // TODO: totally wrong + // convert into tile space const Heightmap * const hm = &tm->tiles[ tx ][ ty ]; return hm->bilerp_height( x - tx * TILE_SIZE, y - ty * TILE_SIZE ); diff --git a/terrain_manager.h b/terrain_manager.h @@ -5,6 +5,7 @@ #include <glm/glm.hpp> #include "intrinsics.h" +#include "memory_arena.h" #include "heightmap.h" static const u32 TILE_SIZE = 128; @@ -15,8 +16,9 @@ static const u32 VIEW_HALF = VIEW_SIZE / 2; struct TerrainManager { char dir[ 128 ]; + MemoryArena * mem; + u32 width, height; - u32 last_tx, last_ty; GLuint shader; @@ -29,11 +31,15 @@ struct TerrainManager { bool first_teleport; + // tile_x and tile_y are the coordinates of the tile we are centered on + // view_x and view_y are indices into tiles of the tile we are centered on + u32 tile_x, tile_y; u32 view_left, view_top; Heightmap tiles[ VIEW_SIZE ][ VIEW_SIZE ]; }; -void terrain_init( TerrainManager * const tm, const char * const tiles_dir ); +void terrain_init( TerrainManager * const tm, const char * const tiles_dir, + MemoryArena * const mem ); void terrain_teleport( TerrainManager * const tm, const glm::vec3 position ); void terrain_update( TerrainManager * const tm, const glm::vec3 position ); void terrain_render( const TerrainManager * const tm, const glm::mat4 VP, const float sun_slope );