From 56b08e59f7e86039c9adda9030f9c68d26718539 Mon Sep 17 00:00:00 2001 From: Emil Kosz Date: Sat, 7 Jun 2025 20:25:01 +0200 Subject: [PATCH] Dynamic render distance --- game/res/shaders/default.vert | 3 + game/res/textures/font.png | Bin 1860 -> 1851 bytes game/res/textures/font.xcf | Bin 36636 -> 36670 bytes game/src/chunk/chunkman.c | 55 ++++++----- game/src/chunk/chunkman.h | 3 - game/src/entity/entman.c | 19 +++- game/src/entity/entman.h | 2 - game/src/gl/mesh.c | 169 +++++++++++----------------------- game/src/gl/mesh.h | 1 - game/src/graphics.c | 33 +++++++ game/src/graphics.h | 8 ++ 11 files changed, 139 insertions(+), 154 deletions(-) diff --git a/game/res/shaders/default.vert b/game/res/shaders/default.vert index b539105..51b7213 100644 --- a/game/res/shaders/default.vert +++ b/game/res/shaders/default.vert @@ -1,5 +1,8 @@ #version 100 +/* Be aware of the fact that we are indeed sending three integers for + the position and two for the UV. None of the data is floating + point. */ attribute vec4 position; attribute vec2 uv; diff --git a/game/res/textures/font.png b/game/res/textures/font.png index 141349e373bdee6d5b9350d887b9aedc599277a1..a34641727baf0b17754e7e3118235e640805a266 100644 GIT binary patch delta 1743 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 I>zopr0IsQ7!~g&Q diff --git a/game/res/textures/font.xcf b/game/res/textures/font.xcf index 24de64bc396552dd5e3cea36a44f10f04547c72c..4ab5815480d70e97200a426055abf0dfe5ae4999 100644 GIT binary patch delta 735 zcmbO;k7?gLrU{1_w`@F|&B3^Hvp%O4Bjei1`+CGCH*j$ZK4Sm_?@eHeA@}&^SzM89 z%>NmfCM!rQGqO&W6I5qq`u~^V|Kxe9>a2|ae>41_yg*u3oRNX?|9=Li|BMW*{}~yW z|1&fE{?EYhfAR(CMm9!5CZ z`2U}Yf%!iR1LJ>Q2FCx)46Of|7#ROQW%v*B-G7Gv5C#K;0*f&-F#YFYUAy2M$SYu!k7`voSFK zXJ=siFUr99pPPaCKhxxoo{F38Om9&^Nt}BflO!lKKz_lnX!A$UCytXFIoAj>L(&_J p>^U-7pHq7B+8z$h7Z9<2BTyQZ>Xm?Sdo`f61(f#K{H{lj2>}1y{VV_g delta 654 zcmdltk7>?4rU{1_mux(o&A~W*vp%O4BV+gE2R&kw8@Mvo9Ffsi3zxkGq z1Ba*}10%?||LhEm|3w)X|AU>fIoka=<7Pew6LzxY=QD{4VKaJiw7cSF6R*RLj0}^1 sbnj+dG+Cchdh+=m4$fncgwrnoN>Wli-yqyxHYhCyrPVeI^y)DI0Oq2_MgRZ+ diff --git a/game/src/chunk/chunkman.c b/game/src/chunk/chunkman.c index 1f016f0..6d24e4e 100644 --- a/game/src/chunk/chunkman.c +++ b/game/src/chunk/chunkman.c @@ -3,6 +3,8 @@ /* TODO: Sort chunks by distance to player, and generate them like that. Will require having a queue or similar structure. */ +extern int render_distance; + int n_frame_chunks; static GHashTable *chunks; @@ -114,9 +116,9 @@ chunkman_tick (vec3 position) uint64_t freq = SDL_GetPerformanceFrequency (); double elapsed_us = 0; - for (int z = cz - RENDER_DISTANCE - 1; z <= cz + RENDER_DISTANCE + 1; ++z) + for (int z = cz - render_distance - 1; z <= cz + render_distance + 1; ++z) { - for (int x = cx - RENDER_DISTANCE - 1; x <= cx + RENDER_DISTANCE + 1; ++x) + for (int x = cx - render_distance - 1; x <= cx + render_distance + 1; ++x) { uint64_t now = SDL_GetPerformanceCounter (); elapsed_us = (double) (now - start) * 1000000.0 / (double) freq; @@ -133,9 +135,9 @@ chunkman_tick (vec3 position) } } - for (int z = cz - RENDER_DISTANCE; z <= cz + RENDER_DISTANCE; ++z) + for (int z = cz - render_distance; z <= cz + render_distance; ++z) { - for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x) + for (int x = cx - render_distance; x <= cx + render_distance; ++x) { uint64_t now = SDL_GetPerformanceCounter (); elapsed_us = (double) (now - start) * 1000000.0 / (double) freq; @@ -178,39 +180,34 @@ chunkman_render (vec3 position, vec4 planes[6]) n_frame_chunks = 0; - for (int z = cz - RENDER_DISTANCE; z <= cz + RENDER_DISTANCE; ++z) + for (int z = cz - render_distance; z <= cz + render_distance; ++z) { - for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x) + for (int x = cx - render_distance; x <= cx + render_distance; ++x) { - if ((x - cx) * (x - cx) + (z - cz) * (z - cz) <= RENDER_SQR) + ChunkMesh *mesh = chunkman_get_ChunkMesh_at (x, z); + if (mesh != NULL) { - ChunkMesh *mesh = chunkman_get_ChunkMesh_at (x, z); - if (mesh != NULL) - { - /* This, compared to the entity AABB, seems to work - completely fine. */ #if FRUSTUM_CULL - vec3 aabb[2] = { - { x * CHUNK_DIM, 0.0, z * CHUNK_DIM }, - { (x + 1) * CHUNK_DIM, TERRAIN_HEIGHT, (z + 1) * CHUNK_DIM } - }; + vec3 aabb[2] = { + { x * CHUNK_DIM, 0.0, z * CHUNK_DIM }, + { (x + 1) * CHUNK_DIM, TERRAIN_HEIGHT, (z + 1) * CHUNK_DIM } + }; - if (!glm_aabb_frustum (aabb, planes)) - { - continue; - } + if (!glm_aabb_frustum (aabb, planes)) + { + continue; + } #endif - if (!bound) - { - ChunkMesh_bind (mesh); - bound = true; - } - - program_set_vec3_ind (RESPRG ("chunk"), "chunk_position", x * CHUNK_DIM, 0.0, z * CHUNK_DIM); - ChunkMesh_render (mesh, flags_get ("wireframe_enabled")); - n_frame_chunks++; + if (!bound) + { + ChunkMesh_bind (mesh); + bound = true; } + + program_set_vec3_ind (RESPRG ("chunk"), "chunk_position", x * CHUNK_DIM, 0.0, z * CHUNK_DIM); + ChunkMesh_render (mesh, flags_get ("wireframe_enabled")); + n_frame_chunks++; } } } diff --git a/game/src/chunk/chunkman.h b/game/src/chunk/chunkman.h index 25bd465..870d9a3 100644 --- a/game/src/chunk/chunkman.h +++ b/game/src/chunk/chunkman.h @@ -9,10 +9,7 @@ #include "../entity/entman.h" #include "../graphics.h" -#define RENDER_DISTANCE 5 -#define RENDER_SQR (RENDER_DISTANCE*RENDER_DISTANCE) #define TERRAIN_HEIGHT 8.0 -#define CHUNK_FRAME_BUDGET_US 100 void chunkman_init (); void chunkman_tick (vec3 position); diff --git a/game/src/entity/entman.c b/game/src/entity/entman.c index 90564ab..bf0c032 100644 --- a/game/src/entity/entman.c +++ b/game/src/entity/entman.c @@ -7,6 +7,7 @@ seperately somehow. */ extern vec3 camera_position; +extern int render_distance; Entity *player_entity, *sky_entity; int n_frame_ents; @@ -16,7 +17,7 @@ int n_frame_ents; static GArray *entities; static GQueue *spawn_requests; -static SimpleMesh mesh_quad1, mesh_quad2, mesh_quad_x, mesh_cube; +static SimpleMesh mesh_quad1, mesh_quad2, mesh_quad_x; static unsigned int last_program = -1; static unsigned int last_type = -1; static unsigned int last_texture = -1; @@ -38,7 +39,6 @@ entman_init () mesh_quad1 = SimpleMesh_make_quad1 (); mesh_quad2 = SimpleMesh_make_quad2 (); mesh_quad_x = SimpleMesh_make_quad_x (); - mesh_cube = SimpleMesh_make_cube (); player_entity = Entity_new (); player_entity->visible = false; @@ -89,7 +89,9 @@ entman_tick () elapsed_us = (double) (now - start) * 1000000.0 / (double) freq; if (elapsed_us > ENTITY_FRAME_BUDGET_US) - break; + { + break; + } spawn_queue_process_one (); } @@ -121,11 +123,18 @@ entman_render_entity (Entity *entity, void *userdata) return; } - unsigned int cull_dist = RENDER_DISTANCE * CHUNK_DIM * (100 / entity->cull_distance); + /* Why an int, why int division? It's simply much faster than + floating point operations. No need to have super accurate cull + distance anyway, and might as well save a lot when rendering entities. */ + unsigned int cull_dist = (render_distance * CHUNK_DIM * entity->cull_distance) / 100; + /* Underneath is the slowest (for the CPU) part of the entity render + process. Moving the camera positions from memory into some + registers. Thus the entity rendering function optimization is + finished, as the last bottleneck is the amount of entities. */ vec2 c_xz = { camera_position[0], camera_position[2] }; vec2 e_xz = { entity->position[0], entity->position[2] }; - if (glm_vec2_distance2 (c_xz, e_xz) > glm_pow2 (cull_dist) && !entity->dont_cull) + if (glm_vec2_distance2 (c_xz, e_xz) > cull_dist*cull_dist && !entity->dont_cull) { return; } diff --git a/game/src/entity/entman.h b/game/src/entity/entman.h index dc18810..37d22a3 100644 --- a/game/src/entity/entman.h +++ b/game/src/entity/entman.h @@ -17,8 +17,6 @@ #define ENTADD(entity) (entman_add_entity (entity)) -#define ENTITY_FRAME_BUDGET_US 100 - typedef struct SpawnRequest { char *template_name; diff --git a/game/src/gl/mesh.c b/game/src/gl/mesh.c index 219ee2e..a4c31ed 100644 --- a/game/src/gl/mesh.c +++ b/game/src/gl/mesh.c @@ -5,16 +5,19 @@ OpenGL function, glVertexAttrib, that repeats the attribute for every subsequent vertex. */ +/* Every vertex attribute here is an int. This is to save GPU time or + some shit. Idk. But we don't need floats anyway. */ + void SimpleMesh_bind (SimpleMesh *mesh) { glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo); glEnableVertexAttribArray (0); - glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (float) * 3, 0); + glVertexAttribPointer (0, 3, GL_INT, GL_FALSE, sizeof (int) * 3, 0); glBindBuffer (GL_ARRAY_BUFFER, mesh->uvbo); glEnableVertexAttribArray (1); - glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0); + glVertexAttribPointer (1, 2, GL_INT, GL_FALSE, sizeof (int) * 2, 0); glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo); } @@ -29,22 +32,22 @@ SimpleMesh SimpleMesh_make_quad1 () { /* The positions are trivial. */ - float positions[12] = { - -1.0, -1.0, 0.0, - +1.0, -1.0, 0.0, - -1.0, 1.0, 0.0, - +1.0, 1.0, 0.0 + int positions[12] = { + -1, -1, 0, + +1, -1, 0, + -1, 1, 0, + +1, 1, 0 }; unsigned int indices[12] = { 3, 2, 0, 0, 1, 3, }; - float uvs[8] = { - 0.0, 1.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0, + int uvs[8] = { + 0, 1, + 1, 1, + 0, 0, + 1, 0, }; SimpleMesh mesh; @@ -54,15 +57,14 @@ SimpleMesh_make_quad1 () glGenBuffers (1, &mesh.ebo); glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 12, positions, GL_STATIC_DRAW); + glBufferData (GL_ARRAY_BUFFER, sizeof (int) * 12, positions, GL_STATIC_DRAW); glEnableVertexAttribArray (0); - glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (float) * 3, 0); + glVertexAttribPointer (0, 3, GL_INT, GL_FALSE, sizeof (int) * 3, 0); glBindBuffer (GL_ARRAY_BUFFER, mesh.uvbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 8, uvs, GL_STATIC_DRAW); + glBufferData (GL_ARRAY_BUFFER, sizeof (int) * 8, uvs, GL_STATIC_DRAW); glEnableVertexAttribArray (1); - glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0); - + glVertexAttribPointer (1, 2, GL_INT, GL_FALSE, sizeof (int) * 2, 0); glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * mesh.indices_len, indices, GL_STATIC_DRAW); @@ -74,11 +76,11 @@ SimpleMesh SimpleMesh_make_quad2 () { /* The positions are trivial. */ - float positions[12] = { - -1.0, -1.0, 0.0, - +1.0, -1.0, 0.0, - -1.0, 1.0, 0.0, - +1.0, 1.0, 0.0 + int positions[12] = { + -1, -1, 0, + +1, -1, 0, + -1, 1, 0, + +1, 1, 0 }; unsigned int indices[12] = { @@ -86,11 +88,11 @@ SimpleMesh_make_quad2 () 3, 2, 0, 0, 1, 3, /* Back of quad 1 */ }; - float uvs[8] = { - 0.0, 1.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0, + int uvs[8] = { + 0, 1, + 1, 1, + 0, 0, + 1, 0, }; SimpleMesh mesh; @@ -100,15 +102,14 @@ SimpleMesh_make_quad2 () glGenBuffers (1, &mesh.ebo); glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 12, positions, GL_STATIC_DRAW); + glBufferData (GL_ARRAY_BUFFER, sizeof (int) * 12, positions, GL_STATIC_DRAW); glEnableVertexAttribArray (0); - glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (float) * 3, 0); + glVertexAttribPointer (0, 3, GL_INT, GL_FALSE, sizeof (int) * 3, 0); glBindBuffer (GL_ARRAY_BUFFER, mesh.uvbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 8, uvs, GL_STATIC_DRAW); + glBufferData (GL_ARRAY_BUFFER, sizeof (int) * 8, uvs, GL_STATIC_DRAW); glEnableVertexAttribArray (1); - glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0); - + glVertexAttribPointer (1, 2, GL_INT, GL_FALSE, sizeof (int) * 2, 0); glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * mesh.indices_len, indices, GL_STATIC_DRAW); @@ -120,16 +121,16 @@ SimpleMesh SimpleMesh_make_quad_x () { /* The positions are trivial. */ - float positions[24] = { - -1.0, -1.0, 0.0, - +1.0, -1.0, 0.0, - -1.0, 1.0, 0.0, - +1.0, 1.0, 0.0, + int positions[24] = { + -1, -1, 0, + +1, -1, 0, + -1, 1, 0, + +1, 1, 0, - 0.0, -1.0, -1.0, - 0.0, -1.0, 1.0, - 0.0, 1.0, -1.0, - 0.0, 1.0, 1.0 + 0, -1, -1, + 0, -1, 1, + 0, 1, -1, + 0, 1, 1 }; unsigned int indices[24] = { @@ -139,16 +140,16 @@ SimpleMesh_make_quad_x () 7, 6, 4, 4, 5, 7 /* Back of quad 2 */ }; - float uvs[16] = { - 0.0, 1.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0, + int uvs[16] = { + 0, 1, + 1, 1, + 0, 0, + 1, 0, - 0.0, 1.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0 + 0, 1, + 1, 1, + 0, 0, + 1, 0 }; SimpleMesh mesh; @@ -158,77 +159,17 @@ SimpleMesh_make_quad_x () glGenBuffers (1, &mesh.ebo); glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 24, positions, GL_STATIC_DRAW); + glBufferData (GL_ARRAY_BUFFER, sizeof (int) * 24, positions, GL_STATIC_DRAW); glEnableVertexAttribArray (0); - glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (float) * 3, 0); + glVertexAttribPointer (0, 3, GL_INT, GL_FALSE, sizeof (int) * 3, 0); glBindBuffer (GL_ARRAY_BUFFER, mesh.uvbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 16, uvs, GL_STATIC_DRAW); + glBufferData (GL_ARRAY_BUFFER, sizeof (int) * 16, uvs, GL_STATIC_DRAW); glEnableVertexAttribArray (1); - glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0); + glVertexAttribPointer (1, 2, GL_INT, GL_FALSE, sizeof (int) * 2, 0); glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * mesh.indices_len, indices, GL_STATIC_DRAW); return mesh; } - -SimpleMesh -SimpleMesh_make_cube () -{ - /* The positions are trivial. */ - float positions[24] = { - -1.0f, -1.0f, -1.0f, - +1.0f, -1.0f, -1.0f, - +1.0f, 1.0f, -1.0f, - -1.0f, 1.0f, -1.0f, - -1.0f, -1.0f, 1.0f, - +1.0f, -1.0f, 1.0f, - +1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 1.0f - }; - - unsigned int indices[36] = { - 4, 5, 6, 6, 7, 4, - 0, 3, 2, 2, 1, 0, - 0, 4, 7, 7, 3, 0, - 1, 2, 6, 6, 5, 1, - 0, 1, 5, 5, 4, 0, - 3, 7, 6, 6, 2, 3 - }; - - /* TODO: make correct UVs. */ - - float uvs[16] = { - 0.0, 1.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0, - - 0.0, 1.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0 - }; - - SimpleMesh mesh; - mesh.indices_len = 36; - glGenBuffers (1, &mesh.pbo); - glGenBuffers (1, &mesh.uvbo); - glGenBuffers (1, &mesh.ebo); - - glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 24, positions, GL_STATIC_DRAW); - glEnableVertexAttribArray (0); - glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (float) * 3, 0); - - glBindBuffer (GL_ARRAY_BUFFER, mesh.uvbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 16, uvs, GL_STATIC_DRAW); - glEnableVertexAttribArray (1); - glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0); - - glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); - glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * mesh.indices_len, indices, GL_STATIC_DRAW); - - return mesh; -} diff --git a/game/src/gl/mesh.h b/game/src/gl/mesh.h index c52596f..ca5802a 100644 --- a/game/src/gl/mesh.h +++ b/game/src/gl/mesh.h @@ -19,4 +19,3 @@ void SimpleMesh_render (SimpleMesh *mesh, bool wireframe); SimpleMesh SimpleMesh_make_quad1 (); SimpleMesh SimpleMesh_make_quad2 (); SimpleMesh SimpleMesh_make_quad_x (); -SimpleMesh SimpleMesh_make_cube (); diff --git a/game/src/graphics.c b/game/src/graphics.c index 97b72b7..ff84fda 100644 --- a/game/src/graphics.c +++ b/game/src/graphics.c @@ -4,8 +4,14 @@ extern vec3 camera_position; extern int last_time; SDL_Window *sdl_window; +int render_distance = 1; + static SDL_GLContext gl_context; +static uint64_t last_check_perf = 0; +static int avg_counter = 0; +static double avg_elapsed = 0; + #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 @@ -61,6 +67,9 @@ graphics_render () { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + uint64_t start = SDL_GetPerformanceCounter (); + uint64_t freq = SDL_GetPerformanceFrequency (); + mat4 projection, view; camera_get_projection (WINDOW_WIDTH / WINDOW_HEIGHT, projection); camera_get_view (view); @@ -87,6 +96,30 @@ graphics_render () glDisable (GL_BLEND); SDL_GL_SwapWindow (sdl_window); + + uint64_t now = SDL_GetPerformanceCounter(); + double elapsed_us = (double) (now - start) * 1000000.0 / (double) freq; + + avg_elapsed += elapsed_us; + avg_counter++; + + if ((now - last_check_perf) >= freq * RENDER_AVG_FREQ_S) + { + double avg = avg_elapsed / avg_counter; + + if (avg < RENDER_FRAME_BUDGET_US && render_distance < RENDER_DISTANCE_MAX) + { + render_distance++; + } + else if (avg > RENDER_FRAME_BUDGET_US && render_distance > RENDER_DISTANCE_MIN) + { + render_distance--; + } + + avg_elapsed = 0; + avg_counter = 0; + last_check_perf = now; + } } void diff --git a/game/src/graphics.h b/game/src/graphics.h index 565f0a6..e5805f9 100644 --- a/game/src/graphics.h +++ b/game/src/graphics.h @@ -13,6 +13,14 @@ #define FRUSTUM_CULL 1 +#define CHUNK_FRAME_BUDGET_US 5000 +#define ENTITY_FRAME_BUDGET_US 5000 + +#define RENDER_FRAME_BUDGET_US 16666 /* 60 FPS */ +#define RENDER_AVG_FREQ_S 10 +#define RENDER_DISTANCE_MIN 1 +#define RENDER_DISTANCE_MAX 12 + void graphics_init (); void graphics_render (); void graphics_free ();