Merge pull request #269 from MihailRis/framerate-control
Framerate control
This commit is contained in:
commit
d793b2f648
@ -1,3 +1,14 @@
|
|||||||
|
local tostring_overrides = {}
|
||||||
|
tostring_overrides["display.framerate"] = function(x)
|
||||||
|
if x == -1 then
|
||||||
|
return "V-Sync"
|
||||||
|
elseif x == 0 then
|
||||||
|
return "Unlimited"
|
||||||
|
else
|
||||||
|
return tostring(x)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function create_setting(id, name, step, postfix, tooltip, changeonrelease)
|
function create_setting(id, name, step, postfix, tooltip, changeonrelease)
|
||||||
local info = core.get_setting_info(id)
|
local info = core.get_setting_info(id)
|
||||||
postfix = postfix or ""
|
postfix = postfix or ""
|
||||||
@ -18,11 +29,18 @@ function create_setting(id, name, step, postfix, tooltip, changeonrelease)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function update_setting(x, id, name, postfix)
|
function update_setting(x, id, name, postfix)
|
||||||
|
local str
|
||||||
|
local func = tostring_overrides[id]
|
||||||
|
if func then
|
||||||
|
str = func(x)
|
||||||
|
else
|
||||||
|
str = core.str_setting(id)
|
||||||
|
end
|
||||||
-- updating label
|
-- updating label
|
||||||
document[id..".L"].text = string.format(
|
document[id..".L"].text = string.format(
|
||||||
"%s: %s%s",
|
"%s: %s%s",
|
||||||
gui.str(name, "settings"),
|
gui.str(name, "settings"),
|
||||||
core.str_setting(id),
|
str,
|
||||||
postfix
|
postfix
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -37,8 +55,8 @@ end
|
|||||||
|
|
||||||
function on_open()
|
function on_open()
|
||||||
create_setting("camera.fov", "FOV", 1, "°")
|
create_setting("camera.fov", "FOV", 1, "°")
|
||||||
|
create_setting("display.framerate", "Framerate", 1, "", "", true)
|
||||||
create_checkbox("display.fullscreen", "Fullscreen")
|
create_checkbox("display.fullscreen", "Fullscreen")
|
||||||
create_checkbox("display.vsync", "V-Sync")
|
|
||||||
create_checkbox("camera.shaking", "Camera Shaking")
|
create_checkbox("camera.shaking", "Camera Shaking")
|
||||||
create_checkbox("camera.inertia", "Camera Inertia")
|
create_checkbox("camera.inertia", "Camera Inertia")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -55,6 +55,7 @@ settings.Camera Inertia=Инерция Камеры
|
|||||||
settings.Fog Curve=Кривая Тумана
|
settings.Fog Curve=Кривая Тумана
|
||||||
settings.FOV=Поле Зрения
|
settings.FOV=Поле Зрения
|
||||||
settings.Fullscreen=Полный экран
|
settings.Fullscreen=Полный экран
|
||||||
|
settings.Framerate=Частота кадров
|
||||||
settings.Gamma=Гамма
|
settings.Gamma=Гамма
|
||||||
settings.Language=Язык
|
settings.Language=Язык
|
||||||
settings.Load Distance=Дистанция Загрузки
|
settings.Load Distance=Дистанция Загрузки
|
||||||
|
|||||||
BIN
res/textures/misc/icon.png
Normal file
BIN
res/textures/misc/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.1 KiB |
@ -64,6 +64,18 @@ inline void create_channel(Engine* engine, std::string name, NumberSetting& sett
|
|||||||
}, true));
|
}, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<ImageData> load_icon(const fs::path& resdir) {
|
||||||
|
try {
|
||||||
|
auto file = resdir / fs::u8path("textures/misc/icon.png");
|
||||||
|
if (fs::exists(file)) {
|
||||||
|
return imageio::read(file.u8string());
|
||||||
|
}
|
||||||
|
} catch (const std::exception& err) {
|
||||||
|
logger.error() << "could not load window icon: " << err.what();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, EnginePaths* paths)
|
Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, EnginePaths* paths)
|
||||||
: settings(settings), settingsHandler(settingsHandler), paths(paths),
|
: settings(settings), settingsHandler(settingsHandler), paths(paths),
|
||||||
interpreter(std::make_unique<cmd::CommandsInterpreter>())
|
interpreter(std::make_unique<cmd::CommandsInterpreter>())
|
||||||
@ -71,10 +83,16 @@ Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, Engin
|
|||||||
paths->prepare();
|
paths->prepare();
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
|
auto resdir = paths->getResources();
|
||||||
|
|
||||||
controller = std::make_unique<EngineController>(this);
|
controller = std::make_unique<EngineController>(this);
|
||||||
if (Window::initialize(&this->settings.display)){
|
if (Window::initialize(&this->settings.display)){
|
||||||
throw initialize_error("could not initialize window");
|
throw initialize_error("could not initialize window");
|
||||||
}
|
}
|
||||||
|
if (auto icon = load_icon(resdir)) {
|
||||||
|
icon->flipY();
|
||||||
|
Window::setIcon(icon.get());
|
||||||
|
}
|
||||||
loadControls();
|
loadControls();
|
||||||
audio::initialize(settings.audio.enabled.get());
|
audio::initialize(settings.audio.enabled.get());
|
||||||
create_channel(this, "master", settings.audio.volumeMaster);
|
create_channel(this, "master", settings.audio.volumeMaster);
|
||||||
@ -99,8 +117,6 @@ Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, Engin
|
|||||||
addWorldGenerators();
|
addWorldGenerators();
|
||||||
|
|
||||||
scripting::initialize(this);
|
scripting::initialize(this);
|
||||||
|
|
||||||
auto resdir = paths->getResources();
|
|
||||||
basePacks = files::read_list(resdir/fs::path("config/builtins.list"));
|
basePacks = files::read_list(resdir/fs::path("config/builtins.list"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +187,8 @@ void Engine::mainloop() {
|
|||||||
if (!Window::isIconified()) {
|
if (!Window::isIconified()) {
|
||||||
renderFrame(batch);
|
renderFrame(batch);
|
||||||
}
|
}
|
||||||
Window::swapInterval(Window::isIconified() ? 1 : settings.display.vsync.get());
|
Window::setFramerate(!Window::isIconified() ? 20 :
|
||||||
|
settings.display.framerate.get());
|
||||||
|
|
||||||
processPostRunnables();
|
processPostRunnables();
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) {
|
|||||||
builder.add("width", &settings.display.width);
|
builder.add("width", &settings.display.width);
|
||||||
builder.add("height", &settings.display.height);
|
builder.add("height", &settings.display.height);
|
||||||
builder.add("samples", &settings.display.samples);
|
builder.add("samples", &settings.display.samples);
|
||||||
builder.add("vsync", &settings.display.vsync);
|
builder.add("framerate", &settings.display.framerate);
|
||||||
builder.add("fullscreen", &settings.display.fullscreen);
|
builder.add("fullscreen", &settings.display.fullscreen);
|
||||||
|
|
||||||
builder.section("camera");
|
builder.section("camera");
|
||||||
|
|||||||
@ -28,8 +28,8 @@ struct DisplaySettings {
|
|||||||
IntegerSetting height {720};
|
IntegerSetting height {720};
|
||||||
/// @brief Anti-aliasing samples
|
/// @brief Anti-aliasing samples
|
||||||
IntegerSetting samples {0};
|
IntegerSetting samples {0};
|
||||||
/// @brief VSync on
|
/// @brief Framerate limit
|
||||||
FlagSetting vsync {true};
|
IntegerSetting framerate {-1, -1, 120};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChunksSettings {
|
struct ChunksSettings {
|
||||||
|
|||||||
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
static debug::Logger logger("window");
|
static debug::Logger logger("window");
|
||||||
|
|
||||||
@ -20,6 +22,8 @@ uint Window::width = 0;
|
|||||||
uint Window::height = 0;
|
uint Window::height = 0;
|
||||||
int Window::posX = 0;
|
int Window::posX = 0;
|
||||||
int Window::posY = 0;
|
int Window::posY = 0;
|
||||||
|
int Window::framerate = -1;
|
||||||
|
double Window::prevSwap = 0.0;
|
||||||
bool Window::fullscreen = false;
|
bool Window::fullscreen = false;
|
||||||
|
|
||||||
static util::ObjectsKeeper observers_keeper;
|
static util::ObjectsKeeper observers_keeper;
|
||||||
@ -58,8 +62,7 @@ bool Window::isIconified() {
|
|||||||
return glfwGetWindowAttrib(window, GLFW_ICONIFIED);
|
return glfwGetWindowAttrib(window, GLFW_ICONIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::isFocused()
|
bool Window::isFocused() {
|
||||||
{
|
|
||||||
return glfwGetWindowAttrib(window, GLFW_FOCUSED);
|
return glfwGetWindowAttrib(window, GLFW_FOCUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +185,8 @@ int Window::initialize(DisplaySettings* settings){
|
|||||||
}
|
}
|
||||||
}, true));
|
}, true));
|
||||||
|
|
||||||
glfwSwapInterval(settings->vsync.get());
|
glfwSwapInterval(1);
|
||||||
|
setFramerate(settings->framerate.get());
|
||||||
const GLubyte* vendor = glGetString(GL_VENDOR);
|
const GLubyte* vendor = glGetString(GL_VENDOR);
|
||||||
const GLubyte* renderer = glGetString(GL_RENDERER);
|
const GLubyte* renderer = glGetString(GL_RENDERER);
|
||||||
logger.info() << "GL Vendor: " << (char*)vendor;
|
logger.info() << "GL Vendor: " << (char*)vendor;
|
||||||
@ -281,8 +285,11 @@ void Window::setShouldClose(bool flag){
|
|||||||
glfwSetWindowShouldClose(window, flag);
|
glfwSetWindowShouldClose(window, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::swapInterval(int interval){
|
void Window::setFramerate(int framerate) {
|
||||||
glfwSwapInterval(interval);
|
if ((framerate != -1) != (Window::framerate != -1)) {
|
||||||
|
glfwSwapInterval(framerate == -1);
|
||||||
|
}
|
||||||
|
Window::framerate = framerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::toggleFullscreen(){
|
void Window::toggleFullscreen(){
|
||||||
@ -315,9 +322,15 @@ bool Window::isFullscreen() {
|
|||||||
return fullscreen;
|
return fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::swapBuffers(){
|
void Window::swapBuffers() {
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
Window::resetScissor();
|
Window::resetScissor();
|
||||||
|
double currentTime = time();
|
||||||
|
if (framerate > 0 && currentTime - prevSwap < (1.0 / framerate)) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(
|
||||||
|
static_cast<int>((1.0/framerate - (currentTime-prevSwap))*1000)));
|
||||||
|
}
|
||||||
|
prevSwap = time();
|
||||||
}
|
}
|
||||||
|
|
||||||
double Window::time() {
|
double Window::time() {
|
||||||
@ -362,3 +375,12 @@ bool Window::tryToMaximize(GLFWwindow* window, GLFWmonitor* monitor) {
|
|||||||
workArea.y + (workArea.w - Window::height) / 2 + windowFrame.y / 2);
|
workArea.y + (workArea.w - Window::height) / 2 + windowFrame.y / 2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::setIcon(const ImageData* image) {
|
||||||
|
GLFWimage icon {
|
||||||
|
static_cast<int>(image->getWidth()),
|
||||||
|
static_cast<int>(image->getHeight()),
|
||||||
|
image->getData()
|
||||||
|
};
|
||||||
|
glfwSetWindowIcon(window, 1, &icon);
|
||||||
|
}
|
||||||
|
|||||||
@ -19,6 +19,8 @@ class Window {
|
|||||||
static std::stack<glm::vec4> scissorStack;
|
static std::stack<glm::vec4> scissorStack;
|
||||||
static glm::vec4 scissorArea;
|
static glm::vec4 scissorArea;
|
||||||
static bool fullscreen;
|
static bool fullscreen;
|
||||||
|
static int framerate;
|
||||||
|
static double prevSwap;
|
||||||
|
|
||||||
static bool tryToMaximize(GLFWwindow* window, GLFWmonitor* monitor);
|
static bool tryToMaximize(GLFWwindow* window, GLFWmonitor* monitor);
|
||||||
public:
|
public:
|
||||||
@ -34,7 +36,7 @@ public:
|
|||||||
static bool isShouldClose();
|
static bool isShouldClose();
|
||||||
static void setShouldClose(bool flag);
|
static void setShouldClose(bool flag);
|
||||||
static void swapBuffers();
|
static void swapBuffers();
|
||||||
static void swapInterval(int interval);
|
static void setFramerate(int interval);
|
||||||
static void toggleFullscreen();
|
static void toggleFullscreen();
|
||||||
static bool isFullscreen();
|
static bool isFullscreen();
|
||||||
static bool isMaximized();
|
static bool isMaximized();
|
||||||
@ -53,6 +55,7 @@ public:
|
|||||||
static const char* getClipboardText();
|
static const char* getClipboardText();
|
||||||
static void setClipboardText(const char* text);
|
static void setClipboardText(const char* text);
|
||||||
static DisplaySettings* getSettings();
|
static DisplaySettings* getSettings();
|
||||||
|
static void setIcon(const ImageData* image);
|
||||||
|
|
||||||
static glm::vec2 size() {
|
static glm::vec2 size() {
|
||||||
return glm::vec2(width, height);
|
return glm::vec2(width, height);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user