diff --git a/SDLU/graphics/RenderWindow.cpp b/SDLU/graphics/RenderWindow.cpp index 832c233..db386f0 100644 --- a/SDLU/graphics/RenderWindow.cpp +++ b/SDLU/graphics/RenderWindow.cpp @@ -4,17 +4,17 @@ namespace sdlu { - RenderWindow::RenderWindow() + RenderWindow::RenderWindow() : + m_pWindow(nullptr), m_pRenderer(nullptr), + m_oFramerate(0), m_oTimeSinceLastDisplay(std::chrono::steady_clock::now()) { - m_pWindow = nullptr; - m_pRenderer = nullptr; + } RenderWindow::RenderWindow(Vector2u dimension, const std::string& title, - Uint32 windowFlags, Uint32 rendererFlags) + Uint32 windowFlags, Uint32 rendererFlags) : + RenderWindow() { - m_pWindow = nullptr; - m_pRenderer = nullptr; Create(dimension, title, windowFlags, rendererFlags); } @@ -170,6 +170,19 @@ namespace sdlu RETURN_IF_NULLPTR(m_pWindow); SDL_RenderPresent(m_pRenderer); + + if (m_oFramerate != 0) + { + Uint64 diff = std::chrono::duration_cast( + std::chrono::steady_clock::now() - m_oTimeSinceLastDisplay).count(); + + if (diff < 1000 / m_oFramerate) + { + SDL_Delay(1000 / m_oFramerate - diff); + } + } + + m_oTimeSinceLastDisplay = std::chrono::steady_clock::now(); } void RenderWindow::SetVisible(bool visible) @@ -227,4 +240,9 @@ namespace sdlu { SDL_SetWindowIcon(m_pWindow, icon); } + + void RenderWindow::SetMaxFramerate(Uint32 max) + { + m_oFramerate = max; + } } \ No newline at end of file diff --git a/SDLU/graphics/RenderWindow.hpp b/SDLU/graphics/RenderWindow.hpp index 274a16c..0534efa 100644 --- a/SDLU/graphics/RenderWindow.hpp +++ b/SDLU/graphics/RenderWindow.hpp @@ -6,6 +6,7 @@ */ #pragma once #include +#include #include #include @@ -223,6 +224,17 @@ namespace sdlu */ void SetIcon(SDL_Surface* icon); + /** + * @brief Sets a maximum framerate on the display function + * + * If the maximum framerate is not 0, SDL_Delay() will be called + * after each Display() to ensure that the time between displays + * is not shorter than the framerate limit. + * + * @param[in] max The new maximum framerate + */ + void SetMaxFramerate(Uint32 max); + protected: SDL_Window* m_pWindow; ///< A pointer to the window object SDL_Renderer* m_pRenderer; ///< A pointer to the renderer object @@ -246,5 +258,10 @@ namespace sdlu * @brief This function is called after Close() finishes. */ virtual void OnClose(); + + private: + Uint32 m_oFramerate; + + std::chrono::steady_clock::time_point m_oTimeSinceLastDisplay; }; } \ No newline at end of file diff --git a/SDLU_Example/header.hpp b/SDLU_Example/header.hpp index 3afd380..8756575 100644 --- a/SDLU_Example/header.hpp +++ b/SDLU_Example/header.hpp @@ -1,3 +1,4 @@ +#include "..\SDLU\graphics\RenderWindow.hpp" #pragma once #include "SDLU.hpp" #include diff --git a/SDLU_Example/main.cpp b/SDLU_Example/main.cpp index 5e219c4..7783776 100644 --- a/SDLU_Example/main.cpp +++ b/SDLU_Example/main.cpp @@ -15,10 +15,14 @@ int main(int argc, char** argv) } } + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); + Uint64 diff = 1; + MyWindow window(800, 800, "Test"); SDL_SetWindowTitle(window.GetWindow(), "New Title"); window.SetIcon(64, 64, icon_data); + window.SetMaxFramerate(144); SDL_Event event; float t = 0.f; @@ -42,6 +46,11 @@ int main(int argc, char** argv) window.Display(); t += 0.01; + + diff = std::chrono::duration_cast + (std::chrono::steady_clock::now() - start).count(); + window.SetTitle(std::to_string(1000000 / diff) + " FPS"); + start = std::chrono::steady_clock::now(); } SDL_Quit();