diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 52 |
1 files changed, 46 insertions, 6 deletions
| @@ -72,12 +72,14 @@ typedef struct State { | |||
| 72 | SDL_Window* window; | 72 | SDL_Window* window; |
| 73 | void* gfx_mem; | 73 | void* gfx_mem; |
| 74 | swgfx* gfx; | 74 | swgfx* gfx; |
| 75 | Uint64 last_tick; | ||
| 76 | R stats_elapsed; | ||
| 75 | Camera camera; | 77 | Camera camera; |
| 76 | CameraController camera_controller; | 78 | CameraController camera_controller; |
| 77 | Uint64 last_tick; | ||
| 78 | Model* model; | 79 | Model* model; |
| 79 | size_t numTextures; | 80 | size_t numTextures; |
| 80 | sgImage textures[MaxTextures]; | 81 | sgImage textures[MaxTextures]; |
| 82 | sgCounters last_stats; | ||
| 81 | } State; | 83 | } State; |
| 82 | 84 | ||
| 83 | static bool StateWrite(const State* state, FILE* file) { | 85 | static bool StateWrite(const State* state, FILE* file) { |
| @@ -121,10 +123,34 @@ static bool StateLoad(const char* path, State* state) { | |||
| 121 | return result; | 123 | return result; |
| 122 | } | 124 | } |
| 123 | 125 | ||
| 126 | static inline R frac(R a) { return a - (R)((int)a); } | ||
| 127 | |||
| 124 | static sgVec3 SgVec3FromMathVec3(vec3 v) { | 128 | static sgVec3 SgVec3FromMathVec3(vec3 v) { |
| 125 | return (sgVec3){v.x, v.y, v.z}; | 129 | return (sgVec3){v.x, v.y, v.z}; |
| 126 | } | 130 | } |
| 127 | 131 | ||
| 132 | static void ShowStats(const sgCounters* last_stats, const sgCounters* stats, R time_elapsed) { | ||
| 133 | assert(last_stats); | ||
| 134 | assert(stats); | ||
| 135 | if (stats->frames == last_stats->frames) { | ||
| 136 | return; | ||
| 137 | } | ||
| 138 | assert(time_elapsed >= 0.f); | ||
| 139 | |||
| 140 | const uint64_t frames_elapsed = stats->frames - last_stats->frames; | ||
| 141 | #define RATE_PER_SEC(STAT) (int)((R)(stats->STAT - last_stats->STAT) / time_elapsed) | ||
| 142 | #define RATE_PER_FRAME(STAT) (int)((stats->STAT - last_stats->STAT) / frames_elapsed) | ||
| 143 | const int fps = RATE_PER_SEC(frames); | ||
| 144 | const int pps = RATE_PER_SEC(pixels); | ||
| 145 | const int tps = RATE_PER_SEC(triangles3); | ||
| 146 | const int ppf = RATE_PER_FRAME(pixels); | ||
| 147 | const int tpf = RATE_PER_FRAME(triangles3); | ||
| 148 | #undef RATE_PER_FRAME | ||
| 149 | #undef RATE_PER_SEC | ||
| 150 | |||
| 151 | printf("fps: %d, pps: %d, tps: %d, ppf: %d, tpf: %d\n", fps, pps, tps, ppf, tpf); | ||
| 152 | } | ||
| 153 | |||
| 128 | static CameraCommand CameraCommandFromInput( | 154 | static CameraCommand CameraCommandFromInput( |
| 129 | const bool* keyboard_state, const SDL_MouseButtonFlags mouse_flags) { | 155 | const bool* keyboard_state, const SDL_MouseButtonFlags mouse_flags) { |
| 130 | assert(keyboard_state); | 156 | assert(keyboard_state); |
| @@ -190,6 +216,14 @@ static bool Update(State* state, R dt) { | |||
| 190 | const CameraCommand cmd = CameraCommandFromInput(keyboard_state, mouse_flags); | 216 | const CameraCommand cmd = CameraCommandFromInput(keyboard_state, mouse_flags); |
| 191 | UpdateCamera(&state->camera_controller, dt, mouse, cmd, &state->camera); | 217 | UpdateCamera(&state->camera_controller, dt, mouse, cmd, &state->camera); |
| 192 | 218 | ||
| 219 | state->stats_elapsed += dt; | ||
| 220 | if (state->stats_elapsed >= 1.f) { | ||
| 221 | const sgCounters stats = sgGetCounters(state->gfx); | ||
| 222 | ShowStats(&state->last_stats, &stats, state->stats_elapsed); | ||
| 223 | state->last_stats = stats; | ||
| 224 | state->stats_elapsed = frac(state->stats_elapsed); | ||
| 225 | } | ||
| 226 | |||
| 193 | return true; | 227 | return true; |
| 194 | } | 228 | } |
| 195 | 229 | ||
| @@ -401,6 +435,7 @@ static bool Initialize(State* state) { | |||
| 401 | }; | 435 | }; |
| 402 | 436 | ||
| 403 | state->last_tick = SDL_GetPerformanceCounter(); | 437 | state->last_tick = SDL_GetPerformanceCounter(); |
| 438 | state->stats_elapsed = 0.f; | ||
| 404 | 439 | ||
| 405 | return true; | 440 | return true; |
| 406 | } | 441 | } |
| @@ -436,13 +471,18 @@ static void Shutdown(State* state) { | |||
| 436 | } | 471 | } |
| 437 | } | 472 | } |
| 438 | 473 | ||
| 439 | static R GetDeltaTime(State* state) { | 474 | static R GetDeltaTimeSec(Uint64 before, Uint64 after) { |
| 440 | assert(state); | ||
| 441 | constexpr Uint64 NS_IN_SEC = 1'000'000'000; | 475 | constexpr Uint64 NS_IN_SEC = 1'000'000'000; |
| 442 | const Uint64 this_tick = SDL_GetPerformanceCounter(); | ||
| 443 | const Uint64 freq = SDL_GetPerformanceFrequency(); | 476 | const Uint64 freq = SDL_GetPerformanceFrequency(); |
| 444 | const Uint64 elapsed_ns = (this_tick - state->last_tick) * NS_IN_SEC / freq; | 477 | const Uint64 elapsed_ns = (after - before) * NS_IN_SEC / freq; |
| 445 | const R elapsed_sec = (R)elapsed_ns / (R)NS_IN_SEC; | 478 | const R elapsed_sec = (R)elapsed_ns / (R)NS_IN_SEC; |
| 479 | return elapsed_sec; | ||
| 480 | } | ||
| 481 | |||
| 482 | static R GetFrameDeltaTime(State* state) { | ||
| 483 | assert(state); | ||
| 484 | const Uint64 this_tick = SDL_GetPerformanceCounter(); | ||
| 485 | const R elapsed_sec = GetDeltaTimeSec(state->last_tick, this_tick); | ||
| 446 | state->last_tick = this_tick; | 486 | state->last_tick = this_tick; |
| 447 | return elapsed_sec; | 487 | return elapsed_sec; |
| 448 | } | 488 | } |
| @@ -532,7 +572,7 @@ int main() { | |||
| 532 | 572 | ||
| 533 | // Draw and update if needed. | 573 | // Draw and update if needed. |
| 534 | if (success && running) { | 574 | if (success && running) { |
| 535 | const R dt = GetDeltaTime(&state); | 575 | const R dt = GetFrameDeltaTime(&state); |
| 536 | success = Update(&state, dt); | 576 | success = Update(&state, dt); |
| 537 | } | 577 | } |
| 538 | if (success && running) { | 578 | if (success && running) { |
