diff --git a/doc/en/scripting/builtins/libgui.md b/doc/en/scripting/builtins/libgui.md index cbcca4ce7..df3615539 100644 --- a/doc/en/scripting/builtins/libgui.md +++ b/doc/en/scripting/builtins/libgui.md @@ -40,6 +40,37 @@ gui.get_locales_info() -> table of tables { Returns information about all loaded locales (res/texts/\*). +## Frames + +```lua +-- A replacement for menu:reset() to close the pause menu, deactivating the main UI frame. +gui.close_menu() + +-- Creates a frame. +gui.create_frame( + -- Global frame id (not related to the UI 'id' property). + id: str, + -- The texture to render the frame to. + -- If the string is empty, the frame is rendered to the screen. + output_texture: str, + -- Frame size. For example: {640, 480} + size: vec2 +) -> Element, Document + +-- Returns the id of the active frame (not the element id). +gui.get_active_frame() -> str + +-- Sets the active frame, receiving user input. +-- An empty string specifies the null frame capturing the cursor. +gui.set_active_frame( + -- ID of the frame created via gui.create_frame + id: str, + -- Function providing the cursor position in the frame. + -- Used for custom projection (e.g., in 3D) + [optional] cursorLocator +) +``` + ```lua gui.clear_markup( -- markup language ("md" - Markdown) diff --git a/doc/ru/scripting/builtins/libgui.md b/doc/ru/scripting/builtins/libgui.md index 50203bb46..5c564a0ad 100644 --- a/doc/ru/scripting/builtins/libgui.md +++ b/doc/ru/scripting/builtins/libgui.md @@ -40,6 +40,37 @@ gui.get_env(document: string) -> table gui.get_locales_info() -> table ``` +## Фреймы + +```lua +-- Замена для menu:reset() для закрытия меню паузы, деактивирующая основной фрейм UI. +gui.close_menu() + +-- Создаёт фрейм. +gui.create_frame( + -- Глобальный id фрейма (не связан с UI свойством 'id'). + id: str, + -- Текстура, в которую будет производиться рендер фрейма. + -- В случае пустой строки рендер производится на экран. + output_texture: str, + -- Размер фрейма. Например: {640, 480} + size: vec2 +) -> Element, Document + +-- Возвращает id активного фрейма (не id элемента). +gui.get_active_frame() -> str + +-- Устанавливает активный фрейм, получающий пользовательский ввод. +-- Пустая строка указывает null-фрейм, при котором захватывается курсор. +gui.set_active_frame( + -- id фрейма, созданного через gui.create_frame + id: str, + -- Функция-поставщик позиции курсора во фрейме. + -- Используется для пользовательской проекции (например в 3D) + [опционально] cursorLocator +) +``` + ## Разметка ```lua @@ -109,4 +140,4 @@ gui.template( ```lua -- Корневой UI документ. gui.root: Document -``` \ No newline at end of file +``` diff --git a/res/layouts/pages/pause.xml b/res/layouts/pages/pause.xml index 3e4427cae..fb26968ca 100644 --- a/res/layouts/pages/pause.xml +++ b/res/layouts/pages/pause.xml @@ -1,5 +1,5 @@ - + diff --git a/res/layouts/pages/settings_graphics.xml.lua b/res/layouts/pages/settings_graphics.xml.lua index b8b9d5497..806f48d0c 100644 --- a/res/layouts/pages/settings_graphics.xml.lua +++ b/res/layouts/pages/settings_graphics.xml.lua @@ -46,4 +46,5 @@ function on_open() create_checkbox("graphics.advanced-render", "Advanced render", "graphics.advanced-render.tooltip") create_setting("graphics.ssao", "SSAO", 1, "", "graphics.ssao.tooltip") create_setting("graphics.shadows-quality", "Shadows quality", 1) + create_setting("graphics.clouds-quality", "Clouds quality", 1) end diff --git a/res/preload.json b/res/preload.json index 0cd11b5bc..00948068e 100644 --- a/res/preload.json +++ b/res/preload.json @@ -8,7 +8,8 @@ "translucent", "background", "skybox_gen", - "shadows" + "shadows", + "clouds" ], "post-effects": [ "default", @@ -48,7 +49,8 @@ "gui/world", "gui/hud", "gui/entity", - "gui/half_block" + "gui/half_block", + "misc/blank" ], "fonts": [ { diff --git a/res/presets/weather/cloudy.json b/res/presets/weather/cloudy.json index 645b0a287..5e11a8ac6 100644 --- a/res/presets/weather/cloudy.json +++ b/res/presets/weather/cloudy.json @@ -1,4 +1,7 @@ { - "clouds": 0.8 + "clouds": 1.0, + "clouds_tint": [0.6, 0.7, 0.8], + "sky_tint": [1.5, 1.5, 1.5], + "min_sky_light": [0.05, 0.07, 0.1] } diff --git a/res/presets/weather/fog.json b/res/presets/weather/fog.json index e9c3a2b34..458283969 100644 --- a/res/presets/weather/fog.json +++ b/res/presets/weather/fog.json @@ -2,5 +2,6 @@ "fog_opacity": 0.98, "fog_dencity": 3.6, "fog_curve": 0.25, - "clouds": 0.8 + "clouds": 0.9, + "min_sky_light": [0.0, 0.0, 0.0] } diff --git a/res/presets/weather/rain.json b/res/presets/weather/rain.json index 184a80f0d..90e0512e9 100644 --- a/res/presets/weather/rain.json +++ b/res/presets/weather/rain.json @@ -19,5 +19,8 @@ "fog_opacity": 0.5, "fog_dencity": 1.7, "fog_curve": 0.5, - "clouds": 0.9 + "clouds": 0.96, + "sky_tint": [2.0, 2.0, 2.0], + "clouds_tint": [0.6, 0.7, 0.8], + "min_sky_light": [0.05, 0.07, 0.1] } diff --git a/res/presets/weather/snow.json b/res/presets/weather/snow.json index da80a8560..18763aa85 100644 --- a/res/presets/weather/snow.json +++ b/res/presets/weather/snow.json @@ -11,5 +11,8 @@ "fog_opacity": 0.8, "fog_dencity": 2.5, "fog_curve": 0.5, - "clouds": 0.5 + "clouds": 1.0, + "sky_tint": [1.9, 1.9, 1.9], + "clouds_tint": [0.7, 0.8, 0.9], + "min_sky_light": [0.05, 0.07, 0.1] } diff --git a/res/presets/weather/thunder.json b/res/presets/weather/thunder.json index d2a107f93..0a6f97c96 100644 --- a/res/presets/weather/thunder.json +++ b/res/presets/weather/thunder.json @@ -19,5 +19,7 @@ "fog_dencity": 2.0, "fog_curve": 0.5, "clouds": 0.7, - "thunder_rate": 0.1 + "thunder_rate": 0.1, + "clouds_tint": [0.3, 0.4, 0.5], + "min_sky_light": [0.0, 0.0, 0.0] } diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index c26db1ac6..3aa149972 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -232,6 +232,22 @@ _GUI_ROOT = Document.new("core:root") _MENU = _GUI_ROOT.menu menu = _MENU gui.root = _GUI_ROOT +gui.main_frame_id = "core:main" + +function gui.close_menu() + if menu then + menu:reset() + end + gui.set_active_frame("") +end + +local __gui_create_frame = gui.create_frame +function gui.create_frame(id, output, size) + __gui_create_frame(id, output, size) + + local document = Document.new(id) + return document.root, document +end do local status, err = pcall(function() @@ -435,9 +451,12 @@ function __vc_on_hud_open() if menu.page ~= "" then if not menu:back() then menu:reset() + gui.set_active_frame("") end elseif hud.is_inventory_open() then hud.close_inventory() + elseif gui.get_active_frame() then + gui.set_active_frame("") else hud.pause() end diff --git a/res/shaders/clouds.glslf b/res/shaders/clouds.glslf new file mode 100644 index 000000000..9b29ef110 --- /dev/null +++ b/res/shaders/clouds.glslf @@ -0,0 +1,31 @@ +layout (location = 0) out vec4 f_color; +layout (location = 1) out vec4 f_position; +layout (location = 2) out vec4 f_normal; +layout (location = 3) out vec4 f_emission; + +#include + +in vec4 a_torchLight; + +uniform sampler2D u_texture0; +uniform vec3 u_sunDir; + +// flags +uniform bool u_alphaClip; +uniform bool u_debugLights; +uniform bool u_debugNormals; +uniform vec4 u_tint; + +void main() { + f_color.rgb = max(a_torchLight.rgb, a_skyLight); + f_color.a = 1.0; + f_color *= u_tint; + +#ifndef ADVANCED_RENDER + vec3 fogColor = texture(u_skybox, a_dir).rgb; + f_color = mix(f_color, vec4(fogColor, 1.0), a_fog); +#endif + f_position = vec4(a_position, 1.0); + f_normal = vec4(a_normal, 1.0); + f_emission = vec4(vec3(a_emission), 1.0); +} diff --git a/res/shaders/clouds.glslv b/res/shaders/clouds.glslv new file mode 100644 index 000000000..0b9c17774 --- /dev/null +++ b/res/shaders/clouds.glslv @@ -0,0 +1,49 @@ +#include + +layout (location = 0) in vec3 v_position; +layout (location = 1) in vec2 v_texCoord; +layout (location = 2) in vec4 v_light; +layout (location = 3) in vec4 v_normal; + +#include +#include +#include +#include + +uniform float u_dayTime; + +out vec4 a_torchLight; + +void main() { + a_modelpos = u_model * vec4(v_position, 1.0f); + a_modelpos.x += sin(u_timer * 0.05 + a_modelpos.z * 0.002) * 1.5; + a_modelpos.z += sin(u_timer * 0.2 + a_modelpos.x * 0.002) * 1.5; + a_modelpos.y += sin(u_timer * 0.1 + (a_modelpos.x + a_modelpos.z) * 0.001) * 2.0; + + vec3 pos3d = a_modelpos.xyz - u_cameraPos; + + a_realnormal = v_normal.xyz * 2.0 - 1.0; + a_normal = calc_screen_normal(a_realnormal); + + a_torchLight = vec4(calc_torch_light( + v_light.rgb, a_realnormal, a_modelpos.xyz, u_torchlightColor, u_gamma + ), 1.0); + a_texCoord = v_texCoord; + + a_dir = a_modelpos.xyz - u_cameraPos; + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); + a_skyLight = skyLightColor.rgb*v_light.a; + + mat4 viewmodel = u_view * u_model; + a_distance = length(viewmodel * vec4(pos3d, 0.0)); + +#ifndef ADVANCED_RENDER + a_fog = calc_fog(length(viewmodel * vec4(pos3d * FOG_POS_SCALE, 0.0)) / 256.0); +#endif + + a_emission = v_normal.w; + + vec4 viewmodelpos = u_view * a_modelpos; + a_position = viewmodelpos.xyz; + gl_Position = u_proj * viewmodelpos; +} diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index c337ddb2d..8f534a6dc 100644 --- a/res/shaders/entity.glslv +++ b/res/shaders/entity.glslv @@ -13,6 +13,8 @@ layout (location = 4) in vec4 v_normal; out vec4 a_color; +uniform float u_dayTime; + void main() { a_modelpos = u_model * vec4(v_position, 1.0); vec3 pos3d = a_modelpos.xyz - u_cameraPos; @@ -26,7 +28,7 @@ void main() { a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_skybox); + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); a_color.rgb = max(a_color.rgb, skyLightColor.rgb * v_light.a) * v_color; a_color.a = u_opacity; diff --git a/res/shaders/lib/constants.glsl b/res/shaders/lib/constants.glsl index 74f295458..a8a9a4bb3 100644 --- a/res/shaders/lib/constants.glsl +++ b/res/shaders/lib/constants.glsl @@ -8,9 +8,8 @@ #define CURVATURE_FACTOR 0.002 // lighting -#define SKY_LIGHT_MUL 2.9 -#define SKY_LIGHT_TINT (vec3(1.0, 0.95, 0.9) * 2.0) -#define MIN_SKY_LIGHT vec3(0.2, 0.25, 0.33) +#define SKY_LIGHT_MUL 2.5 +#define SKY_LIGHT_TINT (vec3(1.0, 0.75, 0.6) * 2.0) // fog #define FOG_POS_SCALE vec3(1.0, 0.2, 1.0) diff --git a/res/shaders/lib/sky.glsl b/res/shaders/lib/sky.glsl index ce3604f5f..cfdbc3f2b 100644 --- a/res/shaders/lib/sky.glsl +++ b/res/shaders/lib/sky.glsl @@ -3,11 +3,12 @@ #include -vec3 pick_sky_color(samplerCube cubemap) { - vec3 skyLightColor = texture(cubemap, vec3(0.4f, 0.05f, 0.4f)).rgb; +vec3 pick_sky_color(samplerCube cubemap, float dayTime, vec3 minSkyLight) { + float elevation = sin(dayTime * PI2) * 0.2; + vec3 skyLightColor = texture(cubemap, vec3(0.0f, elevation, -0.4f)).rgb; skyLightColor *= SKY_LIGHT_TINT; skyLightColor = min(vec3(1.0f), skyLightColor * SKY_LIGHT_MUL); - skyLightColor = max(MIN_SKY_LIGHT, skyLightColor); + skyLightColor = max(minSkyLight, skyLightColor); return skyLightColor; } diff --git a/res/shaders/lib/world_uniforms.glsl b/res/shaders/lib/world_uniforms.glsl index 20c8f529e..96dde0110 100644 --- a/res/shaders/lib/world_uniforms.glsl +++ b/res/shaders/lib/world_uniforms.glsl @@ -11,5 +11,6 @@ uniform float u_timer; uniform samplerCube u_skybox; uniform vec3 u_torchlightColor; uniform float u_torchlightDistance; +uniform vec3 u_minSkyLight; #endif // GLSL_WORLD_UNIFORMS_ diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index 3d7220297..08cc6469e 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -10,6 +10,8 @@ layout (location = 3) in vec4 v_normal; #include #include +uniform float u_dayTime; + out vec4 a_torchLight; void main() { @@ -25,7 +27,7 @@ void main() { a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_skybox); + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); a_skyLight = skyLightColor.rgb*v_light.a; mat4 viewmodel = u_view * u_model; diff --git a/res/shaders/skybox_gen.glslf b/res/shaders/skybox_gen.glslf index 583104ebb..b6f2b7ffb 100644 --- a/res/shaders/skybox_gen.glslf +++ b/res/shaders/skybox_gen.glslf @@ -241,6 +241,8 @@ uniform vec3 u_xaxis; uniform vec3 u_yaxis; uniform vec3 u_zaxis; uniform vec3 u_lightDir; +uniform vec3 u_tint; +uniform vec3 u_hightlight; uniform int u_quality; uniform float u_mie; uniform float u_fog; @@ -295,5 +297,5 @@ void main() { col = 1.0 - exp(-col); col = min(col, vec3(1.0)); // Output to screen - f_color = vec4(col, 1.0); + f_color = vec4(col * u_tint + u_hightlight, 1.0); } diff --git a/res/shaders/translucent.glslv b/res/shaders/translucent.glslv index 8c429e97b..d9d8031c3 100644 --- a/res/shaders/translucent.glslv +++ b/res/shaders/translucent.glslv @@ -12,6 +12,8 @@ layout (location = 3) in vec4 v_normal; out vec4 a_torchLight; +uniform float u_dayTime; + void main() { a_modelpos = u_model * vec4(v_position, 1.0f); vec3 pos3d = a_modelpos.xyz - u_cameraPos; @@ -25,7 +27,7 @@ void main() { a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_skybox); + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); a_skyLight = skyLightColor.rgb*v_light.a; mat4 viewmodel = u_view * u_model; diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index 2f0985d45..66dc40a42 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -112,6 +112,7 @@ settings.Windowed=Оконный settings.Borderless=Безрамочный settings.Microphone=Микрофон settings.microphone.None=Нет +settings.Clouds quality=Качество облаков settings.Acoustic effects=Акустические эффекты # Управление diff --git a/res/textures/misc/blank.png b/res/textures/misc/blank.png new file mode 100644 index 000000000..d057ee32d Binary files /dev/null and b/res/textures/misc/blank.png differ diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index 4543a054b..4d943ae95 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -375,7 +375,7 @@ std::shared_ptr AssetsLoader::startTask(runnable onDone, int maxWorkers) { auto pool = std::make_shared>( "assets-loader-pool", - [=]() { return std::make_shared(this); }, + [=]() { return std::make_unique(this); }, [this](const assetload::postfunc& func) { func(&assets); }, maxWorkers ); diff --git a/src/coders/png.cpp b/src/coders/png.cpp index 7c469e32f..030844352 100644 --- a/src/coders/png.cpp +++ b/src/coders/png.cpp @@ -251,13 +251,13 @@ std::unique_ptr png::load_image(const ubyte* bytes, size_t size) { } png_read_image(pngPtr, rowPointers.get()); - ImageFormat format = ImageFormat::rgba8888; + ImageFormat format = ImageFormat::RGBA8888; switch (colorType) { case PNG_COLOR_TYPE_RGBA: - format = ImageFormat::rgba8888; + format = ImageFormat::RGBA8888; break; case PNG_COLOR_TYPE_RGB: - format = ImageFormat::rgb888; + format = ImageFormat::RGB888; break; default: png_destroy_read_struct(&pngPtr, &infoPtr, nullptr); @@ -296,7 +296,7 @@ void png::write_image(const std::string& filename, const ImageData* image) { image->getWidth(), image->getHeight(), (const ubyte*)image->getData(), - image->getFormat() == ImageFormat::rgba8888 + image->getFormat() == ImageFormat::RGBA8888 ); } @@ -306,6 +306,6 @@ util::Buffer png::encode_image(const ImageData& image) { image.getWidth(), image.getHeight(), image.getData(), - format == ImageFormat::rgba8888 + format == ImageFormat::RGBA8888 ); } diff --git a/src/content/ContentControl.cpp b/src/content/ContentControl.cpp index f9b8d7736..6daf48dc0 100644 --- a/src/content/ContentControl.cpp +++ b/src/content/ContentControl.cpp @@ -52,8 +52,6 @@ std::vector& ContentControl::getBasePacks() { } void ContentControl::resetContent(const std::vector& nonReset) { - paths.setCurrentWorldFolder(""); - scripting::cleanup(nonReset); std::vector resRoots; { diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 17e9e9f80..e793224a9 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -306,6 +306,9 @@ void Engine::startPauseLoop() { } void Engine::renderFrame() { + if (input->isCursorLocked() != (gui->getActiveFrame() == nullptr)) { + input->toggleCursor(); + } screen->draw(time.getDelta()); DrawContext ctx(nullptr, *window, nullptr); diff --git a/src/engine/ServerMainloop.cpp b/src/engine/ServerMainloop.cpp index 41887aeed..54698194e 100644 --- a/src/engine/ServerMainloop.cpp +++ b/src/engine/ServerMainloop.cpp @@ -1,7 +1,6 @@ #include "ServerMainloop.hpp" #include "Engine.hpp" -#include "EnginePaths.hpp" #include "logic/scripting/scripting.hpp" #include "logic/LevelController.hpp" #include "interfaces/Process.hpp" @@ -80,11 +79,10 @@ void ServerMainloop::run() { void ServerMainloop::setLevel(std::unique_ptr level) { if (level == nullptr) { controller->onWorldQuit(); - engine.getPaths().setCurrentWorldFolder(""); controller = nullptr; } else { controller = std::make_unique( - &engine, std::move(level), nullptr + engine, std::move(level), nullptr ); } } diff --git a/src/frontend/UiDocument.cpp b/src/frontend/UiDocument.cpp index c1269b879..a202c0d96 100644 --- a/src/frontend/UiDocument.cpp +++ b/src/frontend/UiDocument.cpp @@ -10,7 +10,7 @@ UiDocument::UiDocument( std::string id, - uidocscript script, + UiDocScript script, const std::shared_ptr& root, scriptenv env ) : id(std::move(id)), script(script), root(root), env(std::move(env)) { @@ -48,7 +48,7 @@ std::shared_ptr UiDocument::get(const std::string& id) const { return found->second.lock(); } -const uidocscript& UiDocument::getScript() const { +const UiDocScript& UiDocument::getScript() const { return script; } @@ -73,7 +73,7 @@ std::unique_ptr UiDocument::read( gui::UiXmlReader reader(gui, scriptenv(env)); auto view = reader.readXML(file.string(), *xmldoc->getRoot()); view->setId("root"); - uidocscript script {}; + UiDocScript script {}; auto scriptFile = io::path(file.string()+".lua"); if (io::is_regular_file(scriptFile)) { scripting::load_layout_script( diff --git a/src/frontend/UiDocument.hpp b/src/frontend/UiDocument.hpp index 8ebf7c3e6..57077bec0 100644 --- a/src/frontend/UiDocument.hpp +++ b/src/frontend/UiDocument.hpp @@ -13,7 +13,7 @@ namespace gui { class UINode; } -struct uidocscript { +struct UiDocScript { bool onopen : 1; bool onprogress : 1; bool onclose : 1; @@ -23,14 +23,14 @@ using UINodesMap = std::unordered_map>; class UiDocument { std::string id; - uidocscript script; + UiDocScript script; UINodesMap map; std::shared_ptr root; scriptenv env; public: UiDocument( std::string id, - uidocscript script, + UiDocScript script, const std::shared_ptr &root, scriptenv env ); @@ -42,7 +42,7 @@ public: const UINodesMap& getMap() const; std::shared_ptr getRoot() const; std::shared_ptr get(const std::string& id) const; - const uidocscript& getScript() const; + const UiDocScript& getScript() const; scriptenv getEnvironment() const; static std::unique_ptr read( diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index a9036b7ca..780bbf00a 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -1,9 +1,3 @@ -#include -#include -#include -#include -#include - #include "audio/audio.hpp" #include "constants.hpp" #include "content/Content.hpp" @@ -37,6 +31,12 @@ #include "world/Level.hpp" #include "world/World.hpp" +#include +#include +#include +#include +#include + using namespace gui; static std::shared_ptr