FPS/batch counter works

This commit is contained in:
2026-04-14 13:55:39 +03:00
parent e6494936d6
commit 611dcd0d46
4 changed files with 117 additions and 7 deletions

View File

@@ -38,22 +38,31 @@
//=============================================================================
ImGuiRenderListener::ImGuiRenderListener(Ogre::ImGuiOverlay *imguiOverlay,
EditorUISystem *uiSystem)
EditorUISystem *uiSystem,
Ogre::RenderWindow* renderWindow)
: m_imguiOverlay(imguiOverlay)
, m_uiSystem(uiSystem)
, m_renderWindow(renderWindow)
{
m_lastTime = m_timer.getMilliseconds();
}
void ImGuiRenderListener::preViewportUpdate(
const Ogre::RenderTargetViewportEvent &evt)
{
(void)evt;
// Calculate delta time
unsigned long currentTime = m_timer.getMilliseconds();
m_deltaTime = (currentTime - m_lastTime) / 1000.0f;
m_lastTime = currentTime;
// Start ImGui frame before viewport renders
Ogre::ImGuiOverlay::NewFrame();
// Render editor UI
// Render editor UI with delta time
if (m_uiSystem) {
m_uiSystem->update();
m_uiSystem->update(m_deltaTime);
}
}
@@ -61,6 +70,13 @@ void ImGuiRenderListener::postViewportUpdate(
const Ogre::RenderTargetViewportEvent &evt)
{
(void)evt;
// Capture stats after rendering (they're updated at end of frame)
if (m_renderWindow && m_uiSystem) {
Ogre::RenderTarget::FrameStats stats = m_renderWindow->getStatistics();
m_uiSystem->setLastBatchCount(static_cast<int>(stats.batchCount));
}
// End ImGui frame after viewport renders
ImGui::EndFrame();
}
@@ -207,7 +223,7 @@ void EditorApp::setup()
// Create and register ImGui render listener
m_imguiListener = std::make_unique<ImGuiRenderListener>(
m_imguiOverlay, m_uiSystem.get());
m_imguiOverlay, m_uiSystem.get(), getRenderWindow());
getRenderWindow()->addListener(m_imguiListener.get());
// Register input listeners

View File

@@ -31,7 +31,8 @@ class RoomLayoutSystem;
class ImGuiRenderListener : public Ogre::RenderTargetListener {
public:
ImGuiRenderListener(Ogre::ImGuiOverlay *imguiOverlay,
EditorUISystem *uiSystem);
EditorUISystem *uiSystem,
Ogre::RenderWindow* renderWindow);
void preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override;
void postViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override;
@@ -39,6 +40,15 @@ public:
private:
Ogre::ImGuiOverlay *m_imguiOverlay;
EditorUISystem *m_uiSystem;
Ogre::RenderWindow* m_renderWindow;
// Timer for delta time calculation
Ogre::Timer m_timer;
unsigned long m_lastTime = 0;
float m_deltaTime = 0.0f;
// Frame stats (updated in postViewportUpdate)
int m_lastBatchCount = 0;
};
/**

View File

@@ -176,7 +176,7 @@ void EditorUISystem::registerModularComponents()
ComponentRegistration::registerAll(m_componentRegistry, m_sceneMgr, m_physicsSystem, m_renderWindow);
}
void EditorUISystem::update()
void EditorUISystem::update(float deltaTime)
{
// Render UI windows
// Note: NewFrame() is called by ImGuiRenderListener::preViewportUpdate
@@ -192,6 +192,9 @@ void EditorUISystem::update()
if (m_showFileDialog) {
renderFileDialog();
}
// Render FPS overlay
renderFPSOverlay(deltaTime);
}
void EditorUISystem::setSelectedEntity(flecs::entity entity)
@@ -1131,3 +1134,65 @@ void EditorUISystem::renderFileDialog()
ImGui::End();
}
void EditorUISystem::renderFPSOverlay(float deltaTime)
{
// Toggle FPS overlay with F12 key
if (ImGui::IsKeyPressed(ImGuiKey_F12)) {
m_showFPSOverlay = !m_showFPSOverlay;
}
if (!m_showFPSOverlay) {
return;
}
// Update FPS calculation
m_fpsTimeAccumulator += deltaTime;
m_fpsFrameCount++;
// Note: Batch count is set by ImGuiRenderListener::postViewportUpdate
// after each frame render (stats are updated at end of frame)
// Update FPS every 0.5 seconds for smoother display
if (m_fpsTimeAccumulator >= 0.5f) {
m_currentFPS = m_fpsFrameCount / m_fpsTimeAccumulator;
m_fpsTimeAccumulator = 0.0f;
m_fpsFrameCount = 0;
}
// Set up transparent window style
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration |
ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoNav;
// Position in top-right corner with padding
ImVec2 windowPos = ImVec2(ImGui::GetIO().DisplaySize.x - 10.0f, 10.0f);
ImVec2 windowPivot = ImVec2(1.0f, 0.0f); // Top-right pivot
ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, windowPivot);
ImGui::SetNextWindowBgAlpha(0.35f); // Semi-transparent background
if (ImGui::Begin("FPS Overlay", nullptr, windowFlags)) {
// FPS text color based on performance
ImVec4 fpsColor;
if (m_currentFPS >= 60.0f) {
fpsColor = ImVec4(0.0f, 1.0f, 0.0f, 1.0f); // Green for 60+ FPS
} else if (m_currentFPS >= 30.0f) {
fpsColor = ImVec4(1.0f, 1.0f, 0.0f, 1.0f); // Yellow for 30-60 FPS
} else {
fpsColor = ImVec4(1.0f, 0.0f, 0.0f, 1.0f); // Red for <30 FPS
}
ImGui::TextColored(fpsColor, "%.1f FPS", m_currentFPS);
ImGui::Text("Batches: %d", m_lastBatchCount);
ImGui::Separator();
ImVec4 hintColor = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
ImGui::TextColored(hintColor, "F12 to toggle");
}
ImGui::End();
}

View File

@@ -35,7 +35,12 @@ public:
* Update and render all UI windows
* Call this once per frame
*/
void update();
void update(float deltaTime);
/**
* Render FPS and batch count overlay
*/
void renderFPSOverlay(float deltaTime);
/**
* Set the currently selected entity
@@ -83,6 +88,11 @@ public:
* Set physics system for debug toggle
*/
void setPhysicsSystem(EditorPhysicsSystem* physics) { m_physicsSystem = physics; }
/**
* Set last frame batch count (called from render listener)
*/
void setLastBatchCount(int count) { m_lastBatchCount = count; }
@@ -144,6 +154,15 @@ private:
// Settings
bool m_parentSceneNodes = true; // Whether child entities inherit parent's SceneNode
// FPS overlay settings
bool m_showFPSOverlay = true; // Show FPS counter by default
// FPS tracking
float m_fpsTimeAccumulator = 0.0f;
int m_fpsFrameCount = 0;
float m_currentFPS = 0.0f;
int m_lastBatchCount = 0;
// Physics system reference (for debug toggle)
EditorPhysicsSystem* m_physicsSystem = nullptr;