Frame budgets now in nanoseconds, game runs okayish on 5 % CPU
This commit is contained in:
+19
-15
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
@@ -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 ();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user