diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index 905a1fd3..d8734890 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -55,6 +55,7 @@ settings.Camera Inertia=Инерция Камеры settings.Fog Curve=Кривая Тумана settings.FOV=Поле Зрения settings.Fullscreen=Полный экран +settings.Framerate=Частота кадров settings.Gamma=Гамма settings.Language=Язык settings.Load Distance=Дистанция Загрузки diff --git a/src/engine.cpp b/src/engine.cpp index 2c68370a..0c447096 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -171,7 +171,8 @@ void Engine::mainloop() { if (!Window::isIconified()) { renderFrame(batch); } - Window::swapInterval(Window::isIconified() ? 1 : settings.display.vsync.get()); + Window::setFramerate(Window::isIconified() ? 20 : + settings.display.framerate.get()); processPostRunnables(); diff --git a/src/files/settings_io.cpp b/src/files/settings_io.cpp index 28c62acf..444f079f 100644 --- a/src/files/settings_io.cpp +++ b/src/files/settings_io.cpp @@ -48,6 +48,7 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) { builder.add("width", &settings.display.width); builder.add("height", &settings.display.height); builder.add("samples", &settings.display.samples); + builder.add("framerate", &settings.display.framerate); builder.add("vsync", &settings.display.vsync); builder.add("fullscreen", &settings.display.fullscreen); diff --git a/src/settings.hpp b/src/settings.hpp index 8a8ad0cb..4f024840 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -28,6 +28,8 @@ struct DisplaySettings { IntegerSetting height {720}; /// @brief Anti-aliasing samples IntegerSetting samples {0}; + /// @brief Framerate limit + IntegerSetting framerate {-1, -1, 120}; /// @brief VSync on FlagSetting vsync {true}; }; diff --git a/src/window/Window.cpp b/src/window/Window.cpp index 9e0b1bad..8414c75d 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -9,6 +9,8 @@ #include #include +#include +#include static debug::Logger logger("window"); @@ -20,6 +22,8 @@ uint Window::width = 0; uint Window::height = 0; int Window::posX = 0; int Window::posY = 0; +int Window::framerate = -1; +double Window::prevSwap = 0.0; bool Window::fullscreen = false; static util::ObjectsKeeper observers_keeper; @@ -58,8 +62,7 @@ bool Window::isIconified() { return glfwGetWindowAttrib(window, GLFW_ICONIFIED); } -bool Window::isFocused() -{ +bool Window::isFocused() { return glfwGetWindowAttrib(window, GLFW_FOCUSED); } @@ -182,7 +185,8 @@ int Window::initialize(DisplaySettings* settings){ } }, true)); - glfwSwapInterval(settings->vsync.get()); + glfwSwapInterval(1); + setFramerate(settings->framerate.get()); const GLubyte* vendor = glGetString(GL_VENDOR); const GLubyte* renderer = glGetString(GL_RENDERER); logger.info() << "GL Vendor: " << (char*)vendor; @@ -281,8 +285,11 @@ void Window::setShouldClose(bool flag){ glfwSetWindowShouldClose(window, flag); } -void Window::swapInterval(int interval){ - glfwSwapInterval(interval); +void Window::setFramerate(int framerate) { + if ((framerate != -1) != (Window::framerate != -1)) { + glfwSwapInterval(framerate == -1); + } + Window::framerate = framerate; } void Window::toggleFullscreen(){ @@ -315,9 +322,16 @@ bool Window::isFullscreen() { return fullscreen; } -void Window::swapBuffers(){ +void Window::swapBuffers() { + double currentTime = time(); + if (framerate > 0 && currentTime - prevSwap < (1.0 / framerate)) { + std::cout << static_cast((1.0/framerate - (currentTime-prevSwap))*1000) << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds( + static_cast((1.0/framerate - (currentTime-prevSwap))*1000))); + } glfwSwapBuffers(window); Window::resetScissor(); + prevSwap = time(); } double Window::time() { diff --git a/src/window/Window.hpp b/src/window/Window.hpp index b301f6ad..ff52982c 100644 --- a/src/window/Window.hpp +++ b/src/window/Window.hpp @@ -19,6 +19,8 @@ class Window { static std::stack scissorStack; static glm::vec4 scissorArea; static bool fullscreen; + static int framerate; + static double prevSwap; static bool tryToMaximize(GLFWwindow* window, GLFWmonitor* monitor); public: @@ -34,7 +36,7 @@ public: static bool isShouldClose(); static void setShouldClose(bool flag); static void swapBuffers(); - static void swapInterval(int interval); + static void setFramerate(int interval); static void toggleFullscreen(); static bool isFullscreen(); static bool isMaximized();