feat: add tracy / various fixes
This commit is contained in:
+216
-78
@@ -10,7 +10,16 @@
|
||||
#include "glm/gtx/transform.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
#include <tracy/Tracy.hpp>
|
||||
#include <common/TracySystem.hpp>
|
||||
|
||||
struct TracyFrameScope
|
||||
{
|
||||
~TracyFrameScope()
|
||||
{
|
||||
FrameMark;
|
||||
}
|
||||
};
|
||||
|
||||
App::App()
|
||||
{
|
||||
@@ -19,7 +28,9 @@ App::App()
|
||||
void App::init(const AppParams& params)
|
||||
{
|
||||
m_params = params;
|
||||
|
||||
ZoneScopedN("App::init");
|
||||
tracy::SetThreadName("Main Thread");
|
||||
TracySetProgramName(params.appName.c_str());
|
||||
AssetFS::GetInstance().Init(params.exeDir);
|
||||
// AssetFS::GetInstance().Mount("engine", params.exeDir / "assets" / "engine");
|
||||
// AssetFS::GetInstance().Mount("game", params.exeDir / "assets" / "game");
|
||||
@@ -53,16 +64,21 @@ void App::init(const AppParams& params)
|
||||
|
||||
void App::run()
|
||||
{
|
||||
Time::GetInstance().Update(); // initialize delta timing
|
||||
ZoneScopedN("App::run");
|
||||
|
||||
Time::GetInstance().Update();
|
||||
|
||||
const float fixedDt = static_cast<float>(Time::GetInstance().FixedDeltaTime());
|
||||
const int maxSteps = 5; // prevent spiral of death
|
||||
const int maxSteps = 5;
|
||||
float accumulator = 0.0f;
|
||||
|
||||
isRunning = true;
|
||||
|
||||
while (isRunning)
|
||||
{
|
||||
// ---- Update timing ---
|
||||
TracyFrameScope tracyFrame;
|
||||
ZoneScopedN("App::Frame");
|
||||
|
||||
Time::GetInstance().Update();
|
||||
float dt = static_cast<float>(Time::GetInstance().DeltaTime());
|
||||
|
||||
@@ -72,117 +88,193 @@ void App::run()
|
||||
{
|
||||
float newFPS = 1.0f / dt;
|
||||
avgFPS = std::lerp(avgFPS, newFPS, 0.1f);
|
||||
TracyPlot("FPS", avgFPS);
|
||||
TracyPlot("Delta Time ms", dt * 1000.0f);
|
||||
}
|
||||
|
||||
accumulator += dt;
|
||||
|
||||
InputManager::GetInstance().BeginFrame();
|
||||
camera.Update(dt);
|
||||
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
imguiPass.handleEvent(event);
|
||||
if (event.type == SDL_QUIT)
|
||||
ZoneScopedN("Input BeginFrame + Camera");
|
||||
InputManager::GetInstance().BeginFrame();
|
||||
camera.Update(dt);
|
||||
}
|
||||
|
||||
{
|
||||
ZoneScopedN("SDL Events");
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
isRunning = false;
|
||||
break;
|
||||
}
|
||||
if (event.type == SDL_WINDOWEVENT)
|
||||
{
|
||||
switch (event.window.event)
|
||||
ZoneScopedN("SDL Event");
|
||||
|
||||
imguiPass.handleEvent(event);
|
||||
|
||||
if (event.type == SDL_QUIT)
|
||||
{
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
isRunning = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (event.type == SDL_WINDOWEVENT)
|
||||
{
|
||||
switch (event.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
resizePending = true;
|
||||
lastResizeTime = std::chrono::steady_clock::now();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const bool mouseEvent =
|
||||
event.type == SDL_MOUSEBUTTONDOWN ||
|
||||
event.type == SDL_MOUSEBUTTONUP ||
|
||||
event.type == SDL_MOUSEMOTION ||
|
||||
event.type == SDL_MOUSEWHEEL;
|
||||
|
||||
const bool keyboardEvent =
|
||||
event.type == SDL_KEYDOWN ||
|
||||
event.type == SDL_KEYUP ||
|
||||
event.type == SDL_TEXTINPUT;
|
||||
const bool mouseEvent =
|
||||
event.type == SDL_MOUSEBUTTONDOWN ||
|
||||
event.type == SDL_MOUSEBUTTONUP ||
|
||||
event.type == SDL_MOUSEMOTION ||
|
||||
event.type == SDL_MOUSEWHEEL;
|
||||
|
||||
const bool capturedByImgui =
|
||||
(mouseEvent && imguiPass.wantsMouse()) ||
|
||||
(keyboardEvent && imguiPass.wantsKeyboard());
|
||||
const bool keyboardEvent =
|
||||
event.type == SDL_KEYDOWN ||
|
||||
event.type == SDL_KEYUP ||
|
||||
event.type == SDL_TEXTINPUT;
|
||||
|
||||
if (!capturedByImgui)
|
||||
{
|
||||
if (InputManager::GetInstance().ProcessEvent(event))
|
||||
const bool capturedByImgui =
|
||||
(mouseEvent && imguiPass.wantsMouse()) ||
|
||||
(keyboardEvent && imguiPass.wantsKeyboard());
|
||||
|
||||
if (!capturedByImgui)
|
||||
{
|
||||
isRunning = false;
|
||||
ZoneScopedN("Input ProcessEvent");
|
||||
|
||||
if (InputManager::GetInstance().ProcessEvent(event))
|
||||
{
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isRunning) break;
|
||||
imguiPass.beginFrame();
|
||||
|
||||
customUpdate(dt);
|
||||
|
||||
ImGui::Begin("Debug");
|
||||
ImGui::Text("FPS: %.2f", avgFPS);
|
||||
ImGui::End();
|
||||
|
||||
imguiPass.endFrame();
|
||||
int steps = 0;
|
||||
while (accumulator >= fixedDt && steps < maxSteps)
|
||||
{
|
||||
// physics.Update(fixedDt);
|
||||
customFixedUpdate(fixedDt);
|
||||
// physics.Step(fixedDt);
|
||||
// physics.SyncTransforms();
|
||||
ZoneScopedN("ImGui BeginFrame");
|
||||
imguiPass.beginFrame();
|
||||
}
|
||||
|
||||
accumulator -= fixedDt;
|
||||
steps++;
|
||||
{
|
||||
ZoneScopedN("customUpdate");
|
||||
customUpdate(dt);
|
||||
}
|
||||
|
||||
{
|
||||
ZoneScopedN("Debug ImGui");
|
||||
ImGui::Begin("Debug");
|
||||
ImGui::Text("FPS: %.2f", avgFPS);
|
||||
ImGui::End();
|
||||
|
||||
drawPhysicsPanel(dt, fixedDt, accumulator);
|
||||
|
||||
TracyPlot("FPS", avgFPS);
|
||||
TracyPlot("Frame Time ms", dt * 1000.0f);
|
||||
TracyPlot("Accumulator ms", accumulator * 1000.0f);
|
||||
}
|
||||
|
||||
{
|
||||
ZoneScopedN("ImGui EndFrame");
|
||||
imguiPass.endFrame();
|
||||
}
|
||||
|
||||
{
|
||||
ZoneScopedN("FixedUpdate");
|
||||
|
||||
int steps = 0;
|
||||
|
||||
if (m_PhysicsPaused)
|
||||
{
|
||||
// Important: prevent physics from building up a huge backlog while paused.
|
||||
accumulator = 0.0f;
|
||||
|
||||
if (m_PhysicsStepOnce)
|
||||
{
|
||||
ZoneScopedN("Single Physics Step");
|
||||
|
||||
customFixedUpdate(fixedDt * m_PhysicsTimeScale);
|
||||
|
||||
steps = 1;
|
||||
m_PhysicsStepOnce = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (accumulator >= fixedDt && steps < maxSteps)
|
||||
{
|
||||
ZoneScopedN("Fixed Step");
|
||||
|
||||
customFixedUpdate(fixedDt * m_PhysicsTimeScale);
|
||||
|
||||
accumulator -= fixedDt;
|
||||
steps++;
|
||||
}
|
||||
|
||||
if (steps == maxSteps)
|
||||
{
|
||||
accumulator = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
m_PhysicsStepsLastFrame = steps;
|
||||
|
||||
TracyPlot("Fixed Steps", static_cast<int64_t>(steps));
|
||||
}
|
||||
if (steps == maxSteps) accumulator = 0.0f;
|
||||
|
||||
const float alpha = accumulator / fixedDt;
|
||||
(void)alpha;
|
||||
|
||||
if (gfxDevice.needsSwapchainRecreate() || resizePending)
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
ZoneScopedN("Swapchain Resize Check");
|
||||
|
||||
if (resizePending &&
|
||||
now - lastResizeTime < std::chrono::milliseconds(100))
|
||||
if (gfxDevice.needsSwapchainRecreate() || resizePending)
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
if (resizePending &&
|
||||
now - lastResizeTime < std::chrono::milliseconds(100))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
SDL_Vulkan_GetDrawableSize(window, &w, &h);
|
||||
|
||||
if (w == 0 || h == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spdlog::info("Recreating swapchain to size: {}x{}", w, h);
|
||||
|
||||
{
|
||||
ZoneScopedN("Recreate Swapchain");
|
||||
gfxDevice.recreateSwapchain(w, h);
|
||||
onWindowResize(w, h);
|
||||
}
|
||||
|
||||
resizePending = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
SDL_Vulkan_GetDrawableSize(window, &w, &h);
|
||||
|
||||
if (w == 0 || h == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spdlog::info("Recreating swapchain to size: {}x{}", w, h);
|
||||
|
||||
gfxDevice.recreateSwapchain(w, h);
|
||||
onWindowResize(w, h);
|
||||
|
||||
resizePending = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
customDraw();
|
||||
|
||||
{
|
||||
ZoneScopedN("customDraw");
|
||||
customDraw();
|
||||
}
|
||||
|
||||
if (frameLimit)
|
||||
{
|
||||
ZoneScopedN("Frame Limit Sleep");
|
||||
|
||||
auto sleepTime = Time::GetInstance().SleepDuration();
|
||||
if (sleepTime.count() > 0)
|
||||
{
|
||||
@@ -199,3 +291,49 @@ void App::cleanup()
|
||||
spdlog::info("Cleaning up");
|
||||
customCleanup();
|
||||
}
|
||||
|
||||
void App::drawPhysicsPanel(float dt, float fixedDt, float accumulator)
|
||||
{
|
||||
ImGui::Begin("Physics");
|
||||
|
||||
ImGui::Text("Frame dt: %.3f ms", dt * 1000.0f);
|
||||
ImGui::Text("Fixed dt: %.3f ms", fixedDt * 1000.0f);
|
||||
ImGui::Text("Accumulator: %.3f ms", accumulator * 1000.0f);
|
||||
ImGui::Text("Steps last frame: %d", m_PhysicsStepsLastFrame);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button(m_PhysicsPaused ? "Resume Physics" : "Pause Physics"))
|
||||
{
|
||||
m_PhysicsPaused = !m_PhysicsPaused;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (!m_PhysicsPaused)
|
||||
{
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button("Step Physics");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGui::Button("Step Physics"))
|
||||
{
|
||||
m_PhysicsStepOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Paused", &m_PhysicsPaused);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::SliderFloat("Physics Time Scale", &m_PhysicsTimeScale, 0.0f, 2.0f, "%.2fx");
|
||||
|
||||
if (ImGui::Button("Reset Time Scale"))
|
||||
{
|
||||
m_PhysicsTimeScale = 1.0f;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
Reference in New Issue
Block a user