Frame budgets now in nanoseconds, game runs okayish on 5 % CPU

This commit is contained in:
2025-06-07 16:16:52 +02:00
parent eba888ef4d
commit 9971052f14
6 changed files with 40 additions and 31 deletions
+19 -15
View File
@@ -11,7 +11,6 @@ static GHashTable *chunks;
static GHashTable *chunk_meshes;
static bool bound = false;
static int frame_chunks = 0;
guint
chunkman_ivec2_hash (gconstpointer key)
@@ -113,22 +112,25 @@ chunkman_tick (vec3 position)
int cx, cz;
chunkman_world_to_chunk (position[0], position[2], &cx, &cz);
unsigned int frame_time = SDL_GetTicks ();
frame_chunks = 0;
uint64_t start = SDL_GetPerformanceCounter ();
uint64_t freq = SDL_GetPerformanceFrequency ();
double elapsed_us = 0;
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)
{
uint64_t now = SDL_GetPerformanceCounter ();
elapsed_us = (double) (now - start) * 1000000.0 / (double) freq;
if (elapsed_us > CHUNK_FRAME_BUDGET_US)
{
return;
}
if (chunkman_get_Chunk_at (x, z) == NULL)
{
chunkman_generate_Chunk_at (x, z);
++frame_chunks;
}
if (frame_chunks > CHUNKS_PER_FRAME || SDL_GetTicks () - frame_time > CHUNK_FRAME_BUDGET)
{
return;
}
}
}
@@ -137,15 +139,17 @@ chunkman_tick (vec3 position)
{
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;
if (elapsed_us > CHUNK_FRAME_BUDGET_US)
{
return;
}
if (chunkman_get_ChunkMesh_at (x, z) == NULL)
{
chunkman_generate_ChunkMesh_at (x, z);
++frame_chunks;
}
if (frame_chunks > CHUNKS_PER_FRAME || SDL_GetTicks () - frame_time > CHUNK_FRAME_BUDGET)
{
return;
}
}
}
+1 -2
View File
@@ -12,8 +12,7 @@
#define RENDER_DISTANCE 5
#define RENDER_SQR (RENDER_DISTANCE*RENDER_DISTANCE)
#define TERRAIN_HEIGHT 8.0
#define CHUNK_FRAME_BUDGET 5
#define CHUNKS_PER_FRAME 1
#define CHUNK_FRAME_BUDGET_US 100
void chunkman_init ();
void chunkman_tick (vec3 position);
+8 -3
View File
@@ -1,9 +1,11 @@
#pragma once
#include <stdbool.h>
/* TODO: In the future, if entities are out of the tick radius, when
they reappear, calculate what would happen to them during the time
they were out of the radius. Useful for growing plants and
whatnot. */
/* There should also be an entity mesh type of QUAD1, as billboards
always face the camera, thus the back side need not be rendered. */
#include <stdbool.h>
typedef struct Entity
{
@@ -20,6 +22,9 @@ typedef struct Entity
void *userdata;
void (*on_tick) (struct Entity *self);
bool tick_me_i_dont_care; /* Tick this entity regardless of the
distance and other
predicates. Useful for NPCs. */
vec3 position;
vec3 rotation;
+10 -8
View File
@@ -16,8 +16,6 @@ int n_frame_ents;
static GArray *entities;
static GQueue *spawn_requests;
static int frame_ents = 0;
static SimpleMesh mesh_quad1, mesh_quad2, mesh_quad_x, mesh_cube;
static unsigned int last_program = -1;
static unsigned int last_type = -1;
@@ -90,15 +88,19 @@ spawn_queue_process_one ()
void
entman_tick ()
{
/* Handle spawn requests. */
unsigned int frame_time = SDL_GetTicks ();
frame_ents = 0;
uint64_t start = SDL_GetPerformanceCounter ();
uint64_t freq = SDL_GetPerformanceFrequency ();
double elapsed_us = 0;
while (!g_queue_is_empty (spawn_requests) && SDL_GetTicks () - frame_time < ENTITY_FRAME_BUDGET
&& frame_ents < ENTITIES_PER_FRAME)
while (!g_queue_is_empty (spawn_requests))
{
uint64_t now = SDL_GetPerformanceCounter();
elapsed_us = (double) (now - start) * 1000000.0 / (double) freq;
if (elapsed_us > ENTITY_FRAME_BUDGET_US)
break;
spawn_queue_process_one ();
++frame_ents;
}
/* Handle on tick events. */
+1 -2
View File
@@ -17,8 +17,7 @@
#define ENTADD(entity) (entman_add_entity (entity))
#define ENTITY_FRAME_BUDGET 2
#define ENTITIES_PER_FRAME 16
#define ENTITY_FRAME_BUDGET_US 100
typedef struct SpawnRequest
{
+1 -1
View File
@@ -52,8 +52,8 @@ SDL_AppIterate (void *appstate)
UNUSED (appstate);
game_state_tick (SDL_GetTicks ());
entman_tick ();
chunkman_tick (camera_position);
entman_tick ();
uiman_tick ();
graphics_render ();