#pragma once #include #include #include namespace JUI { struct DataPoint { Vector2 pos; Color4 color; }; class FpsGraph : public JUI::ImageRect { public: void RenderDataPoints() { J2D::Begin(canvas, nullptr, true); DataPoint prev = data[0]; for (auto& data_pt : data) { //J2D::DrawGradientLine(prev.color, data_pt.color, prev.pos, data_pt.pos, 1); J2D::DrawLine(data_pt.color, data_pt.pos, {data_pt.pos.x, graph_height }, 1); prev = data_pt; } float target_line_height = (1.f / 60.f) * y_axis_scale; J2D::DrawString(Colors::Black, "60 FPS / 16.7ms (Target)", 0, graph_height - target_line_height, 10, 1.f); J2D::DrawLine(Colors::White, {0, graph_height - target_line_height}, {GetAbsoluteSize().x, graph_height - target_line_height}, 1); J2D::End(); } FpsGraph() : JUI::ImageRect() { BGColor(Colors::Transparent); BorderColor(Colors::Transparent); for (int i = 0; i < sample_history; i++) { Plot({i / 1.f, 0.f}, Colors::Black); } canvas = new JGL::RenderTarget(Vector2i(graph_width, graph_height)); RenderDataPoints(); Content(canvas); }; explicit FpsGraph(Widget* parent) : FpsGraph() { Parent(parent); } void Plot(const Vector2& pt, const Color4& col) { data.push_back(DataPoint{ pt, col }); } void Update(float delta) override { ImageRect::Update(delta); data.erase(data.begin()); for (auto& data_pt : data) { data_pt.pos.x -= 1; } Color4 color = Colors::Green; if (delta > 1.f/120.f) color = Colors::Blue; if (delta > 1.f/60.f) color = Colors::Yellow; if (delta > 1.f/30.f) color = Colors::Red; if (delta > 1.f/15.f) color = Colors::Purples::Magenta; if (delta > 1.f/5.f) color = Colors::Black; Plot({(data.size()-1.f), graph_height - (delta*y_axis_scale)}, color); RenderDataPoints(); Content(canvas); } void SetupAsPseudoDockedElementAtBottomOfScreen() { this->Size({100_percent, 50_px}); this->AnchorPoint({1, 1}); this->Position({100_percent, 100_percent}); } std::vector data; JGL::RenderTarget* canvas; float graph_height = 50; float graph_width = 500; float sample_history = 500; float y_axis_scale = 600; protected: private: }; class FpsGraphWindow : public JUI::Window { public: FpsGraphWindow() : Window() { Name("FPSGraphWindow"); Title("FPS Graph"); Size({500_px, 70_px}); this->SetResizable(false); data_graph = new FpsGraph(this->Content()); data_graph->Size({500_px, 50_px}); } explicit FpsGraphWindow(Widget* parent) : FpsGraphWindow() { this->Parent(parent); } protected: FpsGraph* data_graph; private: }; }