From 75276e48096b8af086ccdb049af8d4ac4cb0c3b5 Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Thu, 21 Dec 2023 18:27:39 +0100 Subject: [PATCH] Implement timings --- src/kekengine/cpp/common/engine.cpp | 34 +++++++++++++++---- src/kekengine/cpp/debug/timings.cpp | 20 +++++++++++ .../cpp/player/defaultplayercontroller.cpp | 4 +-- .../cpp/player/noclipplayercontroller.cpp | 2 +- src/kekengine/include/internal.h | 3 +- src/kekengine/include/timings.h | 31 +++++++++++++++++ 6 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 src/kekengine/cpp/debug/timings.cpp create mode 100644 src/kekengine/include/timings.h diff --git a/src/kekengine/cpp/common/engine.cpp b/src/kekengine/cpp/common/engine.cpp index cad2b58..7ead9e8 100644 --- a/src/kekengine/cpp/common/engine.cpp +++ b/src/kekengine/cpp/common/engine.cpp @@ -1,4 +1,5 @@ #include "engine.h" +#include "timings.h" #include #include @@ -8,6 +9,7 @@ #include #include #include +#include #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION @@ -175,13 +177,16 @@ int init() { int start() { int prevTime = 0; while(!glfwWindowShouldClose(kekData.window)) { - auto start = std::chrono::high_resolution_clock::now(); + Timings timings; + Timer frameTimer; // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, kekData.screenWidth, kekData.screenHeight); - Physics::step(kekData.lastFrameTime); + Timer physicsTimer; + Physics::step(kekData.lastTimings.frameTime); + timings.physicsTime = physicsTimer.elapsedSeconds(); for(auto cb : kekData.input->periodicCallbacks) { cb.second(PeriodicEvent{kekData.window}); @@ -202,6 +207,8 @@ int start() { glUniform3fv(glGetUniformLocation(kekData.shader->id, "cameraPos"), 1, glm::value_ptr(position)); if(kekData.shader->lighting) { + Timer lightingTimer; + LightList *lights = kekData.activeScene->lights; std::vector shaderLights; // TODO: Maybe don't compute on every frame @@ -267,9 +274,13 @@ int start() { glUniform1i(glGetUniformLocation(kekData.shader->id, "numPointLights"), numPointLights); glUniform1i(glGetUniformLocation(kekData.shader->id, "numDirectionalLights"), numDirectionalLights); glUniform1i(glGetUniformLocation(kekData.shader->id, "numSpotLights"), numSpotLights); + + timings.lightingTime = lightingTimer.elapsedSeconds(); } + Timer drawTimer; kekData.activeScene->draw(kekData.shader); + timings.renderTime = drawTimer.elapsedSeconds(); } glDisable(GL_DEPTH_TEST); @@ -279,7 +290,17 @@ int start() { glm::mat4 uiProjection = glm::ortho(0.0f, (float) kekData.screenWidth, (float) kekData.screenHeight, 0.0f); int time = (int) (glfwGetTime() * 10); - if(time != prevTime) fpsText->setText("FPS: " + std::to_string((int) floor(1.0f / kekData.lastFrameTime)) + " (" + std::to_string(kekData.lastFrameTime * 1000) + " ms)"); + if(time != prevTime) { + int fps = (int) floor(1.0f / kekData.lastTimings.frameTime); + std::string str = std::format("FPS: {} ({}) | Physics: {}, Lighting: {}, Render: {}, Idle: {}", + std::to_string(fps), + formatSeconds(kekData.lastTimings.frameTime), + formatSeconds(kekData.lastTimings.physicsTime), + formatSeconds(kekData.lastTimings.lightingTime), + formatSeconds(kekData.lastTimings.renderTime), + formatSeconds(kekData.lastTimings.idleTime)); + fpsText->setText(str); + } prevTime = time; for(UIElement *uiEl : kekData.ui->elements) { @@ -290,13 +311,14 @@ int start() { glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); + Timer idleTimer; // Swap buffers and poll window events glfwSwapBuffers(kekData.window); glfwPollEvents(); + timings.idleTime = idleTimer.elapsedSeconds(); - auto end = std::chrono::high_resolution_clock::now(); - std::chrono::duration secsTaken = end - start; - kekData.lastFrameTime = secsTaken.count(); + timings.frameTime = frameTimer.elapsedSeconds(); + kekData.lastTimings = timings; } return KEK_SUCCESS; diff --git a/src/kekengine/cpp/debug/timings.cpp b/src/kekengine/cpp/debug/timings.cpp new file mode 100644 index 0000000..c424ea8 --- /dev/null +++ b/src/kekengine/cpp/debug/timings.cpp @@ -0,0 +1,20 @@ +#include "timings.h" +#include + +namespace kek { + +Timer::Timer() { + reset(); +} + +void Timer::reset() { + this->start = std::chrono::high_resolution_clock::now(); +} + +float Timer::elapsedSeconds() { + auto now = std::chrono::high_resolution_clock::now(); + std::chrono::duration secsTaken = now - start; + return secsTaken.count(); +} + +} diff --git a/src/kekengine/cpp/player/defaultplayercontroller.cpp b/src/kekengine/cpp/player/defaultplayercontroller.cpp index 59c0ed9..fa248ef 100644 --- a/src/kekengine/cpp/player/defaultplayercontroller.cpp +++ b/src/kekengine/cpp/player/defaultplayercontroller.cpp @@ -94,7 +94,7 @@ void DefaultPlayerController::update() { kekData.player->onGround = onGround; if(!onGround) { - velocity += gravity * kekData.lastFrameTime; + velocity += gravity * kekData.lastTimings.frameTime; } else { velocity = glm::vec3(0); } @@ -136,7 +136,7 @@ void DefaultPlayerController::update() { move += direction; } - this->move(move * kekData.lastFrameTime); + this->move(move * kekData.lastTimings.frameTime); } } diff --git a/src/kekengine/cpp/player/noclipplayercontroller.cpp b/src/kekengine/cpp/player/noclipplayercontroller.cpp index b2df940..445ac0b 100644 --- a/src/kekengine/cpp/player/noclipplayercontroller.cpp +++ b/src/kekengine/cpp/player/noclipplayercontroller.cpp @@ -46,7 +46,7 @@ void NoclipPlayerController::update() { } if(glm::length2(direction) > 0) { - direction = glm::normalize(direction) * noclipSpeed * kekData.lastFrameTime; + direction = glm::normalize(direction) * noclipSpeed * kekData.lastTimings.frameTime; move(direction); } } diff --git a/src/kekengine/include/internal.h b/src/kekengine/include/internal.h index 5a8f0bf..d03f6fc 100644 --- a/src/kekengine/include/internal.h +++ b/src/kekengine/include/internal.h @@ -10,6 +10,7 @@ #include "player.h" #include "scene.h" #include "texture.h" +#include "timings.h" #include "ui.h" namespace kek { @@ -30,7 +31,7 @@ struct KekData { int screenWidth; int screenHeight; - float lastFrameTime; + Timings lastTimings; std::map> loadedTextures; std::map> loadedFonts; diff --git a/src/kekengine/include/timings.h b/src/kekengine/include/timings.h new file mode 100644 index 0000000..76d7f25 --- /dev/null +++ b/src/kekengine/include/timings.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace kek { + +struct Timings { + float frameTime = 0; + float physicsTime = 0; + float lightingTime = 0; + float renderTime = 0; + float idleTime = 0; +}; + +class Timer { + + private: + std::chrono::high_resolution_clock::time_point start; + + public: + void reset(); + float elapsedSeconds(); + Timer(); +}; + +inline std::string formatSeconds(float seconds) { + return std::format("{:.2f} ms", seconds * 1000); +} + +}