implement timer

This commit is contained in:
Ben Kyd
2023-10-16 18:48:45 +01:00
parent 1176f320b8
commit 96473cf236
3 changed files with 133 additions and 33 deletions

View File

@@ -22,6 +22,57 @@
namespace inferno {
InfernoTimer* inferno_timer_create()
{
InfernoTimer* timer = new InfernoTimer;
// lazy init
inferno_timer_start(timer);
inferno_timer_end(timer);
return timer;
}
void inferno_timer_cleanup(InfernoTimer* timer)
{
delete timer;
}
void inferno_timer_rolling_average(InfernoTimer* timer, int count)
{
if (timer->Times.size() > count)
timer->Times.erase(timer->Times.begin());
timer->RollingAverage = std::accumulate(timer->Times.begin(), timer->Times.end(), std::chrono::duration<double>(0.0)) / count;
}
void inferno_timer_start(InfernoTimer* timer)
{
timer->StartTime = std::chrono::high_resolution_clock::now();
}
void inferno_timer_end(InfernoTimer* timer)
{
timer->EndTime = std::chrono::high_resolution_clock::now();
timer->Time = timer->EndTime - timer->StartTime;
timer->Times.push_back(timer->Time);
inferno_timer_rolling_average(timer, 100);
}
void inferno_timer_print(InfernoTimer* timer, bool time)
{
if (time)
yolo::info("Time: {}s", timer->Time.count());
yolo::info("Average time: {}ms", timer->RollingAverage.count() * 1000.0);
}
std::chrono::duration<double> inferno_timer_get_time(InfernoTimer* timer)
{
return timer->Time;
}
std::chrono::duration<double> inferno_timer_get_average(InfernoTimer* timer)
{
return timer->RollingAverage;
}
InfernoApp* inferno_create()
{
// MOTD
@@ -30,6 +81,7 @@ InfernoApp* inferno_create()
InfernoApp* app = new InfernoApp;
app->Input = new InfernoInput;
app->Scene = scene::scene_create();
app->MainTimer = inferno_timer_create();
// Create window
graphics::window_create("Inferno v" INFERNO_VERSION, 1280, 720);
@@ -92,7 +144,7 @@ void inferno_preset_gui(InfernoApp* app)
yolo::info("LAYOUT SET TO DEFAULT");
}
void inferno_move_input(InfernoApp* app)
void inferno_move_input(InfernoApp* app, std::chrono::duration<double> deltaTime)
{
static GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
glfwSetCursor(graphics::window_get_glfw_window(), cursor);
@@ -137,20 +189,55 @@ void inferno_stop_move_input(InfernoApp* app)
app->Input->MouseDelta = { 0.0f, 0.0f };
}
bool inferno_pre(InfernoApp* app)
{
app->FrameCount++;
if (app->FrameCount % 100 == 0) {
yolo::info("FPS: {}", 1.0 / inferno_timer_get_time(app->MainTimer).count());
inferno_timer_print(app->MainTimer, false);
}
if (!graphics::window_new_frame())
return false;
// set the main window to the dockspace and then on the first launch set the preset
ImGuiID dockspace_id = ImGui::GetID("main");
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) {
inferno_preset_gui(app);
}
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
return true;
}
void inferno_end(InfernoApp* app)
{
// clang-format off
GLenum err;
while((err = glGetError()) != GL_NO_ERROR) {
std::string error;
switch (err) {
case GL_INVALID_ENUM: error = "INVALID_ENUM"; break;
case GL_INVALID_VALUE: error = "INVALID_VALUE"; break;
case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break;
case GL_STACK_OVERFLOW: error = "STACK_OVERFLOW"; break;
case GL_STACK_UNDERFLOW: error = "STACK_UNDERFLOW"; break;
case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break;
default: error = std::to_string((uint32_t)err); break;
}
yolo::error("[GL]: {} {}", err, error);
}
}
int inferno_run(InfernoApp* app)
{
while (true) {
if (!graphics::window_new_frame())
inferno_timer_start(app->MainTimer);
if (!inferno_pre(app))
break;
// set the main window to the dockspace and then on the first launch set the preset
ImGuiID dockspace_id = ImGui::GetID("main");
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) {
inferno_preset_gui(app);
}
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
if (glm::length(app->Input->MouseDelta) > 0.0f)
graphics::camera_mouse_move(app->Scene->Camera, app->Input->MouseDelta);
if (app->Input->MovementDelta != 0b00000000)
@@ -200,7 +287,7 @@ int inferno_run(InfernoApp* app)
if (showPreview && ImGui::Begin("Preview", nullptr, ImGuiWindowFlags_NoScrollbar)) {
if (ImGui::IsWindowHovered()) {
inferno_move_input(app);
inferno_move_input(app, inferno_timer_get_time(app->MainTimer));
} else {
inferno_stop_move_input(app);
}
@@ -229,24 +316,11 @@ int inferno_run(InfernoApp* app)
ImGui::ShowDemoWindow();
}
// clang-format off
GLenum err;
while((err = glGetError()) != GL_NO_ERROR) {
std::string error;
switch (err) {
case GL_INVALID_ENUM: error = "INVALID_ENUM"; break;
case GL_INVALID_VALUE: error = "INVALID_VALUE"; break;
case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break;
case GL_STACK_OVERFLOW: error = "STACK_OVERFLOW"; break;
case GL_STACK_UNDERFLOW: error = "STACK_UNDERFLOW"; break;
case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break;
default: error = std::to_string((uint32_t)err); break;
}
yolo::error("[GL]: {} {}", err, error);
}
graphics::window_render();
inferno_end(app);
inferno_timer_end(app->MainTimer);
}
return 1;

View File

@@ -18,6 +18,27 @@ namespace scene {
struct Scene;
}
typedef struct InfernoTimer {
std::chrono::time_point<std::chrono::high_resolution_clock> StartTime;
std::chrono::time_point<std::chrono::high_resolution_clock> EndTime;
std::chrono::duration<double> Time;
std::vector<std::chrono::duration<double>> Times;
std::chrono::duration<double> RollingAverage;
} InfernoTimer;
InfernoTimer* inferno_timer_create();
void inferno_timer_cleanup(InfernoTimer* timer);
void inferno_timer_rolling_average(InfernoTimer* timer, int count);
void inferno_timer_start(InfernoTimer* timer);
void inferno_timer_end(InfernoTimer* timer);
void inferno_timer_print(InfernoTimer* timer, bool time);
std::chrono::duration<double> inferno_timer_get_time(InfernoTimer* timer);
std::chrono::duration<double> inferno_timer_get_average(InfernoTimer* timer);
typedef struct InfernoInput {
glm::vec2 MouseDelta = {0.0f, 0.0f};
uint8_t MovementDelta = 0;
@@ -28,13 +49,19 @@ typedef struct InfernoApp {
scene::Scene* Scene;
graphics::PreviewRenderer* PreviewRenderer;
graphics::RayRenderer* RayRenderer;
InfernoTimer* MainTimer;
uint64_t FrameCount;
} InfernoApp;
InfernoApp* inferno_create();
void inferno_cleanup(InfernoApp* app);
void inferno_preset_gui(InfernoApp* app);
void inferno_move_input(InfernoApp* app);
void inferno_move_input(InfernoApp* app, std::chrono::duration<double> delta);
void inferno_stop_move_input(InfernoApp* app);
bool inferno_pre(InfernoApp* app);
void inferno_end(InfernoApp* app);
int inferno_run(InfernoApp* app);
} // namespace inferno

View File

@@ -104,12 +104,11 @@ void rayr_draw(RayRenderer* renderer)
// ray data and nothing else being reallocated every frame for no reason
// ReferencedRayField startRays = mRaySource->getInitialRays(true);
for (int x = 0; x < renderer->Viewport->x; x++)
for (int y = 0; y < renderer->Viewport->y; y++)
renderer->RenderData[y * renderer->Viewport->x + x] = { 0.1f, 0.1f, 0.1f, 1.0f };
// for (int x = 0; x < renderer->Viewport->x; x++)
// for (int y = 0; y < renderer->Viewport->y; y++)
// renderer->RenderData[y * renderer->Viewport->x + x] = { 0.1f, 0.1f, 0.1f, 1.0f };
//
// before we start we now want to check that it hasn't been force-stopped
yolo::info("Sample complete");
}
//
// void RayRenderer::computeHit(HitInfo* info)