From 79e197eb1b63fb67c1e27e28b215bed007a0da0d Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Thu, 16 Jul 2020 03:58:18 +0200 Subject: [PATCH] [GameTime] Added to centralize time, sunlight intensity and sky color. --- resources/shaders/fog.f.glsl | 13 +----- resources/shaders/game.f.glsl | 5 +- source/client/graphics/CelestialObject.cpp | 3 +- source/client/graphics/Skybox.cpp | 15 +----- source/client/states/GameState.cpp | 22 ++++----- source/common/core/GameTime.cpp | 54 ++++++++++++++++++++++ source/common/core/GameTime.hpp | 45 ++++++++++++++++++ 7 files changed, 117 insertions(+), 40 deletions(-) create mode 100644 source/common/core/GameTime.cpp create mode 100644 source/common/core/GameTime.hpp diff --git a/resources/shaders/fog.f.glsl b/resources/shaders/fog.f.glsl index 38fbf1152..f814fc027 100644 --- a/resources/shaders/fog.f.glsl +++ b/resources/shaders/fog.f.glsl @@ -1,20 +1,11 @@ #version 120 uniform vec4 u_fogColor; - -uniform float u_time; +uniform vec4 u_skyColor; vec4 fog(vec4 color, float fogCoord, float fogStart, float fogEnd) { float fog = clamp((fogEnd - fogCoord) / (fogEnd - fogStart), 0.0, 1.0); - const float pi = 3.1415927; - - float sunlight = clamp(0.5 + sin(2 * pi * u_time) * 2.0, 0.0, 1.0); - - float red = clamp(sunlight - (1 - u_fogColor.r), 0.0, u_fogColor.r); - float green = clamp(sunlight - (1 - u_fogColor.g), 0.0, u_fogColor.g); - float blue = clamp(sunlight - (1 - u_fogColor.b), 0.0, u_fogColor.b); - - return mix(vec4(red, green, blue, u_fogColor.a), color, fog); + return mix(vec4(u_skyColor.r, u_skyColor.g, u_skyColor.b, u_fogColor.a), color, fog); } diff --git a/resources/shaders/game.f.glsl b/resources/shaders/game.f.glsl index 84e0c97d2..4f86442c2 100644 --- a/resources/shaders/game.f.glsl +++ b/resources/shaders/game.f.glsl @@ -13,7 +13,8 @@ uniform int u_renderDistance; uniform sampler2D u_tex; -uniform float u_time; +uniform vec4 u_skyColor; +uniform float u_sunlightIntensity; // Get light color vec4 light(vec4 color, vec3 lightColor, vec4 lightPosition, float ambientIntensity, float diffuseIntensity); @@ -58,7 +59,7 @@ void main() { if (lightCheck != -1.) { const float pi = 3.1415927; - float sunlight = clamp(v_lightValue.x * 0.5 * (1 + sin(2 * pi * u_time) * 4.0), 3, 15); + float sunlight = clamp(v_lightValue.x * u_sunlightIntensity, 3, 15); float ambientIntensity = max(max(v_lightValue.x, v_lightValue.y) / 16.0, minBrightness); float diffuseIntensity = max(v_lightValue.x, v_lightValue.y) / 32.0; diff --git a/source/client/graphics/CelestialObject.cpp b/source/client/graphics/CelestialObject.cpp index ce4052a68..ef5cab436 100644 --- a/source/client/graphics/CelestialObject.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -30,6 +30,7 @@ #include #include "CelestialObject.hpp" +#include "GameTime.hpp" #include "Vertex.hpp" CelestialObject::CelestialObject() { @@ -95,7 +96,7 @@ void CelestialObject::draw(gk::RenderTarget &target, gk::RenderStates states) co if (m_isUpdateNeeded) updateVertexBuffer(); - states.transform.rotate(-fmod((gk::GameClock::getInstance().getTicks() * 1.f / 1000.f + m_rotationOffset), 360), m_rotationAxis); + states.transform.rotate(-GameTime::getCurrentTime(m_rotationOffset) * 360.f, m_rotationAxis); states.transform *= getTransform(); states.vertexAttributes = VertexAttribute::All; diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 5b66ef94c..a4c1bcd0c 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -24,9 +24,8 @@ * * ===================================================================================== */ -#include - #include "ClientWorld.hpp" +#include "GameTime.hpp" #include "Sky.hpp" #include "Skybox.hpp" @@ -57,19 +56,9 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { - // FIXME: Duplicated in GameState - float time = std::fmod(gk::GameClock::getInstance().getTicks() * 1.f / 1000.f, 360.f) / 360.f; if (m_world.sky()) { - const float pi = 3.1415927f; - float sunlight = std::clamp(0.5f + std::sin(2 * pi * time) * 2.0f, 0.0f, 1.0f); - - gk::Color skyColor = m_world.sky()->color(); - skyColor.r = std::clamp(sunlight - (1.f - skyColor.r), 0.0f, skyColor.r); - skyColor.g = std::clamp(sunlight - (1.f - skyColor.g), 0.0f, skyColor.g); - skyColor.b = std::clamp(sunlight - (1.f - skyColor.b), 0.0f, skyColor.b); - gk::Shader::bind(&m_shader); - m_shader.setUniform("u_skyColor", skyColor); + m_shader.setUniform("u_skyColor", GameTime::getSkyColorFromTime(*m_world.sky(), GameTime::getCurrentTime())); m_shader.setUniform("u_starColor", m_world.sky()->color()); gk::Shader::bind(nullptr); } diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index fdff85588..b5fcf1569 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -32,8 +32,8 @@ #include #include -#include #include +#include #include #include #include @@ -42,6 +42,7 @@ #include "Events.hpp" #include "GameKey.hpp" #include "GameState.hpp" +#include "GameTime.hpp" #include "KeyboardHandler.hpp" #include "LuaGUIState.hpp" #include "PauseMenuState.hpp" @@ -201,22 +202,17 @@ void GameState::onGuiScaleChanged(const GuiScaleChangedEvent &event) { } void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const { - // FIXME: Duplicated in Skybox - float time = std::fmod(gk::GameClock::getInstance().getTicks() * 1.f / 1000.f, 360.f) / 360.f; - if (m_world.sky()) { - const float pi = 3.1415927f; - float sunlight = std::clamp(0.5f + std::sin(2 * pi * time) * 2.0f, 0.0f, 1.0f); + gk::Shader::bind(&m_shader); - gk::Color skyColor = m_world.sky()->color(); - float red = std::clamp(sunlight - (1 - skyColor.r), 0.0f, skyColor.r); - float green = std::clamp(sunlight - (1 - skyColor.g), 0.0f, skyColor.g); - float blue = std::clamp(sunlight - (1 - skyColor.b), 0.0f, skyColor.b); + float time = GameTime::getCurrentTime(); + if (m_world.sky()) { + const gk::Color &color = GameTime::getSkyColorFromTime(*m_world.sky(), time); + glClearColor(color.r, color.g, color.b, color.a); - glClearColor(red, green, blue, 1.0f); + m_shader.setUniform("u_skyColor", color); + m_shader.setUniform("u_sunlightIntensity", GameTime::getSunlightIntensityFromTime(time)); } - gk::Shader::bind(&m_shader); - m_shader.setUniform("u_time", time); gk::Shader::bind(nullptr); m_fbo.begin(); diff --git a/source/common/core/GameTime.cpp b/source/common/core/GameTime.cpp new file mode 100644 index 000000000..05dbb78fc --- /dev/null +++ b/source/common/core/GameTime.cpp @@ -0,0 +1,54 @@ +/* + * ===================================================================================== + * + * OpenMiner + * + * Copyright (C) 2018-2020 Unarelith, Quentin Bazin + * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) + * + * This file is part of OpenMiner. + * + * OpenMiner is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * OpenMiner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with OpenMiner; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * ===================================================================================== + */ +#include + +#include + +#include "GameTime.hpp" +#include "Sky.hpp" + +float GameTime::getCurrentTime(float offset) { + return std::fmod(gk::GameClock::getInstance().getTicks() * daySpeed / 1000.f + offset, 360.f) / 360.f; +} + +float GameTime::getSunlightIntensityFromTime(float time) { + static const float pi = 3.1415927f; + return std::clamp(0.5f + std::sin(2 * pi * time) * 2.0f, 0.0f, 1.0f); +} + +gk::Color GameTime::getSkyColorFromTime(const Sky &sky, float time) { + float sunlight = getSunlightIntensityFromTime(time); + + gk::Color skyColor = sky.color(); + skyColor.r = std::clamp(sunlight - (1.f - skyColor.r), 0.0f, skyColor.r); + skyColor.g = std::clamp(sunlight - (1.f - skyColor.g), 0.0f, skyColor.g); + skyColor.b = std::clamp(sunlight - (1.f - skyColor.b), 0.0f, skyColor.b); + skyColor.a = 1.f; + + return skyColor; +} + diff --git a/source/common/core/GameTime.hpp b/source/common/core/GameTime.hpp new file mode 100644 index 000000000..d405f9bae --- /dev/null +++ b/source/common/core/GameTime.hpp @@ -0,0 +1,45 @@ +/* + * ===================================================================================== + * + * OpenMiner + * + * Copyright (C) 2018-2020 Unarelith, Quentin Bazin + * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) + * + * This file is part of OpenMiner. + * + * OpenMiner is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * OpenMiner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with OpenMiner; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * ===================================================================================== + */ +#ifndef GAMETIME_HPP_ +#define GAMETIME_HPP_ + +#include + +class Sky; + +class GameTime { + public: + static constexpr float daySpeed = 1.f; + + static float getCurrentTime(float offset = 0.f); + + // Note: These functions are only needed in the client + static float getSunlightIntensityFromTime(float time); + static gk::Color getSkyColorFromTime(const Sky &sky, float time); +}; + +#endif // GAMETIME_HPP_