Implement timings

This commit is contained in:
MrLetsplay 2023-12-21 18:27:39 +01:00
parent f98772758d
commit 75276e4809
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
6 changed files with 84 additions and 10 deletions

View File

@ -1,4 +1,5 @@
#include "engine.h" #include "engine.h"
#include "timings.h"
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
@ -8,6 +9,7 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <string>
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
@ -175,13 +177,16 @@ int init() {
int start() { int start() {
int prevTime = 0; int prevTime = 0;
while(!glfwWindowShouldClose(kekData.window)) { while(!glfwWindowShouldClose(kekData.window)) {
auto start = std::chrono::high_resolution_clock::now(); Timings timings;
Timer frameTimer;
// Clear the screen // Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, kekData.screenWidth, kekData.screenHeight); 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) { for(auto cb : kekData.input->periodicCallbacks) {
cb.second(PeriodicEvent{kekData.window}); cb.second(PeriodicEvent{kekData.window});
@ -202,6 +207,8 @@ int start() {
glUniform3fv(glGetUniformLocation(kekData.shader->id, "cameraPos"), 1, glm::value_ptr(position)); glUniform3fv(glGetUniformLocation(kekData.shader->id, "cameraPos"), 1, glm::value_ptr(position));
if(kekData.shader->lighting) { if(kekData.shader->lighting) {
Timer lightingTimer;
LightList *lights = kekData.activeScene->lights; LightList *lights = kekData.activeScene->lights;
std::vector<Light *> shaderLights; // TODO: Maybe don't compute on every frame std::vector<Light *> 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, "numPointLights"), numPointLights);
glUniform1i(glGetUniformLocation(kekData.shader->id, "numDirectionalLights"), numDirectionalLights); glUniform1i(glGetUniformLocation(kekData.shader->id, "numDirectionalLights"), numDirectionalLights);
glUniform1i(glGetUniformLocation(kekData.shader->id, "numSpotLights"), numSpotLights); glUniform1i(glGetUniformLocation(kekData.shader->id, "numSpotLights"), numSpotLights);
timings.lightingTime = lightingTimer.elapsedSeconds();
} }
Timer drawTimer;
kekData.activeScene->draw(kekData.shader); kekData.activeScene->draw(kekData.shader);
timings.renderTime = drawTimer.elapsedSeconds();
} }
glDisable(GL_DEPTH_TEST); 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); glm::mat4 uiProjection = glm::ortho(0.0f, (float) kekData.screenWidth, (float) kekData.screenHeight, 0.0f);
int time = (int) (glfwGetTime() * 10); 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; prevTime = time;
for(UIElement *uiEl : kekData.ui->elements) { for(UIElement *uiEl : kekData.ui->elements) {
@ -290,13 +311,14 @@ int start() {
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
Timer idleTimer;
// Swap buffers and poll window events // Swap buffers and poll window events
glfwSwapBuffers(kekData.window); glfwSwapBuffers(kekData.window);
glfwPollEvents(); glfwPollEvents();
timings.idleTime = idleTimer.elapsedSeconds();
auto end = std::chrono::high_resolution_clock::now(); timings.frameTime = frameTimer.elapsedSeconds();
std::chrono::duration<float> secsTaken = end - start; kekData.lastTimings = timings;
kekData.lastFrameTime = secsTaken.count();
} }
return KEK_SUCCESS; return KEK_SUCCESS;

View File

@ -0,0 +1,20 @@
#include "timings.h"
#include <chrono>
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<float> secsTaken = now - start;
return secsTaken.count();
}
}

View File

@ -94,7 +94,7 @@ void DefaultPlayerController::update() {
kekData.player->onGround = onGround; kekData.player->onGround = onGround;
if(!onGround) { if(!onGround) {
velocity += gravity * kekData.lastFrameTime; velocity += gravity * kekData.lastTimings.frameTime;
} else { } else {
velocity = glm::vec3(0); velocity = glm::vec3(0);
} }
@ -136,7 +136,7 @@ void DefaultPlayerController::update() {
move += direction; move += direction;
} }
this->move(move * kekData.lastFrameTime); this->move(move * kekData.lastTimings.frameTime);
} }
} }

View File

@ -46,7 +46,7 @@ void NoclipPlayerController::update() {
} }
if(glm::length2(direction) > 0) { if(glm::length2(direction) > 0) {
direction = glm::normalize(direction) * noclipSpeed * kekData.lastFrameTime; direction = glm::normalize(direction) * noclipSpeed * kekData.lastTimings.frameTime;
move(direction); move(direction);
} }
} }

View File

@ -10,6 +10,7 @@
#include "player.h" #include "player.h"
#include "scene.h" #include "scene.h"
#include "texture.h" #include "texture.h"
#include "timings.h"
#include "ui.h" #include "ui.h"
namespace kek { namespace kek {
@ -30,7 +31,7 @@ struct KekData {
int screenWidth; int screenWidth;
int screenHeight; int screenHeight;
float lastFrameTime; Timings lastTimings;
std::map<std::string, std::weak_ptr<Texture>> loadedTextures; std::map<std::string, std::weak_ptr<Texture>> loadedTextures;
std::map<std::string, std::weak_ptr<Font>> loadedFonts; std::map<std::string, std::weak_ptr<Font>> loadedFonts;

View File

@ -0,0 +1,31 @@
#pragma once
#include <chrono>
#include <string>
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);
}
}