feat: refresh on demand in menu (adaptive framerate)
This commit is contained in:
parent
ba0977a6f0
commit
7fc3703ad2
@ -255,8 +255,8 @@ void Engine::updateFrontend() {
|
||||
gui->postAct();
|
||||
}
|
||||
|
||||
void Engine::nextFrame() {
|
||||
windowControl->nextFrame();
|
||||
void Engine::nextFrame(bool waitForRefresh) {
|
||||
windowControl->nextFrame(waitForRefresh);
|
||||
}
|
||||
|
||||
void Engine::startPauseLoop() {
|
||||
@ -275,7 +275,7 @@ void Engine::startPauseLoop() {
|
||||
if (isHeadless()) {
|
||||
platform::sleep(1.0 / params.tps * 1000);
|
||||
} else {
|
||||
nextFrame();
|
||||
nextFrame(false);
|
||||
}
|
||||
}
|
||||
if (initialCursorLocked) {
|
||||
|
||||
@ -99,7 +99,7 @@ public:
|
||||
void applicationTick();
|
||||
void updateFrontend();
|
||||
void renderFrame();
|
||||
void nextFrame();
|
||||
void nextFrame(bool waitForRefresh);
|
||||
void startPauseLoop();
|
||||
|
||||
/// @brief Set screen (scene).
|
||||
|
||||
@ -45,7 +45,9 @@ void Mainloop::run() {
|
||||
engine.renderFrame();
|
||||
}
|
||||
engine.postUpdate();
|
||||
engine.nextFrame();
|
||||
engine.nextFrame(
|
||||
dynamic_cast<const MenuScreen*>(engine.getScreen().get()) != nullptr
|
||||
);
|
||||
}
|
||||
logger.info() << "main loop stopped";
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "window/input.hpp"
|
||||
#include "debug/Logger.hpp"
|
||||
#include "graphics/core/ImageData.hpp"
|
||||
#include "util/platform.hpp"
|
||||
|
||||
static debug::Logger logger("window-control");
|
||||
|
||||
@ -78,15 +79,19 @@ void WindowControl::toggleFullscreen() {
|
||||
}
|
||||
}
|
||||
|
||||
void WindowControl::nextFrame() {
|
||||
void WindowControl::nextFrame(bool waitForRefresh) {
|
||||
const auto& settings = engine.getSettings();
|
||||
auto& window = engine.getWindow();
|
||||
auto& input = engine.getInput();
|
||||
window.setFramerate(
|
||||
window.isIconified() && settings.display.limitFpsIconified.get()
|
||||
? 20
|
||||
: settings.display.framerate.get()
|
||||
);
|
||||
if (waitForRefresh) {
|
||||
window.setFramerate(Window::FPS_UNLIMITED);
|
||||
} else {
|
||||
window.setFramerate(
|
||||
window.isIconified() && settings.display.limitFpsIconified.get()
|
||||
? 20
|
||||
: settings.display.framerate.get()
|
||||
);
|
||||
}
|
||||
window.swapBuffers();
|
||||
input.pollEvents();
|
||||
input.pollEvents(waitForRefresh);
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ public:
|
||||
|
||||
Result initialize();
|
||||
|
||||
void nextFrame();
|
||||
void nextFrame(bool waitForRefresh);
|
||||
|
||||
void saveScreenshot();
|
||||
|
||||
|
||||
@ -18,6 +18,8 @@ enum class WindowMode {
|
||||
|
||||
class Window {
|
||||
public:
|
||||
static inline constexpr int FPS_UNLIMITED = 0;
|
||||
|
||||
Window(glm::ivec2 size) : size(std::move(size)) {}
|
||||
|
||||
virtual ~Window() = default;
|
||||
@ -40,6 +42,9 @@ public:
|
||||
virtual void popScissor() = 0;
|
||||
virtual void resetScissor() = 0;
|
||||
|
||||
virtual void setShouldRefresh() = 0;
|
||||
virtual bool checkShouldRefresh() = 0;
|
||||
|
||||
virtual double time() = 0;
|
||||
|
||||
virtual void setFramerate(int framerate) = 0;
|
||||
|
||||
@ -180,14 +180,18 @@ public:
|
||||
: window(window) {
|
||||
}
|
||||
|
||||
void pollEvents() override {
|
||||
void pollEvents(bool waitForRefresh) override {
|
||||
delta.x = 0.0f;
|
||||
delta.y = 0.0f;
|
||||
scroll = 0;
|
||||
currentFrame++;
|
||||
codepoints.clear();
|
||||
pressedKeys.clear();
|
||||
glfwPollEvents();
|
||||
if (waitForRefresh) {
|
||||
glfwWaitEvents();
|
||||
} else {
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
for (auto& [_, binding] : bindings.getAll()) {
|
||||
if (!binding.enabled) {
|
||||
@ -377,6 +381,18 @@ public:
|
||||
prevSwap = time();
|
||||
}
|
||||
|
||||
void setShouldRefresh() override {
|
||||
shouldRefresh = true;
|
||||
}
|
||||
|
||||
bool checkShouldRefresh() override {
|
||||
if (shouldRefresh) {
|
||||
shouldRefresh = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isMaximized() const override {
|
||||
return glfwGetWindowAttrib(window, GLFW_MAXIMIZED);
|
||||
}
|
||||
@ -557,12 +573,14 @@ private:
|
||||
double prevSwap = 0.0;
|
||||
int posX = 0;
|
||||
int posY = 0;
|
||||
bool shouldRefresh = true;
|
||||
};
|
||||
static_assert(!std::is_abstract<GLFWWindow>());
|
||||
|
||||
static void mouse_button_callback(GLFWwindow* window, int button, int action, int) {
|
||||
auto handler = static_cast<GLFWWindow*>(glfwGetWindowUserPointer(window));
|
||||
handler->input.onMouseCallback(button, action == GLFW_PRESS);
|
||||
handler->setShouldRefresh();
|
||||
}
|
||||
|
||||
static void character_callback(GLFWwindow* window, unsigned int codepoint) {
|
||||
@ -574,6 +592,8 @@ static void key_callback(
|
||||
GLFWwindow* window, int key, int /*scancode*/, int action, int /*mode*/
|
||||
) {
|
||||
auto handler = static_cast<GLFWWindow*>(glfwGetWindowUserPointer(window));
|
||||
handler->setShouldRefresh();
|
||||
|
||||
auto& input = handler->input;
|
||||
if (key == GLFW_KEY_UNKNOWN) {
|
||||
return;
|
||||
@ -599,11 +619,13 @@ static void window_size_callback(GLFWwindow* window, int width, int height) {
|
||||
static void scroll_callback(GLFWwindow* window, double, double yoffset) {
|
||||
auto handler = static_cast<GLFWWindow*>(glfwGetWindowUserPointer(window));
|
||||
handler->input.scroll += yoffset;
|
||||
handler->setShouldRefresh();
|
||||
}
|
||||
|
||||
static void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) {
|
||||
auto handler = static_cast<GLFWWindow*>(glfwGetWindowUserPointer(window));
|
||||
handler->input.setCursorPosition(xpos, ypos);
|
||||
handler->setShouldRefresh();
|
||||
}
|
||||
|
||||
static void iconify_callback(GLFWwindow* window, int iconified) {
|
||||
@ -629,6 +651,11 @@ static void create_standard_cursors() {
|
||||
}
|
||||
}
|
||||
|
||||
static void refresh_callback(GLFWwindow* window) {
|
||||
auto handler = static_cast<GLFWWindow*>(glfwGetWindowUserPointer(window));
|
||||
handler->setShouldRefresh();
|
||||
}
|
||||
|
||||
static void setup_callbacks(GLFWwindow* window) {
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||
@ -637,6 +664,7 @@ static void setup_callbacks(GLFWwindow* window) {
|
||||
glfwSetCharCallback(window, character_callback);
|
||||
glfwSetScrollCallback(window, scroll_callback);
|
||||
glfwSetWindowIconifyCallback(window, iconify_callback);
|
||||
glfwSetWindowRefreshCallback(window, refresh_callback);
|
||||
}
|
||||
|
||||
std::tuple<
|
||||
|
||||
@ -261,7 +261,7 @@ class Input {
|
||||
public:
|
||||
virtual ~Input() = default;
|
||||
|
||||
virtual void pollEvents() = 0;
|
||||
virtual void pollEvents(bool waitForRefresh) = 0;
|
||||
|
||||
virtual const char* getClipboardText() const = 0;
|
||||
virtual void setClipboardText(const char* str) = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user