Skip to main content

FpsWidget.ixx File

ImGui widget for displaying and configuring FPS metrics and frame pacing. More...

Included Headers

#include <vector> #include <string> #include "imgui.h" #include <helios.engine.tooling.FrameStats> #include <helios.engine.tooling.FramePacer> #include <helios.engine.tooling.FpsMetrics> #include <helios.imgui.ImGuiWidget>

Namespaces Index

namespacehelios
namespaceimgui
namespacewidgets

Classes Index

classFpsWidget

Debug widget for real-time FPS metrics and frame pacing configuration. More...

Description

ImGui widget for displaying and configuring FPS metrics and frame pacing.

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7#include <vector>
8#include <string>
9#include "imgui.h"
10
11export module helios.imgui.widgets.FpsWidget;
12
13import helios.imgui.ImGuiWidget;
14import helios.engine.tooling.FpsMetrics;
15import helios.engine.tooling.FramePacer;
16import helios.engine.tooling.FrameStats;
17
18export namespace helios::imgui::widgets {
19
30 class FpsWidget : public ImGuiWidget {
31
32 private:
43 helios::engine::tooling::FpsMetrics* fpsMetrics_ = nullptr;
44
56 helios::engine::tooling::FramePacer* framePacer_ = nullptr;
57
69 float targetFpsInput_ = 0.0f;
70
80 bool showInSeconds_ = false;
81
92 int historySizeInput_ = 60;
93
94 public:
95
102 explicit FpsWidget(
103 helios::engine::tooling::FpsMetrics* fpsMetrics,
104 helios::engine::tooling::FramePacer* framePacer = nullptr
105 ) : fpsMetrics_(fpsMetrics), framePacer_(framePacer)
106 {
107 if (fpsMetrics_) {
108 historySizeInput_ = static_cast<int>(fpsMetrics_->getHistorySize());
109 }
110 if (framePacer_) {
111 targetFpsInput_ = framePacer_->getTargetFps();
112 }
113 }
114
118 void draw() override {
119 if (!fpsMetrics_) {
120 return;
121 }
122
123 // Window settings
124 ImGui::SetNextWindowPos(ImVec2(10, 10), ImGuiCond_FirstUseEver);
125 ImGui::SetNextWindowSize(ImVec2(320, 250), ImGuiCond_FirstUseEver);
126
127 if (ImGui::Begin("FPS Metrics", nullptr, ImGuiWindowFlags_NoCollapse)) {
128
129 // 1 Main Metrics
130 ImGui::SeparatorText("Timing Info");
131
132 float displayFrameTime = showInSeconds_ ? fpsMetrics_->getFrameTimeSeconds() : fpsMetrics_->getFrameTimeMs();
133 float displayWorkTime = showInSeconds_ ? fpsMetrics_->getWorkTimeSeconds() : fpsMetrics_->getWorkTimeMs();
134 float displayIdleTime = showInSeconds_ ? fpsMetrics_->getIdleTimeSeconds() : fpsMetrics_->getIdleTimeMs();
135 const char* unit = showInSeconds_ ? "s" : "ms";
136 const char* format = showInSeconds_ ? "%.5f %s" : "%.2f %s";
137
138 ImGui::Text("FPS: %.1f", fpsMetrics_->getFps());
139 ImGui::Text("Avg Frame: "); ImGui::SameLine(); ImGui::Text(format, displayFrameTime, unit);
140 ImGui::Text("CPU Work: "); ImGui::SameLine(); ImGui::Text(format, displayWorkTime, unit);
141 ImGui::Text("Idle/Wait: "); ImGui::SameLine(); ImGui::Text(format, displayIdleTime, unit);
142 ImGui::Text("Frame #: %llu", fpsMetrics_->getFrameCount());
143
144 // 2 Settings
145 ImGui::SeparatorText("Settings");
146
147 // Checkbox for unit toggle
148 if (ImGui::Checkbox("Show in Seconds", &showInSeconds_)) {
149 // UI state changes; display updates next frame
150 }
151
152 // Input for history size
153 if (ImGui::InputInt("History Size", &historySizeInput_, 1, 10)) {
154 if (historySizeInput_ < 1) historySizeInput_ = 1;
155 if (historySizeInput_ > 1000) historySizeInput_ = 1000;
156
157 fpsMetrics_->setHistorySize(static_cast<size_t>(historySizeInput_));
158 }
159
160 // Frame pacing configuration (if pacer is available)
161 if (framePacer_) {
162 ImGui::SeparatorText("Frame Pacing Config");
163
164 targetFpsInput_ = framePacer_->getTargetFps();
165
166 // Quick preset buttons
167 if (ImGui::Button("Uncapped (0)")) {
168 framePacer_->setTargetFps(0.0f);
169 targetFpsInput_ = 0.0f;
170 }
171 ImGui::SameLine();
172 if (ImGui::Button("30 FPS")) {
173 framePacer_->setTargetFps(30.0f);
174 targetFpsInput_ = 30.0f;
175 }
176 ImGui::SameLine();
177 if (ImGui::Button("60 FPS")) {
178 framePacer_->setTargetFps(60.0f);
179 targetFpsInput_ = 60.0f;
180 }
181 ImGui::SameLine();
182 if (ImGui::Button("120 FPS")) {
183 framePacer_->setTargetFps(120.0f);
184 targetFpsInput_ = 120.0f;
185 }
186 ImGui::SameLine();
187 if (ImGui::Button("144 FPS")) {
188 framePacer_->setTargetFps(144.0f);
189 targetFpsInput_ = 144.0f;
190 }
191
192 // Slider for precise control
193 float sliderFps = targetFpsInput_;
194 if (ImGui::DragFloat("Target FPS", &sliderFps, 1.0f, 0.0f, 300.0f, "%.0f")) {
195 framePacer_->setTargetFps(sliderFps);
196 targetFpsInput_ = sliderFps;
197 }
198 if (ImGui::IsItemHovered()) {
199 ImGui::SetTooltip("Set to 0 for unlimited (V-Sync might still limit)");
200 }
201 }
202
203 // Frame time history graph
204 const auto& history = fpsMetrics_->getHistory();
205 if (!history.empty()) {
206 ImGui::SeparatorText("History");
207
208 std::vector<float> frameTimes;
209 frameTimes.reserve(history.size());
210
211 for (const auto& s : history) {
212 frameTimes.push_back(s.totalFrameTime * 1000.0f);
213 }
214
215 ImGui::PlotLines("Frame Time (ms)",
216 frameTimes.data(),
217 static_cast<int>(frameTimes.size()),
218 0,
219 nullptr,
220 0.0f,
221 FLT_MAX,
222 ImVec2(0, 80.0f));
223 }
224 }
225 ImGui::End();
226 }
227 };
228}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.