From 171763bb90cebdf89eea73dd542fd90b2ff59582 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Tue, 14 Jul 2020 16:13:53 +0200 Subject: [PATCH 01/25] Basic sun added. --- source/client/graphics/Skybox.cpp | 47 ++++++++++++++++++ source/client/graphics/Skybox.hpp | 48 +++++++++++++++++++ source/client/graphics/Sun.cpp | 76 ++++++++++++++++++++++++++++++ source/client/graphics/Sun.hpp | 46 ++++++++++++++++++ source/client/states/GameState.cpp | 1 + source/client/states/GameState.hpp | 3 ++ 6 files changed, 221 insertions(+) create mode 100644 source/client/graphics/Skybox.cpp create mode 100644 source/client/graphics/Skybox.hpp create mode 100644 source/client/graphics/Sun.cpp create mode 100644 source/client/graphics/Sun.hpp diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp new file mode 100644 index 000000000..58a1281fa --- /dev/null +++ b/source/client/graphics/Skybox.cpp @@ -0,0 +1,47 @@ +/* + * ===================================================================================== + * + * 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 + +#include "Skybox.hpp" +#include "Vertex.hpp" + +Skybox::Skybox(gk::Camera &camera) : m_camera(camera) { + setPosition(150, -10, 0); +} + +void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { + // Subtract the camera position - see comment in ClientWorld::draw() + gk::Vector3d cameraPosition = m_camera.getDPosition(); + states.transform.rotate(fmod(gk::GameClock::getInstance().getTicks(true) / 1000.f, 360), {0, 1, 0}); + states.transform.translate(getPosition().x - cameraPosition.x, getPosition().y - cameraPosition.y, getPosition().z - cameraPosition.z); + + target.draw(m_sun, states); +} + diff --git a/source/client/graphics/Skybox.hpp b/source/client/graphics/Skybox.hpp new file mode 100644 index 000000000..0732fd480 --- /dev/null +++ b/source/client/graphics/Skybox.hpp @@ -0,0 +1,48 @@ +/* + * ===================================================================================== + * + * 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 SKYBOX_HPP_ +#define SKYBOX_HPP_ + +#include + +#include "Sun.hpp" + +class Skybox : public gk::Drawable, public gk::Transformable { + public: + Skybox(gk::Camera &camera); + + private: + void draw(gk::RenderTarget &target, gk::RenderStates states) const override; + + gk::Camera m_camera; + + gk::VertexBuffer m_sunVBO; + + Sun m_sun; +}; + +#endif // SKYBOX_HPP_ diff --git a/source/client/graphics/Sun.cpp b/source/client/graphics/Sun.cpp new file mode 100644 index 000000000..85ab9467a --- /dev/null +++ b/source/client/graphics/Sun.cpp @@ -0,0 +1,76 @@ +/* + * ===================================================================================== + * + * 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 "Sun.hpp" +#include "Vertex.hpp" + +Sun::Sun() { + updateVertexBuffer(); +} + +void Sun::updateVertexBuffer() const { + float width = 20.f; + float height = 20.f; + Vertex vertices[4] = { + // Rectangle vertices + {{0, width, 0, -1}}, + {{0, 0, 0, -1}}, + {{0, 0, height, -1}}, + {{0, width, height, -1}}, + }; + + gk::Color color = gk::Color::Yellow; + for (u8 i = 0 ; i < 4 ; ++i) { + vertices[i].color[0] = color.r; + vertices[i].color[1] = color.g; + vertices[i].color[2] = color.b; + vertices[i].color[3] = color.a; + } + + gk::VertexBuffer::bind(&m_vbo); + m_vbo.setData(sizeof(vertices), vertices, GL_STATIC_DRAW); + gk::VertexBuffer::bind(nullptr); +} + +void Sun::draw(gk::RenderTarget &target, gk::RenderStates states) const { + // states.transform *= getTransform(); + + states.vertexAttributes = VertexAttribute::All; + + // glCheck(glEnable(GL_CULL_FACE)); + // glCheck(glEnable(GL_DEPTH_TEST)); + + static const GLubyte indices[] = { + 0, 1, 3, + 3, 1, 2 + }; + + target.drawElements(m_vbo, GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices, states); +} + diff --git a/source/client/graphics/Sun.hpp b/source/client/graphics/Sun.hpp new file mode 100644 index 000000000..ed548513e --- /dev/null +++ b/source/client/graphics/Sun.hpp @@ -0,0 +1,46 @@ +/* + * ===================================================================================== + * + * 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 SUN_HPP_ +#define SUN_HPP_ + +#include +#include +#include + +class Sun : public gk::Drawable, public gk::Transformable { + public: + Sun(); + + void updateVertexBuffer() const; + + private: + void draw(gk::RenderTarget &target, gk::RenderStates states) const override; + + gk::VertexBuffer m_vbo; +}; + +#endif // SUN_HPP_ diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index c3de47466..a289e8c64 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -217,6 +217,7 @@ void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const { states.shader = &m_shader; target.setView(m_camera); target.draw(m_world, states); + target.draw(m_skybox, states); for (auto &it : m_playerBoxes) if (it.second.dimension() == m_player.dimension()) diff --git a/source/client/states/GameState.hpp b/source/client/states/GameState.hpp index 47f6b6cf9..f66d1e9e4 100644 --- a/source/client/states/GameState.hpp +++ b/source/client/states/GameState.hpp @@ -43,6 +43,7 @@ #include "KeyboardHandler.hpp" #include "PlayerBox.hpp" #include "Registry.hpp" +#include "Skybox.hpp" class TextureAtlas; @@ -99,6 +100,8 @@ class GameState : public gk::ApplicationState { KeyboardHandler *m_keyboardHandler; bool m_areModKeysLoaded = false; + + Skybox m_skybox{m_camera}; }; #endif // GAMESTATE_HPP_ From eef600f2924c17696522000e0918777cfd53bd55 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Tue, 14 Jul 2020 16:26:37 +0200 Subject: [PATCH 02/25] Basic moon added. --- .../graphics/{Sun.cpp => CelestialObject.cpp} | 22 +++++++++---------- .../graphics/{Sun.hpp => CelestialObject.hpp} | 17 +++++++++----- source/client/graphics/Skybox.cpp | 15 ++++++------- source/client/graphics/Skybox.hpp | 5 +++-- 4 files changed, 32 insertions(+), 27 deletions(-) rename source/client/graphics/{Sun.cpp => CelestialObject.cpp} (78%) rename source/client/graphics/{Sun.hpp => CelestialObject.hpp} (80%) diff --git a/source/client/graphics/Sun.cpp b/source/client/graphics/CelestialObject.cpp similarity index 78% rename from source/client/graphics/Sun.cpp rename to source/client/graphics/CelestialObject.cpp index 85ab9467a..06a1228e5 100644 --- a/source/client/graphics/Sun.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -24,17 +24,17 @@ * * ===================================================================================== */ +#include #include -#include -#include "Sun.hpp" +#include "CelestialObject.hpp" #include "Vertex.hpp" -Sun::Sun() { +CelestialObject::CelestialObject() { updateVertexBuffer(); } -void Sun::updateVertexBuffer() const { +void CelestialObject::updateVertexBuffer() const { float width = 20.f; float height = 20.f; Vertex vertices[4] = { @@ -45,12 +45,11 @@ void Sun::updateVertexBuffer() const { {{0, width, height, -1}}, }; - gk::Color color = gk::Color::Yellow; for (u8 i = 0 ; i < 4 ; ++i) { - vertices[i].color[0] = color.r; - vertices[i].color[1] = color.g; - vertices[i].color[2] = color.b; - vertices[i].color[3] = color.a; + vertices[i].color[0] = m_color.r; + vertices[i].color[1] = m_color.g; + vertices[i].color[2] = m_color.b; + vertices[i].color[3] = m_color.a; } gk::VertexBuffer::bind(&m_vbo); @@ -58,8 +57,9 @@ void Sun::updateVertexBuffer() const { gk::VertexBuffer::bind(nullptr); } -void Sun::draw(gk::RenderTarget &target, gk::RenderStates states) const { - // states.transform *= getTransform(); +void CelestialObject::draw(gk::RenderTarget &target, gk::RenderStates states) const { + states.transform.rotate(fmod(gk::GameClock::getInstance().getTicks(true) / 1000.f, 360), {0, 1, 0}); + states.transform *= getTransform(); states.vertexAttributes = VertexAttribute::All; diff --git a/source/client/graphics/Sun.hpp b/source/client/graphics/CelestialObject.hpp similarity index 80% rename from source/client/graphics/Sun.hpp rename to source/client/graphics/CelestialObject.hpp index ed548513e..578d37d5c 100644 --- a/source/client/graphics/Sun.hpp +++ b/source/client/graphics/CelestialObject.hpp @@ -24,23 +24,28 @@ * * ===================================================================================== */ -#ifndef SUN_HPP_ -#define SUN_HPP_ +#ifndef CELESTIALOBJECT_HPP_ +#define CELESTIALOBJECT_HPP_ #include #include #include +#include -class Sun : public gk::Drawable, public gk::Transformable { +class CelestialObject : public gk::Drawable, public gk::Transformable { public: - Sun(); + CelestialObject(); - void updateVertexBuffer() const; + void setColor(const gk::Color &color) { m_color = color; updateVertexBuffer(); } private: + void updateVertexBuffer() const; + void draw(gk::RenderTarget &target, gk::RenderStates states) const override; gk::VertexBuffer m_vbo; + + gk::Color m_color = gk::Color::White; }; -#endif // SUN_HPP_ +#endif // CELESTIALOBJECT_HPP_ diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 58a1281fa..b9f092980 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -24,24 +24,23 @@ * * ===================================================================================== */ -#include -#include - -#include - #include "Skybox.hpp" #include "Vertex.hpp" Skybox::Skybox(gk::Camera &camera) : m_camera(camera) { - setPosition(150, -10, 0); + m_sun.setColor(gk::Color::Yellow); + m_sun.setPosition(150, -10, 0); + + m_moon.setColor(gk::Color::White); + m_moon.setPosition(-150, -10, 0); } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { // Subtract the camera position - see comment in ClientWorld::draw() gk::Vector3d cameraPosition = m_camera.getDPosition(); - states.transform.rotate(fmod(gk::GameClock::getInstance().getTicks(true) / 1000.f, 360), {0, 1, 0}); - states.transform.translate(getPosition().x - cameraPosition.x, getPosition().y - cameraPosition.y, getPosition().z - cameraPosition.z); + states.transform.translate(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z); target.draw(m_sun, states); + target.draw(m_moon, states); } diff --git a/source/client/graphics/Skybox.hpp b/source/client/graphics/Skybox.hpp index 0732fd480..4a1f3ad68 100644 --- a/source/client/graphics/Skybox.hpp +++ b/source/client/graphics/Skybox.hpp @@ -29,7 +29,7 @@ #include -#include "Sun.hpp" +#include "CelestialObject.hpp" class Skybox : public gk::Drawable, public gk::Transformable { public: @@ -42,7 +42,8 @@ class Skybox : public gk::Drawable, public gk::Transformable { gk::VertexBuffer m_sunVBO; - Sun m_sun; + CelestialObject m_sun; + CelestialObject m_moon; }; #endif // SKYBOX_HPP_ From 7fb9d202cc96a6587b8bf5e60bd5bb52d5bbf4f9 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Tue, 14 Jul 2020 18:24:28 +0200 Subject: [PATCH 03/25] Basic day/night cycle added. --- resources/shaders/fog.f.glsl | 12 ++++++++++- resources/shaders/game.f.glsl | 11 ++++++++++- source/client/graphics/CelestialObject.cpp | 2 +- source/client/graphics/Skybox.cpp | 4 ++-- source/client/states/GameState.cpp | 23 ++++++++++++++++++---- source/client/world/ClientWorld.cpp | 3 +-- source/client/world/ClientWorld.hpp | 2 ++ 7 files changed, 46 insertions(+), 11 deletions(-) diff --git a/resources/shaders/fog.f.glsl b/resources/shaders/fog.f.glsl index cf5ba69da..83accec7c 100644 --- a/resources/shaders/fog.f.glsl +++ b/resources/shaders/fog.f.glsl @@ -2,9 +2,19 @@ uniform vec4 u_fogColor; +uniform float u_time; + vec4 fog(vec4 color, float fogCoord, float fogStart, float fogEnd) { float fog = clamp((fogEnd - fogCoord) / (fogEnd - fogStart), 0.0, 1.0); - return mix(u_fogColor, color, fog); + const float pi = 3.1415927; + + float sunlight = clamp((1 + sin(2 * pi * u_time) * 4.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); } diff --git a/resources/shaders/game.f.glsl b/resources/shaders/game.f.glsl index be92a4452..ac55c530d 100644 --- a/resources/shaders/game.f.glsl +++ b/resources/shaders/game.f.glsl @@ -10,8 +10,11 @@ varying float v_blockFace; varying float v_dist; uniform int u_renderDistance; + uniform sampler2D u_tex; +uniform float u_time; + // Get light color vec4 light(vec4 color, vec3 lightColor, vec4 lightPosition, float ambientIntensity, float diffuseIntensity); @@ -50,6 +53,10 @@ void main() { float minBrightness = 2.0 / 16.0; 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 ambientIntensity = max(max(v_lightValue.x, v_lightValue.y) / 16.0, minBrightness); float diffuseIntensity = max(v_lightValue.x, v_lightValue.y) / 32.0; @@ -64,7 +71,9 @@ void main() { if (blockFace == 2. || blockFace == 3.) ambientIntensity = max(ambientIntensity * 0.9, minBrightness); - color = light(color, vec3(1.0, 1.0, 1.0), v_coord3d, ambientIntensity, diffuseIntensity); + float lightval = clamp(sunlight / 16.0, v_lightValue.y / 16.0, 1.0); + + color = light(color, vec3(lightval, lightval, lightval), v_coord3d, ambientIntensity, diffuseIntensity); } color.rgb *= v_ambientOcclusion; diff --git a/source/client/graphics/CelestialObject.cpp b/source/client/graphics/CelestialObject.cpp index 06a1228e5..9432744e8 100644 --- a/source/client/graphics/CelestialObject.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -58,7 +58,7 @@ void CelestialObject::updateVertexBuffer() const { } void CelestialObject::draw(gk::RenderTarget &target, gk::RenderStates states) const { - states.transform.rotate(fmod(gk::GameClock::getInstance().getTicks(true) / 1000.f, 360), {0, 1, 0}); + states.transform.rotate(-fmod(gk::GameClock::getInstance().getTicks() * 4 / 1000.f, 360), {0, 1, 0}); states.transform *= getTransform(); states.vertexAttributes = VertexAttribute::All; diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index b9f092980..4ab173b45 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -29,10 +29,10 @@ Skybox::Skybox(gk::Camera &camera) : m_camera(camera) { m_sun.setColor(gk::Color::Yellow); - m_sun.setPosition(150, -10, 0); + m_sun.setPosition(150, -10, -10); m_moon.setColor(gk::Color::White); - m_moon.setPosition(-150, -10, 0); + m_moon.setPosition(-150, -10, -10); } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index a289e8c64..659da0c82 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -24,6 +24,8 @@ * * ===================================================================================== */ +#include +#include #include #include @@ -207,10 +209,23 @@ void GameState::onGuiScaleChanged(const GuiScaleChangedEvent &event) { } void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const { - // FIXME: This uniform is not used anymore since water/leaves effects are disabled - // gk::Shader::bind(&m_shader); - // m_shader.setUniform("u_time", gk::GameClock::getInstance().getTicks()); - // gk::Shader::bind(nullptr); + float time = std::fmod(gk::GameClock::getInstance().getTicks() * 4.f / 1000.f, 360.f) / 360.f; + + gk::Shader::bind(&m_shader); + m_shader.setUniform("u_time", time); + gk::Shader::bind(nullptr); + + 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(); + 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); + + glClearColor(red, green, blue, 1.0f); + } m_fbo.begin(); diff --git a/source/client/world/ClientWorld.cpp b/source/client/world/ClientWorld.cpp index 398303e0e..cba91c1af 100644 --- a/source/client/world/ClientWorld.cpp +++ b/source/client/world/ClientWorld.cpp @@ -112,8 +112,7 @@ void ClientWorld::changeDimension(u16 dimensionID) { const Sky &sky = Registry::getInstance().getSkyFromStringID(dimension.sky()); m_sky = &sky; - glCheck(glClearColor(sky.color().r, sky.color().g, sky.color().b, sky.color().a)); - + // glCheck(glClearColor(sky.color().r, sky.color().g, sky.color().b, sky.color().a)); } void ClientWorld::receiveChunkData(Network::Packet &packet) { diff --git a/source/client/world/ClientWorld.hpp b/source/client/world/ClientWorld.hpp index d9aecc13b..0d57ffe67 100644 --- a/source/client/world/ClientWorld.hpp +++ b/source/client/world/ClientWorld.hpp @@ -68,6 +68,8 @@ class ClientWorld : public World, public gk::Drawable { std::size_t loadedChunkCount() const { return m_chunks.size(); } + const Sky *sky() const { return m_sky; } + private: void createChunkNeighbours(ClientChunk *chunk); From 10cac466db7c45135c23ce697f8f1b5a456522a7 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Tue, 14 Jul 2020 21:24:32 +0200 Subject: [PATCH 04/25] [Skybox] Now uses its own shader. --- external/gamekit | 2 +- resources/shaders/fog.f.glsl | 2 +- resources/shaders/game.f.glsl | 3 +++ resources/shaders/skybox.f.glsl | 24 ++++++++++++++++++++++++ resources/shaders/skybox.v.glsl | 22 ++++++++++++++++++++++ source/client/graphics/PlayerBox.cpp | 2 +- source/client/graphics/Skybox.cpp | 12 +++++++++--- source/client/graphics/Skybox.hpp | 6 +++--- source/client/hud/BlockCursor.cpp | 2 +- source/client/states/GameState.cpp | 23 ++++++++--------------- 10 files changed, 73 insertions(+), 25 deletions(-) create mode 100644 resources/shaders/skybox.f.glsl create mode 100644 resources/shaders/skybox.v.glsl diff --git a/external/gamekit b/external/gamekit index 1813cb06e..ec8bc52b1 160000 --- a/external/gamekit +++ b/external/gamekit @@ -1 +1 @@ -Subproject commit 1813cb06ef71c3d6f1ed80ca18a9f6b424af1c54 +Subproject commit ec8bc52b19b15b1ac0112f783380b779e3d49534 diff --git a/resources/shaders/fog.f.glsl b/resources/shaders/fog.f.glsl index 83accec7c..38fbf1152 100644 --- a/resources/shaders/fog.f.glsl +++ b/resources/shaders/fog.f.glsl @@ -9,7 +9,7 @@ vec4 fog(vec4 color, float fogCoord, float fogStart, float fogEnd) { const float pi = 3.1415927; - float sunlight = clamp((1 + sin(2 * pi * u_time) * 4.0), 0.0, 1.0); + 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); diff --git a/resources/shaders/game.f.glsl b/resources/shaders/game.f.glsl index ac55c530d..84e0c97d2 100644 --- a/resources/shaders/game.f.glsl +++ b/resources/shaders/game.f.glsl @@ -27,6 +27,9 @@ void main() { float blockFace = floor(v_blockFace + 0.5); float lightCheck = floor(v_lightValue.x + 0.5); + // Discard if the pixel is too far away + if(blockFace > -1. && v_dist > u_renderDistance) discard; + // Get current pixel color and apply multiplier on grayscale textures vec4 color = v_color; if (v_texCoord.x > -0.99 && v_texCoord.y > -0.99) { diff --git a/resources/shaders/skybox.f.glsl b/resources/shaders/skybox.f.glsl new file mode 100644 index 000000000..10096b0fb --- /dev/null +++ b/resources/shaders/skybox.f.glsl @@ -0,0 +1,24 @@ +#version 120 + +varying vec4 v_color; +varying vec4 v_coord3d; +varying vec2 v_texCoord; + +uniform sampler2D u_tex; + +void main() { + vec4 color = v_color; + + if (v_texCoord.x != -1 && v_texCoord.y != -1) { + color = texture2D(u_tex, v_texCoord); + + if (color.r == color.g && color.g == color.b) { + color *= v_color; + } + } + + if (color.a < 0.3) discard; + + gl_FragColor = color; +} + diff --git a/resources/shaders/skybox.v.glsl b/resources/shaders/skybox.v.glsl new file mode 100644 index 000000000..36391927b --- /dev/null +++ b/resources/shaders/skybox.v.glsl @@ -0,0 +1,22 @@ +#version 120 + +attribute vec4 color; +attribute vec4 coord3d; +attribute vec2 texCoord; + +varying vec4 v_color; +varying vec4 v_coord3d; +varying vec2 v_texCoord; + +uniform mat4 u_modelMatrix; +uniform mat4 u_projectionMatrix; +uniform mat4 u_viewMatrix; + +void main() { + v_coord3d = u_modelMatrix * vec4(coord3d.xyz, 1.0); + v_color = color; + v_texCoord = texCoord; + + gl_Position = u_projectionMatrix * u_viewMatrix * v_coord3d; +} + diff --git a/source/client/graphics/PlayerBox.cpp b/source/client/graphics/PlayerBox.cpp index c02ce6f45..a7b34dc91 100644 --- a/source/client/graphics/PlayerBox.cpp +++ b/source/client/graphics/PlayerBox.cpp @@ -272,7 +272,7 @@ void PlayerBox::updateVertexBuffer() { void PlayerBox::draw(gk::RenderTarget &target, gk::RenderStates states) const { // Subtract the camera position - see comment in ClientWorld::draw() - gk::Vector3d cameraPosition = m_camera.getDPosition(); + const gk::Vector3d &cameraPosition = m_camera.getDPosition(); states.transform.translate(m_x - cameraPosition.x, m_y - cameraPosition.y, m_z - cameraPosition.z); states.transform.rotate(m_viewAngleH, gk::Vector3{0, 0, 1}); diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 4ab173b45..9f449dd75 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -25,9 +25,13 @@ * ===================================================================================== */ #include "Skybox.hpp" -#include "Vertex.hpp" Skybox::Skybox(gk::Camera &camera) : m_camera(camera) { + m_shader.createProgram(); + m_shader.addShader(GL_VERTEX_SHADER, "resources/shaders/skybox.v.glsl"); + m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/skybox.f.glsl"); + m_shader.linkProgram(); + m_sun.setColor(gk::Color::Yellow); m_sun.setPosition(150, -10, -10); @@ -36,9 +40,11 @@ Skybox::Skybox(gk::Camera &camera) : m_camera(camera) { } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { + states.shader = &m_shader; + // Subtract the camera position - see comment in ClientWorld::draw() - gk::Vector3d cameraPosition = m_camera.getDPosition(); - states.transform.translate(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z); + const gk::Vector3d &cameraPosition = m_camera.getDPosition(); + states.transform.translate(cameraPosition.x, cameraPosition.y, cameraPosition.z); target.draw(m_sun, states); target.draw(m_moon, states); diff --git a/source/client/graphics/Skybox.hpp b/source/client/graphics/Skybox.hpp index 4a1f3ad68..63b61d655 100644 --- a/source/client/graphics/Skybox.hpp +++ b/source/client/graphics/Skybox.hpp @@ -28,6 +28,7 @@ #define SKYBOX_HPP_ #include +#include #include "CelestialObject.hpp" @@ -38,9 +39,8 @@ class Skybox : public gk::Drawable, public gk::Transformable { private: void draw(gk::RenderTarget &target, gk::RenderStates states) const override; - gk::Camera m_camera; - - gk::VertexBuffer m_sunVBO; + gk::Camera &m_camera; + gk::Shader m_shader; CelestialObject m_sun; CelestialObject m_moon; diff --git a/source/client/hud/BlockCursor.cpp b/source/client/hud/BlockCursor.cpp index 53da58a78..cd8c573a8 100644 --- a/source/client/hud/BlockCursor.cpp +++ b/source/client/hud/BlockCursor.cpp @@ -282,7 +282,7 @@ void BlockCursor::draw(gk::RenderTarget &target, gk::RenderStates states) const glCheck(glEnable(GL_DEPTH_TEST)); // Subtract the camera position - see comment in ClientWorld::draw() - gk::Vector3d cameraPosition = m_player.camera().getDPosition(); + const gk::Vector3d &cameraPosition = m_player.camera().getDPosition(); states.transform.translate(m_selectedBlock.x - cameraPosition.x, m_selectedBlock.y - cameraPosition.y, m_selectedBlock.z - cameraPosition.z); glCheck(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index 659da0c82..6cbc1f48c 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -58,6 +58,7 @@ GameState::GameState() m_clientCommandHandler.setupCallbacks(); m_camera.setAspectRatio((float)Config::screenWidth / Config::screenHeight); + m_camera.setFarClippingPlane(10000.0f); m_world.setClient(m_clientCommandHandler); m_world.setCamera(m_player.camera()); @@ -182,23 +183,14 @@ void GameState::update() { } m_client.update(); - - // Update far plane using render distance - static u16 oldRenderDistance = Config::renderDistance; - if (Config::renderDistance != oldRenderDistance) { - m_camera.setFarClippingPlane(Config::renderDistance * CHUNK_MAXSIZE); - oldRenderDistance = Config::renderDistance; - } } void GameState::initShaders() { m_shader.createProgram(); - m_shader.addShader(GL_VERTEX_SHADER, "resources/shaders/game.v.glsl"); m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/light.f.glsl"); m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/fog.f.glsl"); m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/game.f.glsl"); - m_shader.linkProgram(); m_fbo.loadShader("screen"); @@ -210,11 +202,6 @@ void GameState::onGuiScaleChanged(const GuiScaleChangedEvent &event) { void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const { float time = std::fmod(gk::GameClock::getInstance().getTicks() * 4.f / 1000.f, 360.f) / 360.f; - - gk::Shader::bind(&m_shader); - m_shader.setUniform("u_time", time); - gk::Shader::bind(nullptr); - 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); @@ -227,12 +214,18 @@ void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const { glClearColor(red, green, blue, 1.0f); } + gk::Shader::bind(&m_shader); + m_shader.setUniform("u_time", time); + gk::Shader::bind(nullptr); + m_fbo.begin(); states.shader = &m_shader; + target.setView(m_camera); - target.draw(m_world, states); + target.draw(m_skybox, states); + target.draw(m_world, states); for (auto &it : m_playerBoxes) if (it.second.dimension() == m_player.dimension()) From 11608132133a160e465dec3d7851be7f871462ab Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Tue, 14 Jul 2020 21:36:05 +0200 Subject: [PATCH 05/25] [Skybox] Small tweaks. --- source/client/graphics/CelestialObject.cpp | 2 +- source/client/graphics/Skybox.cpp | 8 ++++---- source/client/states/GameState.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/client/graphics/CelestialObject.cpp b/source/client/graphics/CelestialObject.cpp index 9432744e8..d1a073bbf 100644 --- a/source/client/graphics/CelestialObject.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -58,7 +58,7 @@ void CelestialObject::updateVertexBuffer() const { } void CelestialObject::draw(gk::RenderTarget &target, gk::RenderStates states) const { - states.transform.rotate(-fmod(gk::GameClock::getInstance().getTicks() * 4 / 1000.f, 360), {0, 1, 0}); + states.transform.rotate(-fmod(gk::GameClock::getInstance().getTicks() * 1.f / 1000.f, 360), {0, 1, 0}); states.transform *= getTransform(); states.vertexAttributes = VertexAttribute::All; diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 9f449dd75..1e261845c 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -33,10 +33,10 @@ Skybox::Skybox(gk::Camera &camera) : m_camera(camera) { m_shader.linkProgram(); m_sun.setColor(gk::Color::Yellow); - m_sun.setPosition(150, -10, -10); + m_sun.setPosition(300, -10, -10); - m_moon.setColor(gk::Color::White); - m_moon.setPosition(-150, -10, -10); + m_moon.setColor(gk::Color{240, 240, 240}); + m_moon.setPosition(-300, -10, -10); } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { @@ -44,7 +44,7 @@ void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { // Subtract the camera position - see comment in ClientWorld::draw() const gk::Vector3d &cameraPosition = m_camera.getDPosition(); - states.transform.translate(cameraPosition.x, cameraPosition.y, cameraPosition.z); + states.transform.translate(cameraPosition.x, cameraPosition.y, cameraPosition.z - 50); target.draw(m_sun, states); target.draw(m_moon, states); diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index 6cbc1f48c..06a8b653f 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -58,7 +58,7 @@ GameState::GameState() m_clientCommandHandler.setupCallbacks(); m_camera.setAspectRatio((float)Config::screenWidth / Config::screenHeight); - m_camera.setFarClippingPlane(10000.0f); + m_camera.setFarClippingPlane(1000.0f); m_world.setClient(m_clientCommandHandler); m_world.setCamera(m_player.camera()); @@ -201,7 +201,7 @@ void GameState::onGuiScaleChanged(const GuiScaleChangedEvent &event) { } void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const { - float time = std::fmod(gk::GameClock::getInstance().getTicks() * 4.f / 1000.f, 360.f) / 360.f; + 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); From 0c6e56d3b08496744a00c2411937121ffd9655d6 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Wed, 15 Jul 2020 01:14:05 +0200 Subject: [PATCH 06/25] [Skybox] Sun texture added. --- resources/config/textures.xml | 1 + resources/shaders/skybox.f.glsl | 8 ++-- resources/textures/sun.png | Bin 0 -> 488 bytes source/client/graphics/CelestialObject.cpp | 43 ++++++++++++++++----- source/client/graphics/CelestialObject.hpp | 14 ++++++- source/client/graphics/Skybox.cpp | 29 ++++++++++++-- source/client/graphics/Skybox.hpp | 6 ++- source/client/states/GameState.cpp | 1 + source/client/states/GameState.hpp | 2 +- 9 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 resources/textures/sun.png diff --git a/resources/config/textures.xml b/resources/config/textures.xml index 32a4574df..a76be6590 100644 --- a/resources/config/textures.xml +++ b/resources/config/textures.xml @@ -3,6 +3,7 @@ + diff --git a/resources/shaders/skybox.f.glsl b/resources/shaders/skybox.f.glsl index 10096b0fb..fdcdc28df 100644 --- a/resources/shaders/skybox.f.glsl +++ b/resources/shaders/skybox.f.glsl @@ -6,15 +6,15 @@ varying vec2 v_texCoord; uniform sampler2D u_tex; +uniform vec4 u_skyColor; + void main() { vec4 color = v_color; - if (v_texCoord.x != -1 && v_texCoord.y != -1) { + if (v_texCoord.x > -0.99 && v_texCoord.y > -0.99) { color = texture2D(u_tex, v_texCoord); - if (color.r == color.g && color.g == color.b) { - color *= v_color; - } + color += u_skyColor; } if (color.a < 0.3) discard; diff --git a/resources/textures/sun.png b/resources/textures/sun.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0559e4454ad50fa49d1374aea247d855c37c01 GIT binary patch literal 488 zcmVP)Nkl=}@eJy_FS;h)qzgDO z!!WSeePSh~{y_b{GVHd%u-X8Iz0Lbo!d~LKW0zjdKodk6c*?^c5+7iYLV=bH6>Y*I87tbCBzJB8$uDR&1h>~8Dv+I zAl>5-p#ev93^Gic#CL}*a>T11q9gAR@1E2IK@lfih9uz1iXe6gJd}#@hnu>(cQ9tu zfv!6%@Y}7Es}8gdE|IE!aA=}2Az=S`xoUoskFH-48oMujj#f|$jF||E^m!hMjx*oS zm&4h8jsJW&zIj75IhKX#amF?TQWNZnPD9u{k>Fh6KTvRTD*{grl1ZW30-?_{FX-#> zqA57Ndnfv`Snc?4L9Y^Z-{ig@)4pG{zK@FT54!_BuDic*y1z2}zVy2vTMlvX>V9-Q e#NoHo@%bO`sY80000 #include +#include #include "CelestialObject.hpp" #include "Vertex.hpp" CelestialObject::CelestialObject() { - updateVertexBuffer(); +} + +void CelestialObject::setTexture(const std::string &textureName) { + m_texture = &gk::ResourceHandler::getInstance().get(textureName); + + m_isUpdateNeeded = true; } void CelestialObject::updateVertexBuffer() const { - float width = 20.f; - float height = 20.f; + if (!m_width || !m_height) { + gkError() << "Can't update vertex buffer for celestial object of size 0"; + return; + } + Vertex vertices[4] = { // Rectangle vertices - {{0, width, 0, -1}}, - {{0, 0, 0, -1}}, - {{0, 0, height, -1}}, - {{0, width, height, -1}}, + {{0, m_width, 0, -1}}, + {{0, 0, 0, -1}}, + {{0, 0, m_height, -1}}, + {{0, m_width, m_height, -1}}, }; for (u8 i = 0 ; i < 4 ; ++i) { @@ -52,19 +61,35 @@ void CelestialObject::updateVertexBuffer() const { vertices[i].color[3] = m_color.a; } + if (m_texture) { + vertices[0].texCoord[0] = 1.f; + vertices[0].texCoord[1] = 0.f; + vertices[1].texCoord[0] = 0.f; + vertices[1].texCoord[1] = 0.f; + vertices[2].texCoord[0] = 0.f; + vertices[2].texCoord[1] = 1.f; + vertices[3].texCoord[0] = 1.f; + vertices[3].texCoord[1] = 1.f; + } + gk::VertexBuffer::bind(&m_vbo); m_vbo.setData(sizeof(vertices), vertices, GL_STATIC_DRAW); gk::VertexBuffer::bind(nullptr); + + m_isUpdateNeeded = false; } void CelestialObject::draw(gk::RenderTarget &target, gk::RenderStates states) const { + if (m_isUpdateNeeded) + updateVertexBuffer(); + states.transform.rotate(-fmod(gk::GameClock::getInstance().getTicks() * 1.f / 1000.f, 360), {0, 1, 0}); states.transform *= getTransform(); states.vertexAttributes = VertexAttribute::All; - // glCheck(glEnable(GL_CULL_FACE)); - // glCheck(glEnable(GL_DEPTH_TEST)); + if (m_texture) + states.texture = m_texture; static const GLubyte indices[] = { 0, 1, 3, diff --git a/source/client/graphics/CelestialObject.hpp b/source/client/graphics/CelestialObject.hpp index 578d37d5c..d0351fc01 100644 --- a/source/client/graphics/CelestialObject.hpp +++ b/source/client/graphics/CelestialObject.hpp @@ -36,7 +36,12 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { public: CelestialObject(); - void setColor(const gk::Color &color) { m_color = color; updateVertexBuffer(); } + float width() const { return m_width; } + float height() const { return m_height; } + + void setColor(const gk::Color &color) { m_color = color; m_isUpdateNeeded = true; } + void setSize(float width, float height) { m_width = width; m_height = height; m_isUpdateNeeded = true; } + void setTexture(const std::string &textureName); private: void updateVertexBuffer() const; @@ -46,6 +51,13 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { gk::VertexBuffer m_vbo; gk::Color m_color = gk::Color::White; + + float m_width = 0.f; + float m_height = 0.f; + + const gk::Texture *m_texture = nullptr; + + mutable bool m_isUpdateNeeded = true; }; #endif // CELESTIALOBJECT_HPP_ diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 1e261845c..5d868ff03 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -24,22 +24,45 @@ * * ===================================================================================== */ +#include + +#include "ClientWorld.hpp" +#include "Sky.hpp" #include "Skybox.hpp" -Skybox::Skybox(gk::Camera &camera) : m_camera(camera) { +Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_world(world) { m_shader.createProgram(); m_shader.addShader(GL_VERTEX_SHADER, "resources/shaders/skybox.v.glsl"); m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/skybox.f.glsl"); m_shader.linkProgram(); m_sun.setColor(gk::Color::Yellow); - m_sun.setPosition(300, -10, -10); + m_sun.setSize(100, 100); + m_sun.setPosition(300, -m_sun.width() / 2, -m_sun.height() / 2); + m_sun.setTexture("texture-sun"); m_moon.setColor(gk::Color{240, 240, 240}); - m_moon.setPosition(-300, -10, -10); + m_moon.setSize(20, 20); + m_moon.setPosition(-300, -m_moon.width() / 2, -m_moon.height() / 2); } 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 - skyColor.r), 0.0f, skyColor.r); + skyColor.g = std::clamp(sunlight - (1 - skyColor.g), 0.0f, skyColor.g); + skyColor.b = std::clamp(sunlight - (1 - skyColor.b), 0.0f, skyColor.b); + + gk::Shader::bind(&m_shader); + m_shader.setUniform("u_skyColor", skyColor); + gk::Shader::bind(nullptr); + } + states.shader = &m_shader; // Subtract the camera position - see comment in ClientWorld::draw() diff --git a/source/client/graphics/Skybox.hpp b/source/client/graphics/Skybox.hpp index 63b61d655..a8c366828 100644 --- a/source/client/graphics/Skybox.hpp +++ b/source/client/graphics/Skybox.hpp @@ -32,14 +32,18 @@ #include "CelestialObject.hpp" +class ClientWorld; + class Skybox : public gk::Drawable, public gk::Transformable { public: - Skybox(gk::Camera &camera); + Skybox(gk::Camera &camera, ClientWorld &world); private: void draw(gk::RenderTarget &target, gk::RenderStates states) const override; gk::Camera &m_camera; + ClientWorld &m_world; + gk::Shader m_shader; CelestialObject m_sun; diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index 06a8b653f..fdff85588 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -201,6 +201,7 @@ 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; diff --git a/source/client/states/GameState.hpp b/source/client/states/GameState.hpp index f66d1e9e4..5b1956a62 100644 --- a/source/client/states/GameState.hpp +++ b/source/client/states/GameState.hpp @@ -101,7 +101,7 @@ class GameState : public gk::ApplicationState { KeyboardHandler *m_keyboardHandler; bool m_areModKeysLoaded = false; - Skybox m_skybox{m_camera}; + Skybox m_skybox{m_camera, m_world}; }; #endif // GAMESTATE_HPP_ From e99e45eabb0797d3214ef25d34fc25c5c8822042 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Wed, 15 Jul 2020 01:34:16 +0200 Subject: [PATCH 07/25] [Skybox] Moon texture added. --- resources/config/textures.xml | 1 + resources/textures/moon_phases.png | Bin 0 -> 1140 bytes source/client/graphics/CelestialObject.cpp | 28 +++++++++++++++------ source/client/graphics/CelestialObject.hpp | 6 +++++ source/client/graphics/Skybox.cpp | 11 +++++--- 5 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 resources/textures/moon_phases.png diff --git a/resources/config/textures.xml b/resources/config/textures.xml index a76be6590..2082e678a 100644 --- a/resources/config/textures.xml +++ b/resources/config/textures.xml @@ -2,6 +2,7 @@ + diff --git a/resources/textures/moon_phases.png b/resources/textures/moon_phases.png new file mode 100644 index 0000000000000000000000000000000000000000..82d7c4b444cccf0c9670666616ead5cc0e3bc7ca GIT binary patch literal 1140 zcmV-)1dIELP)nxS1zV26iY+_104u7v163?I z0c*A#f(x+c9`Mh!XEM>l8HW~9kw4Ytk|p`;%>3#eTk7s~Zum~H?azmb@9ciGZva&M7)0e?NX6?YRAJI!L<4y6MoH+k@A>_f&90emvjNL$pBC z-YD&ldxI?PUzvS7#v$kIx|^y2kYB;i(T%DGZMnU{q(7YXNAtW5XE-FDtn9{3g%9#~ z^RI#{6=5M=h#riW!|c%5+$Tw z8{T54cY~9~ht;_kh)jMAKadx};_1We0D1~KTbxan=h?!T-8d6BR`3Jw!=}7YWb$M9 zokZj{!DaH=B%mLUXQzNp4<1YpAI^>*!LWh1*oi|pA@DK5$8Dflk%Iw{zk{DR2U~fO zwoGJMdN#i|S>6Y6zPgyNF6ZmV#;~!vz)l>(3F5=Vn#p%tk)4Bt{G0eLzFc+_c@J%5 zojUsE;`r&}c(Xit2Ezv4VyF19IbXO zf<%T;f|xSz-@g9{X9{L@zOec3ED$-X8bAy`9EL8xI7eE1U~xs}WKbjxmK=Qu7PGvAKtpS95kycj# z;nycXRRr8tfU*#lc^9iA1$lT)DacD78y*p%!`3R zoF>Jup&`H4uZeZ@Z~rxP{~sEg#rjE|KVpSKE{z7@fnWsUQBySVY&(R^Ui^aB|_ zGHm#fBp;eL`cR%_BaQP}IMsAv7E1>k=d*aW6?~SDw~NmSVt)Yp1Gq@CKY;xK{2|8v z0QLv)W*qwi*dM?LGVBjve*hoKvp?XD^#`EdsMNFyo5EryV0{IcIv;S5rBDvVigobu zZ~G!zwf=z8!bj}XD(x$hb^8xOGG-qpb*Q?05BH_6YW)G#0_YUCmckW_e{)zrM~Zw; zmI&B~A5nf?C4g3WcPU)4|DY%UQUpwq?=z=VkMF~8s{o4q2gT$jDMD8OzqEK$>ks(< zQjp8h$|*?fmMN%Ji?DA0K~VtFKz$MR{S&T%MX5jF-+v9&?LR1mw}#L9ef9^iKY%yO z*dM_D06s8be*pUf_|TmF0qhT8;S~D=*dM^+S@s9q75*Rmr%q8kb5Vc*0000 #include +#include #include #include "CelestialObject.hpp" @@ -62,14 +63,25 @@ void CelestialObject::updateVertexBuffer() const { } if (m_texture) { - vertices[0].texCoord[0] = 1.f; - vertices[0].texCoord[1] = 0.f; - vertices[1].texCoord[0] = 0.f; - vertices[1].texCoord[1] = 0.f; - vertices[2].texCoord[0] = 0.f; - vertices[2].texCoord[1] = 1.f; - vertices[3].texCoord[0] = 1.f; - vertices[3].texCoord[1] = 1.f; + gk::FloatRect texRect{0, 0, 1, 1}; + + if (m_phaseCount && m_phaseSize && m_currentPhase < m_phaseCount) { + u16 currentPhaseX = m_currentPhase % (m_texture->getSize().x / m_phaseSize); + u16 currentPhaseY = m_currentPhase / (m_texture->getSize().x / m_phaseSize); + texRect.x = currentPhaseX / float(m_texture->getSize().x); + texRect.y = currentPhaseY / float(m_texture->getSize().y); + texRect.sizeX = m_phaseSize / float(m_texture->getSize().x); + texRect.sizeY = m_phaseSize / float(m_texture->getSize().y); + } + + vertices[0].texCoord[0] = texRect.x + texRect.sizeX; + vertices[0].texCoord[1] = texRect.y; + vertices[1].texCoord[0] = texRect.x; + vertices[1].texCoord[1] = texRect.y; + vertices[2].texCoord[0] = texRect.x; + vertices[2].texCoord[1] = texRect.y + texRect.sizeY; + vertices[3].texCoord[0] = texRect.x + texRect.sizeX; + vertices[3].texCoord[1] = texRect.y + texRect.sizeY; } gk::VertexBuffer::bind(&m_vbo); diff --git a/source/client/graphics/CelestialObject.hpp b/source/client/graphics/CelestialObject.hpp index d0351fc01..1111d2b41 100644 --- a/source/client/graphics/CelestialObject.hpp +++ b/source/client/graphics/CelestialObject.hpp @@ -42,6 +42,8 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { void setColor(const gk::Color &color) { m_color = color; m_isUpdateNeeded = true; } void setSize(float width, float height) { m_width = width; m_height = height; m_isUpdateNeeded = true; } void setTexture(const std::string &textureName); + void setPhaseCount(u16 phaseCount, u16 phaseSize) { m_phaseCount = phaseCount; m_phaseSize = phaseSize; m_isUpdateNeeded = true; } + void setCurrentPhase(u16 currentPhase) { m_currentPhase = currentPhase; m_isUpdateNeeded = true; } private: void updateVertexBuffer() const; @@ -58,6 +60,10 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { const gk::Texture *m_texture = nullptr; mutable bool m_isUpdateNeeded = true; + + u16 m_phaseCount = 0; + u16 m_phaseSize = 0; + u16 m_currentPhase = 0; }; #endif // CELESTIALOBJECT_HPP_ diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 5d868ff03..8b1f9d096 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -37,13 +37,16 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor m_shader.linkProgram(); m_sun.setColor(gk::Color::Yellow); - m_sun.setSize(100, 100); - m_sun.setPosition(300, -m_sun.width() / 2, -m_sun.height() / 2); + m_sun.setSize(200, 200); + m_sun.setPosition(500, -m_sun.width() / 2, -m_sun.height() / 2); m_sun.setTexture("texture-sun"); m_moon.setColor(gk::Color{240, 240, 240}); - m_moon.setSize(20, 20); - m_moon.setPosition(-300, -m_moon.width() / 2, -m_moon.height() / 2); + m_moon.setSize(200, 200); + m_moon.setPosition(-500, -m_moon.width() / 2, -m_moon.height() / 2); + m_moon.setTexture("texture-moon_phases"); + m_moon.setPhaseCount(8, 32); + m_moon.setCurrentPhase(0); } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { From 49f9c1d9f0b8a3f88a6d473bd06c98c22166a557 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Wed, 15 Jul 2020 14:26:05 +0200 Subject: [PATCH 08/25] [Skybox] Stars added. --- resources/shaders/skybox.f.glsl | 5 ++++- source/client/graphics/CelestialObject.cpp | 2 +- source/client/graphics/CelestialObject.hpp | 5 +++++ source/client/graphics/Skybox.cpp | 23 +++++++++++++++++----- source/client/graphics/Skybox.hpp | 2 ++ 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/resources/shaders/skybox.f.glsl b/resources/shaders/skybox.f.glsl index fdcdc28df..ed9f1d4eb 100644 --- a/resources/shaders/skybox.f.glsl +++ b/resources/shaders/skybox.f.glsl @@ -7,15 +7,18 @@ varying vec2 v_texCoord; uniform sampler2D u_tex; uniform vec4 u_skyColor; +uniform vec4 u_starColor; void main() { vec4 color = v_color; if (v_texCoord.x > -0.99 && v_texCoord.y > -0.99) { color = texture2D(u_tex, v_texCoord); - color += u_skyColor; } + else if (color.a == 0) { + color = u_starColor; + } if (color.a < 0.3) discard; diff --git a/source/client/graphics/CelestialObject.cpp b/source/client/graphics/CelestialObject.cpp index f0b9c19e0..ce4052a68 100644 --- a/source/client/graphics/CelestialObject.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -95,7 +95,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, 360), {0, 1, 0}); + states.transform.rotate(-fmod((gk::GameClock::getInstance().getTicks() * 1.f / 1000.f + m_rotationOffset), 360), m_rotationAxis); states.transform *= getTransform(); states.vertexAttributes = VertexAttribute::All; diff --git a/source/client/graphics/CelestialObject.hpp b/source/client/graphics/CelestialObject.hpp index 1111d2b41..030b59468 100644 --- a/source/client/graphics/CelestialObject.hpp +++ b/source/client/graphics/CelestialObject.hpp @@ -44,6 +44,8 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { void setTexture(const std::string &textureName); void setPhaseCount(u16 phaseCount, u16 phaseSize) { m_phaseCount = phaseCount; m_phaseSize = phaseSize; m_isUpdateNeeded = true; } void setCurrentPhase(u16 currentPhase) { m_currentPhase = currentPhase; m_isUpdateNeeded = true; } + void setRotationOffset(u16 rotationOffset) { m_rotationOffset = rotationOffset; } + void setRotationAxis(const gk::Vector3f &rotationAxis) { m_rotationAxis = rotationAxis; } private: void updateVertexBuffer() const; @@ -64,6 +66,9 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { u16 m_phaseCount = 0; u16 m_phaseSize = 0; u16 m_currentPhase = 0; + + u16 m_rotationOffset = 0; + gk::Vector3f m_rotationAxis{0, 1, 0}; }; #endif // CELESTIALOBJECT_HPP_ diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 8b1f9d096..5b66ef94c 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -36,17 +36,24 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/skybox.f.glsl"); m_shader.linkProgram(); - m_sun.setColor(gk::Color::Yellow); m_sun.setSize(200, 200); m_sun.setPosition(500, -m_sun.width() / 2, -m_sun.height() / 2); m_sun.setTexture("texture-sun"); - m_moon.setColor(gk::Color{240, 240, 240}); m_moon.setSize(200, 200); m_moon.setPosition(-500, -m_moon.width() / 2, -m_moon.height() / 2); m_moon.setTexture("texture-moon_phases"); m_moon.setPhaseCount(8, 32); m_moon.setCurrentPhase(0); + + for (int i = 0 ; i < 1000 ; ++i) { + auto &star = m_stars.emplace_back(); + star.setColor(gk::Color{0, 0, 0, 0}); + star.setSize(5, 5); + star.setPosition(700 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); + star.setRotationOffset(rand() % 360); + star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); + } } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { @@ -57,12 +64,13 @@ void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { 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 - skyColor.r), 0.0f, skyColor.r); - skyColor.g = std::clamp(sunlight - (1 - skyColor.g), 0.0f, skyColor.g); - skyColor.b = std::clamp(sunlight - (1 - skyColor.b), 0.0f, skyColor.b); + 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_starColor", m_world.sky()->color()); gk::Shader::bind(nullptr); } @@ -74,5 +82,10 @@ void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { target.draw(m_sun, states); target.draw(m_moon, states); + + glDisable(GL_CULL_FACE); + + for (auto &it : m_stars) + target.draw(it, states); } diff --git a/source/client/graphics/Skybox.hpp b/source/client/graphics/Skybox.hpp index a8c366828..07faf28c0 100644 --- a/source/client/graphics/Skybox.hpp +++ b/source/client/graphics/Skybox.hpp @@ -48,6 +48,8 @@ class Skybox : public gk::Drawable, public gk::Transformable { CelestialObject m_sun; CelestialObject m_moon; + + std::vector m_stars; }; #endif // SKYBOX_HPP_ From 6ecb6133cc121433a4195f5a4019a9871ec4d817 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Thu, 16 Jul 2020 03:58:18 +0200 Subject: [PATCH 09/25] [GameTime] Added to centralize time, sunlight intensity and sky color. --- resources/shaders/fog.f.glsl | 13 +----- resources/shaders/game.f.glsl | 7 ++- 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(+), 42 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..0ad478e0a 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); @@ -56,9 +57,7 @@ void main() { float minBrightness = 2.0 / 16.0; 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_ From ebecc93db8994749974f4022abc60ff439f858b2 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Thu, 16 Jul 2020 04:06:07 +0200 Subject: [PATCH 10/25] [CelestialObject] Now allows to control rotation speed. --- source/client/graphics/CelestialObject.cpp | 2 +- source/client/graphics/CelestialObject.hpp | 2 ++ source/client/graphics/Skybox.cpp | 1 + source/common/core/GameTime.cpp | 4 ++-- source/common/core/GameTime.hpp | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source/client/graphics/CelestialObject.cpp b/source/client/graphics/CelestialObject.cpp index ef5cab436..d639d8fcd 100644 --- a/source/client/graphics/CelestialObject.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -96,7 +96,7 @@ void CelestialObject::draw(gk::RenderTarget &target, gk::RenderStates states) co if (m_isUpdateNeeded) updateVertexBuffer(); - states.transform.rotate(-GameTime::getCurrentTime(m_rotationOffset) * 360.f, m_rotationAxis); + states.transform.rotate(-GameTime::getCurrentTime(m_rotationOffset, m_rotationSpeed) * 360.f, m_rotationAxis); states.transform *= getTransform(); states.vertexAttributes = VertexAttribute::All; diff --git a/source/client/graphics/CelestialObject.hpp b/source/client/graphics/CelestialObject.hpp index 030b59468..b2fccf766 100644 --- a/source/client/graphics/CelestialObject.hpp +++ b/source/client/graphics/CelestialObject.hpp @@ -45,6 +45,7 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { void setPhaseCount(u16 phaseCount, u16 phaseSize) { m_phaseCount = phaseCount; m_phaseSize = phaseSize; m_isUpdateNeeded = true; } void setCurrentPhase(u16 currentPhase) { m_currentPhase = currentPhase; m_isUpdateNeeded = true; } void setRotationOffset(u16 rotationOffset) { m_rotationOffset = rotationOffset; } + void setRotationSpeed(float rotationSpeed) { m_rotationSpeed = rotationSpeed; } void setRotationAxis(const gk::Vector3f &rotationAxis) { m_rotationAxis = rotationAxis; } private: @@ -68,6 +69,7 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { u16 m_currentPhase = 0; u16 m_rotationOffset = 0; + float m_rotationSpeed = 1.f; gk::Vector3f m_rotationAxis{0, 1, 0}; }; diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index a4c1bcd0c..15d565fd4 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -51,6 +51,7 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor star.setSize(5, 5); star.setPosition(700 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); star.setRotationOffset(rand() % 360); + star.setRotationSpeed(0.4f); star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); } } diff --git a/source/common/core/GameTime.cpp b/source/common/core/GameTime.cpp index 05dbb78fc..52342e8fb 100644 --- a/source/common/core/GameTime.cpp +++ b/source/common/core/GameTime.cpp @@ -31,8 +31,8 @@ #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::getCurrentTime(float offset, float speed) { + return std::fmod(gk::GameClock::getInstance().getTicks() * daySpeed * speed / 1000.f + offset, 360.f) / 360.f; } float GameTime::getSunlightIntensityFromTime(float time) { diff --git a/source/common/core/GameTime.hpp b/source/common/core/GameTime.hpp index d405f9bae..c04546e7e 100644 --- a/source/common/core/GameTime.hpp +++ b/source/common/core/GameTime.hpp @@ -35,7 +35,7 @@ class GameTime { public: static constexpr float daySpeed = 1.f; - static float getCurrentTime(float offset = 0.f); + static float getCurrentTime(float offset = 0.f, float speed = 1.f); // Note: These functions are only needed in the client static float getSunlightIntensityFromTime(float time); From f9edb0cc63b33a499e765a831a1e1802e997f668 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Thu, 16 Jul 2020 16:32:56 +0200 Subject: [PATCH 11/25] [Config] It's now possible to use fallback AO only while using smooth lighting. --- source/client/core/Config.cpp | 10 +++++----- source/client/core/Config.hpp | 2 +- source/client/states/SettingsMenuState.cpp | 16 ++++++++++++---- source/client/world/ChunkBuilder.cpp | 8 +++----- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/source/client/core/Config.cpp b/source/client/core/Config.cpp index cc22b77d1..5cee9dd71 100644 --- a/source/client/core/Config.cpp +++ b/source/client/core/Config.cpp @@ -50,8 +50,8 @@ bool Config::isCrosshairVisible = true; // Graphics u16 Config::renderDistance = 8; +u8 Config::ambientOcclusion = 2; bool Config::isSmoothLightingEnabled = true; -bool Config::isAmbientOcclusionEnabled = false; bool Config::isWireframeModeEnabled = false; bool Config::isFullscreenModeEnabled = false; bool Config::isVerticalSyncEnabled = true; @@ -90,16 +90,16 @@ void Config::loadConfigFromFile(const char *filename) { isCrosshairVisible = lua["isCrosshairVisible"].get_or(isCrosshairVisible); renderDistance = lua["renderDistance"].get_or(renderDistance); + ambientOcclusion = std::clamp(lua["ambientOcclusion"].get_or(ambientOcclusion), 0, 2); isSmoothLightingEnabled = lua["isSmoothLightingEnabled"].get_or(isSmoothLightingEnabled); - isAmbientOcclusionEnabled = lua["isAmbientOcclusionEnabled"].get_or(isAmbientOcclusionEnabled); isWireframeModeEnabled = lua["isWireframeModeEnabled"].get_or(isWireframeModeEnabled); isFullscreenModeEnabled = lua["isFullscreenModeEnabled"].get_or(isFullscreenModeEnabled); isVerticalSyncEnabled = lua["isVerticalSyncEnabled"].get_or(isVerticalSyncEnabled); cameraFOV = lua["cameraFOV"].get_or(cameraFOV); screenWidth = lua["screenWidth"].get_or(screenWidth); screenHeight = lua["screenHeight"].get_or(screenHeight); - guiScale = lua["guiScale"].get_or(guiScale); - mipmapLevels = lua["mipmapLevels"].get_or(mipmapLevels); + guiScale = std::clamp(lua["guiScale"].get_or(guiScale), 1, 3); + mipmapLevels = std::clamp(lua["mipmapLevels"].get_or(mipmapLevels), 0, 4); mouseSensitivity = lua["mouseSensitivity"].get_or(mouseSensitivity); @@ -126,8 +126,8 @@ void Config::saveConfigToFile(const char *filename) { file << "isCrosshairVisible = " << (isCrosshairVisible ? "true" : "false") << std::endl; file << std::endl; file << "renderDistance = " << renderDistance << std::endl; + file << "ambientOcclusion = " << (u16)ambientOcclusion << std::endl; file << "isSmoothLightingEnabled = " << (isSmoothLightingEnabled ? "true" : "false") << std::endl; - file << "isAmbientOcclusionEnabled = " << (isAmbientOcclusionEnabled ? "true" : "false") << std::endl; file << "isWireframeModeEnabled = " << (isWireframeModeEnabled ? "true" : "false") << std::endl; file << "isFullscreenModeEnabled = " << (isFullscreenModeEnabled ? "true" : "false") << std::endl; file << "isVerticalSyncEnabled = " << (isVerticalSyncEnabled ? "true" : "false") << std::endl; diff --git a/source/client/core/Config.hpp b/source/client/core/Config.hpp index 84764ea82..2121196e3 100644 --- a/source/client/core/Config.hpp +++ b/source/client/core/Config.hpp @@ -45,8 +45,8 @@ namespace Config { // Graphics extern u16 renderDistance; + extern u8 ambientOcclusion; extern bool isSmoothLightingEnabled; - extern bool isAmbientOcclusionEnabled; extern bool isWireframeModeEnabled; extern bool isFullscreenModeEnabled; extern bool isVerticalSyncEnabled; diff --git a/source/client/states/SettingsMenuState.cpp b/source/client/states/SettingsMenuState.cpp index cf4faac67..f226d8d17 100644 --- a/source/client/states/SettingsMenuState.cpp +++ b/source/client/states/SettingsMenuState.cpp @@ -215,13 +215,21 @@ void SettingsMenuState::addGraphicsButtons() { Config::isSmoothLightingEnabled = !Config::isSmoothLightingEnabled; button.setText(std::string("Smooth Lighting: ") + (Config::isSmoothLightingEnabled ? "ON" : "OFF")); - m_aoButton->setEnabled(!Config::isSmoothLightingEnabled); - World::isReloadRequested = true; }); - m_aoButton = &addToggleButton("Ambient Occlusion", Config::isAmbientOcclusionEnabled, true); - m_aoButton->setEnabled(!Config::isSmoothLightingEnabled); + const std::string aoValueNames[3] = { + "OFF", + "Normal", + "Smooth Lighting" + }; + + m_menuWidget.addButton(std::string("Ambient Occlusion: ") + aoValueNames[Config::ambientOcclusion], [&, aoValueNames] (TextButton &button) { + Config::ambientOcclusion = (Config::ambientOcclusion + 1) % (Config::isSmoothLightingEnabled ? 3 : 2); + button.setText(std::string("Ambient Occlusion: ") + aoValueNames[Config::ambientOcclusion]); + + World::isReloadRequested = true; + }); m_menuWidget.addSlider("GUI Scale: " + std::to_string(Config::guiScale), [this] (SliderWidget &slider, u32 eventType) { slider.setText("GUI Scale: " + std::to_string(slider.getCurrentValue())); diff --git a/source/client/world/ChunkBuilder.cpp b/source/client/world/ChunkBuilder.cpp index 407bc7f64..3d6d954d8 100644 --- a/source/client/world/ChunkBuilder.cpp +++ b/source/client/world/ChunkBuilder.cpp @@ -260,7 +260,7 @@ inline void ChunkBuilder::addFace(s8f x, s8f y, s8f z, s8f f, const ClientChunk } auto addVertex = [&](u8 v) { - if (!Config::isAmbientOcclusionEnabled || Config::isSmoothLightingEnabled) + if (Config::ambientOcclusion != 1) vertices[v].ambientOcclusion = 5; if (blockState.drawType() == BlockDrawType::Liquid) @@ -411,10 +411,8 @@ inline u8 ChunkBuilder::getLightForVertex(Light light, s8f x, s8f y, s8f z, cons // continue; // If the chunk is initialized, add the light value to the total - if (lightValues[i] != -1) { - // float strength = ((surroundingBlocks[i] - normal == gk::Vector3i{x, y, z}) ? 1 : Config::aoStrength); - // total += lightValues[i] * strength; - // count += strength; + // But only add dark blocks if AO is set on Smooth Lighting + if (lightValues[i] != -1 && (Config::ambientOcclusion == 2 || lightValues[i] != 0)) { total += lightValues[i]; ++count; } From ff608981d8e5b19ea07b8ee53dc760cbb39636a1 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Thu, 16 Jul 2020 17:49:04 +0200 Subject: [PATCH 12/25] [mods/default] Pickaxe is now effective against Glowstone and Redstone Lamp. --- mods/default/blocks.lua | 6 ++++++ mods/default/tools.lua | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/mods/default/blocks.lua b/mods/default/blocks.lua index db0db4ab1..9a62b6684 100644 --- a/mods/default/blocks.lua +++ b/mods/default/blocks.lua @@ -152,6 +152,9 @@ mod:block { name = "Glowstone", tiles = "glowstone.png", is_light_source = true, + groups = { + om_material_stone = 1 + }, } mod:block { @@ -338,6 +341,9 @@ mod:block { id = "redstone_lamp", name = "Redstone Lamp", tiles = "redstone_lamp_off.png", + groups = { + om_material_stone = 1 + }, states = { { is_light_source = true, tiles = "redstone_lamp_on.png" } diff --git a/mods/default/tools.lua b/mods/default/tools.lua index 0e9f4a3b7..160a529ee 100644 --- a/mods/default/tools.lua +++ b/mods/default/tools.lua @@ -61,6 +61,10 @@ function register_tool(name, material, mining_speed, harvest_capability) tool_def.effective_on = { "group:om_material_wood" } + elseif name == "pickaxe" then + tool_def.effective_on = { + "group:om_material_stone" + } end mod:item(tool_def) From c609f9ebecf159c948a7c998b6a6f44e7f4bef0f Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 01:04:37 +0200 Subject: [PATCH 13/25] [GameTime] Tick system added. [ChatCommandHandler] Added '/tps' command to get ticks per second. [ServerWorld] Fixed world generation speed. --- external/gamekit | 2 +- source/common/core/GameTime.cpp | 23 ++++++++++++++++ source/common/core/GameTime.hpp | 12 +++++++-- source/server/core/ServerApplication.cpp | 12 ++++++++- source/server/network/ChatCommandHandler.cpp | 18 ++++++++++--- source/server/network/ChatCommandHandler.hpp | 2 ++ source/server/world/ServerWorld.cpp | 28 +++++++++----------- source/server/world/ServerWorld.hpp | 4 +-- source/server/world/WorldController.cpp | 4 +-- source/server/world/WorldController.hpp | 2 +- 10 files changed, 79 insertions(+), 28 deletions(-) diff --git a/external/gamekit b/external/gamekit index ec8bc52b1..fb10f8bbf 160000 --- a/external/gamekit +++ b/external/gamekit @@ -1 +1 @@ -Subproject commit ec8bc52b19b15b1ac0112f783380b779e3d49534 +Subproject commit fb10f8bbf8bcf88e77020a961412f52b83a125e6 diff --git a/source/common/core/GameTime.cpp b/source/common/core/GameTime.cpp index 52342e8fb..90b3bde61 100644 --- a/source/common/core/GameTime.cpp +++ b/source/common/core/GameTime.cpp @@ -31,6 +31,9 @@ #include "GameTime.hpp" #include "Sky.hpp" +u64 GameTime::s_ticks = 0; +u16 GameTime::s_ticksPerSecond = 0; + float GameTime::getCurrentTime(float offset, float speed) { return std::fmod(gk::GameClock::getInstance().getTicks() * daySpeed * speed / 1000.f + offset, 360.f) / 360.f; } @@ -52,3 +55,23 @@ gk::Color GameTime::getSkyColorFromTime(const Sky &sky, float time) { return skyColor; } +void GameTime::incrementTicks() { + ++s_ticks; + + static u64 tpsTimer = gk::GameClock::getInstance().getTicks(true); + static u8 tpsCount = 0; + + u64 currentClockTicks = gk::GameClock::getInstance().getTicks(true); + ++tpsCount; + + if (currentClockTicks - tpsTimer > 1000) { + s_ticksPerSecond = floor(tpsCount / ((currentClockTicks - tpsTimer) / 1000.0f) + 0.5f); + tpsTimer = currentClockTicks; + tpsCount = 0; + } +} + +u16 GameTime::getTicksPerSecond() { + return s_ticksPerSecond; +} + diff --git a/source/common/core/GameTime.hpp b/source/common/core/GameTime.hpp index c04546e7e..230ed1c15 100644 --- a/source/common/core/GameTime.hpp +++ b/source/common/core/GameTime.hpp @@ -35,11 +35,19 @@ class GameTime { public: static constexpr float daySpeed = 1.f; - static float getCurrentTime(float offset = 0.f, float speed = 1.f); - // Note: These functions are only needed in the client + static float getCurrentTime(float offset = 0.f, float speed = 1.f); static float getSunlightIntensityFromTime(float time); static gk::Color getSkyColorFromTime(const Sky &sky, float time); + + // Note: These functions are only needed in the server + static void incrementTicks(); + static u16 getTicksPerSecond(); + static u64 getTicks() { return s_ticks; } + + private: + static u64 s_ticks; + static u16 s_ticksPerSecond; }; #endif // GAMETIME_HPP_ diff --git a/source/server/core/ServerApplication.cpp b/source/server/core/ServerApplication.cpp index 247e8db6d..390ea4070 100644 --- a/source/server/core/ServerApplication.cpp +++ b/source/server/core/ServerApplication.cpp @@ -28,6 +28,7 @@ #include "BlockGeometry.hpp" #include "Events.hpp" +#include "GameTime.hpp" #include "ServerApplication.hpp" #include "ServerBlock.hpp" #include "ServerConfig.hpp" @@ -193,7 +194,16 @@ int ServerApplication::run(bool isProtected) { } void ServerApplication::update() { - m_worldController.update(); + static u64 lastTick = m_clock.getTicks() / 50; + bool doTick = false; + if (lastTick < m_clock.getTicks() / 50) { + lastTick = m_clock.getTicks() / 50; + doTick = true; + + GameTime::incrementTicks(); + } + + m_worldController.update(doTick); if (m_clock.getTicks() % 100 < 10) { for (auto &it : m_players) { diff --git a/source/server/network/ChatCommandHandler.cpp b/source/server/network/ChatCommandHandler.cpp index f17411ff0..5a37e9fc9 100644 --- a/source/server/network/ChatCommandHandler.cpp +++ b/source/server/network/ChatCommandHandler.cpp @@ -29,6 +29,7 @@ #include "ChatCommandHandler.hpp" #include "ClientInfo.hpp" +#include "GameTime.hpp" #include "ServerCommandHandler.hpp" #include "ServerConfig.hpp" #include "WorldController.hpp" @@ -113,9 +114,13 @@ void ChatCommandHandler::optionCommand(const std::vector &command, } } -void ChatCommandHandler::stopCommand(const std::vector &, ClientInfo &client) const { - m_server.sendChatMessage(0, "Stopping server...", &client); - m_server.stopServer(); +void ChatCommandHandler::stopCommand(const std::vector &command, ClientInfo &client) const { + if (command.size() > 1) + m_server.sendChatMessage(0, "Usage: /stop", &client); + else { + m_server.sendChatMessage(0, "Stopping server...", &client); + m_server.stopServer(); + } } void ChatCommandHandler::teleportationCommand(const std::vector &command, ClientInfo &client) const { @@ -140,3 +145,10 @@ void ChatCommandHandler::teleportationCommand(const std::vector &co } } +void ChatCommandHandler::tpsCommand(const std::vector &command, ClientInfo &client) const { + if (command.size() > 1) + m_server.sendChatMessage(0, "Usage: /tps", &client); + else + m_server.sendChatMessage(0, "TPS: " + std::to_string(GameTime::getTicksPerSecond()), &client); +} + diff --git a/source/server/network/ChatCommandHandler.hpp b/source/server/network/ChatCommandHandler.hpp index 7428fef76..98f56bda9 100644 --- a/source/server/network/ChatCommandHandler.hpp +++ b/source/server/network/ChatCommandHandler.hpp @@ -49,6 +49,7 @@ class ChatCommandHandler { void optionCommand(const std::vector &command, ClientInfo &client) const; void stopCommand(const std::vector &command, ClientInfo &client) const; void teleportationCommand(const std::vector &command, ClientInfo &client) const; + void tpsCommand(const std::vector &command, ClientInfo &client) const; ServerCommandHandler &m_server; WorldController &m_worldController; @@ -58,6 +59,7 @@ class ChatCommandHandler { {"option", &ChatCommandHandler::optionCommand}, {"stop", &ChatCommandHandler::stopCommand}, {"tp", &ChatCommandHandler::teleportationCommand}, + {"tps", &ChatCommandHandler::tpsCommand}, }; }; diff --git a/source/server/world/ServerWorld.cpp b/source/server/world/ServerWorld.cpp index 26f325bc3..f3253170f 100644 --- a/source/server/world/ServerWorld.cpp +++ b/source/server/world/ServerWorld.cpp @@ -36,28 +36,26 @@ #include "ServerPlayer.hpp" #include "ServerWorld.hpp" -void ServerWorld::update() { - if (m_lastTick < m_clock.getTicks() / 50) { - m_lastTick = m_clock.getTicks() / 50; - - for (auto &it : m_chunks) { +void ServerWorld::update(bool doTick) { + for (auto &it : m_chunks) { + if (doTick) it.second->tick(*this, *m_server); - if (it.second->areAllNeighboursLoaded()) { - it.second->updateLights(); - } + if (it.second->areAllNeighboursLoaded()) { + it.second->updateLights(); + } - if (it.second->isInitialized() && !it.second->isSent()) { - for (auto &client : m_server->server().info().clients()) - if (m_players.getPlayer(client.playerName)->dimension() == m_dimension.id()) - sendChunkData(client, *it.second.get()); + if (it.second->isInitialized() && !it.second->isSent()) { + for (auto &client : m_server->server().info().clients()) + if (m_players.getPlayer(client.playerName)->dimension() == m_dimension.id()) + sendChunkData(client, *it.second.get()); - // gkDebug() << "Chunk updated at" << it.second->x() << it.second->y() << it.second->z(); - } + // gkDebug() << "Chunk updated at" << it.second->x() << it.second->y() << it.second->z(); } } - m_scene.update(); + if (doTick) + m_scene.update(); } void ServerWorld::createChunkNeighbours(ServerChunk &chunk) { diff --git a/source/server/world/ServerWorld.hpp b/source/server/world/ServerWorld.hpp index 8e9735dd3..0191963d5 100644 --- a/source/server/world/ServerWorld.hpp +++ b/source/server/world/ServerWorld.hpp @@ -51,7 +51,7 @@ class ServerWorld : public World { ServerWorld(PlayerList &players, const Dimension &dimension, gk::GameClock &clock) : m_players(players), m_dimension(dimension), m_terrainGenerator(dimension), m_clock(clock), m_scene(players) {} - void update(); + void update(bool doTick); void createChunkNeighbours(ServerChunk &chunk); void sendChunkData(const ClientInfo &client, ServerChunk &chunk); @@ -80,8 +80,6 @@ class ServerWorld : public World { ChunkMap m_chunks; - u32 m_lastTick = 0; - TerrainGenerator m_terrainGenerator; ServerCommandHandler *m_server = nullptr; diff --git a/source/server/world/WorldController.cpp b/source/server/world/WorldController.cpp index 6ac2fff38..1c5869984 100644 --- a/source/server/world/WorldController.cpp +++ b/source/server/world/WorldController.cpp @@ -42,9 +42,9 @@ void WorldController::clearEntities() { it.scene().clear(); } -void WorldController::update() { +void WorldController::update(bool doTick) { for (auto &it : m_worldList) - it.update(); + it.update(doTick); } ServerWorld &WorldController::getWorld(u16 dimension) { diff --git a/source/server/world/WorldController.hpp b/source/server/world/WorldController.hpp index 08d55e2b7..1d6977d31 100644 --- a/source/server/world/WorldController.hpp +++ b/source/server/world/WorldController.hpp @@ -47,7 +47,7 @@ class WorldController { void clearEntities(); - void update(); + void update(bool doTick); void load(const std::string &worldName) { m_worldSaveBackend->load(worldName); } void save(const std::string &worldName) { m_worldSaveBackend->save(worldName); } From 7ddf58fbe4f024b0fd30bbbfe0fb3aa559bc323f Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 01:37:29 +0200 Subject: [PATCH 14/25] [GameTime] 'getCurrentTime' now uses the new tick system. [DebugOverlay] Added client TPS info. [Network] Packet 'ServerTick' added. Sent at the beginning of every tick. --- docs/network-protocol.md | 6 +++ source/client/graphics/Skybox.cpp | 5 +- source/client/hud/DebugOverlay.cpp | 3 ++ .../client/network/ClientCommandHandler.cpp | 6 +++ source/common/core/GameTime.cpp | 2 +- source/common/core/GameTime.hpp | 1 + source/common/network/Network.cpp | 1 + source/common/network/Network.hpp | 53 ++++++++++--------- source/server/core/ServerApplication.cpp | 2 + .../server/network/ServerCommandHandler.cpp | 10 ++++ .../server/network/ServerCommandHandler.hpp | 1 + 11 files changed, 60 insertions(+), 30 deletions(-) diff --git a/docs/network-protocol.md b/docs/network-protocol.md index d38d77d68..2cc3ca790 100644 --- a/docs/network-protocol.md +++ b/docs/network-protocol.md @@ -47,6 +47,12 @@ _This packet has no field._ ### Clientbound +#### ServerTick + +Packet sent at the beginning of every server tick. + +_This packet has no field._ + #### ServerClosed | Field name | Field type | Notes | diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 15d565fd4..b38cdca1f 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -49,9 +49,8 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor auto &star = m_stars.emplace_back(); star.setColor(gk::Color{0, 0, 0, 0}); star.setSize(5, 5); - star.setPosition(700 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); - star.setRotationOffset(rand() % 360); - star.setRotationSpeed(0.4f); + star.setPosition(600 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); + star.setRotationOffset(rand() % GameTime::dayLength); star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); } } diff --git a/source/client/hud/DebugOverlay.cpp b/source/client/hud/DebugOverlay.cpp index 1c67a9c41..6fc101784 100644 --- a/source/client/hud/DebugOverlay.cpp +++ b/source/client/hud/DebugOverlay.cpp @@ -33,6 +33,7 @@ #include "ClientWorld.hpp" #include "Config.hpp" #include "DebugOverlay.hpp" +#include "GameTime.hpp" DebugOverlay::DebugOverlay(const ClientPlayer &player, const ClientWorld &world) : m_player(player), m_world(world) @@ -84,6 +85,8 @@ void DebugOverlay::update() { stream << "Alive entities: " << m_world.scene().registry().alive(); stream << '\n'; stream << "Chunk updates: " << ClientChunk::chunkUpdatesPerSec; + stream << '\n'; + stream << "TPS: " << GameTime::getTicksPerSecond(); m_positionText.setString(stream.str()); } diff --git a/source/client/network/ClientCommandHandler.cpp b/source/client/network/ClientCommandHandler.cpp index 1ee3a4646..303d6599e 100644 --- a/source/client/network/ClientCommandHandler.cpp +++ b/source/client/network/ClientCommandHandler.cpp @@ -37,6 +37,7 @@ #include "ConnectionErrorState.hpp" #include "DrawableComponent.hpp" #include "DrawableDef.hpp" +#include "GameTime.hpp" #include "LuaGUIState.hpp" #include "NetworkComponent.hpp" #include "PositionComponent.hpp" @@ -167,6 +168,11 @@ void ClientCommandHandler::setupCallbacks() { } }); + m_client.setCommandCallback(Network::Command::ServerTick, [this](Network::Packet &) { + if (!m_isSingleplayer) // FIXME + GameTime::incrementTicks(); + }); + m_client.setCommandCallback(Network::Command::ServerClosed, [this](Network::Packet &packet) { std::string message; packet >> message; diff --git a/source/common/core/GameTime.cpp b/source/common/core/GameTime.cpp index 90b3bde61..bb336cbc7 100644 --- a/source/common/core/GameTime.cpp +++ b/source/common/core/GameTime.cpp @@ -35,7 +35,7 @@ u64 GameTime::s_ticks = 0; u16 GameTime::s_ticksPerSecond = 0; float GameTime::getCurrentTime(float offset, float speed) { - return std::fmod(gk::GameClock::getInstance().getTicks() * daySpeed * speed / 1000.f + offset, 360.f) / 360.f; + return std::fmod(s_ticks * daySpeed * speed + offset, dayLength) / dayLength; } float GameTime::getSunlightIntensityFromTime(float time) { diff --git a/source/common/core/GameTime.hpp b/source/common/core/GameTime.hpp index 230ed1c15..5f5f0e465 100644 --- a/source/common/core/GameTime.hpp +++ b/source/common/core/GameTime.hpp @@ -34,6 +34,7 @@ class Sky; class GameTime { public: static constexpr float daySpeed = 1.f; + static constexpr u32 dayLength = 24000; // Note: These functions are only needed in the client static float getCurrentTime(float offset = 0.f, float speed = 1.f); diff --git a/source/common/network/Network.cpp b/source/common/network/Network.cpp index d89f91007..9f1c8384e 100644 --- a/source/common/network/Network.cpp +++ b/source/common/network/Network.cpp @@ -37,6 +37,7 @@ std::string Network::commandToString(Network::Command command) { {Network::Command::ClientOk, "ClientOk"}, {Network::Command::ClientRefused, "ClientRefused"}, + {Network::Command::ServerTick, "ServerTick"}, {Network::Command::ServerClosed, "ServerClosed"}, {Network::Command::ChunkData, "ChunkData"}, diff --git a/source/common/network/Network.hpp b/source/common/network/Network.hpp index 9a883effb..ed8b3ff04 100644 --- a/source/common/network/Network.hpp +++ b/source/common/network/Network.hpp @@ -40,40 +40,41 @@ namespace Network { ClientOk = 0x02, ClientRefused = 0x03, - ServerClosed = 0x04, + ServerTick = 0x04, + ServerClosed = 0x05, - ChunkData = 0x05, - ChunkRequest = 0x06, + ChunkData = 0x06, + ChunkRequest = 0x07, - PlayerPlaceBlock = 0x07, - PlayerDigBlock = 0x08, - PlayerInvUpdate = 0x09, - PlayerPosUpdate = 0x0a, - PlayerRotUpdate = 0x0b, - PlayerSpawn = 0x0c, - PlayerChangeDimension = 0x0d, - PlayerHeldItemChanged = 0x0e, + PlayerPlaceBlock = 0x08, + PlayerDigBlock = 0x09, + PlayerInvUpdate = 0x0a, + PlayerPosUpdate = 0x0b, + PlayerRotUpdate = 0x0c, + PlayerSpawn = 0x0d, + PlayerChangeDimension = 0x0e, + PlayerHeldItemChanged = 0x0f, - BlockUpdate = 0x0f, - BlockActivated = 0x10, - BlockGUIData = 0x11, - BlockInvUpdate = 0x12, - BlockDataUpdate = 0x13, + BlockUpdate = 0x10, + BlockActivated = 0x11, + BlockGUIData = 0x12, + BlockInvUpdate = 0x13, + BlockDataUpdate = 0x14, - ItemActivated = 0x14, + ItemActivated = 0x15, - RegistryData = 0x15, + RegistryData = 0x16, - ChatMessage = 0x16, + ChatMessage = 0x17, - EntitySpawn = 0x17, - EntityDespawn = 0x18, - EntityPosition = 0x19, - EntityRotation = 0x1a, - EntityAnimation = 0x1b, - EntityDrawableDef = 0x1c, + EntitySpawn = 0x18, + EntityDespawn = 0x19, + EntityPosition = 0x1a, + EntityRotation = 0x1b, + EntityAnimation = 0x1c, + EntityDrawableDef = 0x1d, - KeyPressed = 0x1d, + KeyPressed = 0x1e, }; std::string commandToString(Command command); diff --git a/source/server/core/ServerApplication.cpp b/source/server/core/ServerApplication.cpp index 390ea4070..9bcc11778 100644 --- a/source/server/core/ServerApplication.cpp +++ b/source/server/core/ServerApplication.cpp @@ -201,6 +201,8 @@ void ServerApplication::update() { doTick = true; GameTime::incrementTicks(); + + m_serverCommandHandler.sendServerTick(); } m_worldController.update(doTick); diff --git a/source/server/network/ServerCommandHandler.cpp b/source/server/network/ServerCommandHandler.cpp index b7ef936cb..cc6e48388 100644 --- a/source/server/network/ServerCommandHandler.cpp +++ b/source/server/network/ServerCommandHandler.cpp @@ -37,6 +37,16 @@ #include "ServerItem.hpp" #include "WorldController.hpp" +void ServerCommandHandler::sendServerTick(const ClientInfo *client) const { + Network::Packet packet; + packet << Network::Command::ServerTick; + + if (!client) + m_server.sendToAllClients(packet); + else + client->tcpSocket->send(packet); +} + void ServerCommandHandler::sendServerClosed(const std::string &message, const ClientInfo *client) const { Network::Packet packet; packet << Network::Command::ServerClosed << message; diff --git a/source/server/network/ServerCommandHandler.hpp b/source/server/network/ServerCommandHandler.hpp index b40d05b2b..3238e4698 100644 --- a/source/server/network/ServerCommandHandler.hpp +++ b/source/server/network/ServerCommandHandler.hpp @@ -61,6 +61,7 @@ class ServerCommandHandler { ServerCommandHandler(ScriptEngine &scriptEngine, Server &server, WorldController &worldController, PlayerList &players, Registry ®istry) : m_scriptEngine(scriptEngine), m_server(server), m_worldController(worldController), m_players(players), m_registry(registry) {} + void sendServerTick(const ClientInfo *client = nullptr) const; void sendServerClosed(const std::string &message, const ClientInfo *client = nullptr) const; void sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockData *blockData, const ClientInfo *client = nullptr) const; void sendBlockInvUpdate(s32 x, s32 y, s32 z, const Inventory &inventory, const ClientInfo *client = nullptr) const; From ad84470befb91a97380e58b68031aad867976082 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 02:26:37 +0200 Subject: [PATCH 15/25] [DebugInfoWidget] Added 'Ticks' and 'Game time'. [GameTime] The day now starts at 6 AM. --- docs/network-protocol.md | 4 +++- source/client/hud/DebugOverlay.cpp | 9 +++++++++ source/client/network/ClientCommandHandler.cpp | 9 ++++++--- source/common/core/GameTime.cpp | 10 +++++----- source/common/core/GameTime.hpp | 18 +++++++++++++++--- source/server/network/ServerCommandHandler.cpp | 3 ++- 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/docs/network-protocol.md b/docs/network-protocol.md index 2cc3ca790..cd2abfa5a 100644 --- a/docs/network-protocol.md +++ b/docs/network-protocol.md @@ -51,7 +51,9 @@ _This packet has no field._ Packet sent at the beginning of every server tick. -_This packet has no field._ +| Field name | Field type | Notes | +| ------------- | ----------- | ---------------------------------------------------- | +| Current time | u64 | Current time in the server | #### ServerClosed diff --git a/source/client/hud/DebugOverlay.cpp b/source/client/hud/DebugOverlay.cpp index 6fc101784..9e31cd5dc 100644 --- a/source/client/hud/DebugOverlay.cpp +++ b/source/client/hud/DebugOverlay.cpp @@ -86,7 +86,16 @@ void DebugOverlay::update() { stream << '\n'; stream << "Chunk updates: " << ClientChunk::chunkUpdatesPerSec; stream << '\n'; + stream << "Ticks: " << GameTime::getTicks(); + stream << '\n'; stream << "TPS: " << GameTime::getTicksPerSecond(); + stream << '\n'; + stream << "Game time: "; + + u16 hour = GameTime::getCurrentHour(); + u16 minute = GameTime::getCurrentMinute(); + stream << (hour < 10 ? "0" : "") << hour << ":"; + stream << (minute < 10 ? "0" : "") << minute; m_positionText.setString(stream.str()); } diff --git a/source/client/network/ClientCommandHandler.cpp b/source/client/network/ClientCommandHandler.cpp index 303d6599e..794224a04 100644 --- a/source/client/network/ClientCommandHandler.cpp +++ b/source/client/network/ClientCommandHandler.cpp @@ -168,9 +168,12 @@ void ClientCommandHandler::setupCallbacks() { } }); - m_client.setCommandCallback(Network::Command::ServerTick, [this](Network::Packet &) { - if (!m_isSingleplayer) // FIXME - GameTime::incrementTicks(); + m_client.setCommandCallback(Network::Command::ServerTick, [this](Network::Packet &packet) { + if (!m_isSingleplayer) { // FIXME + sf::Uint64 ticks; + packet >> ticks; + GameTime::setTicks(ticks); + } }); m_client.setCommandCallback(Network::Command::ServerClosed, [this](Network::Packet &packet) { diff --git a/source/common/core/GameTime.cpp b/source/common/core/GameTime.cpp index bb336cbc7..969fcf6d9 100644 --- a/source/common/core/GameTime.cpp +++ b/source/common/core/GameTime.cpp @@ -35,7 +35,7 @@ u64 GameTime::s_ticks = 0; u16 GameTime::s_ticksPerSecond = 0; float GameTime::getCurrentTime(float offset, float speed) { - return std::fmod(s_ticks * daySpeed * speed + offset, dayLength) / dayLength; + return std::fmod((s_ticks + dayStartOffset) * daySpeed * speed + offset, dayLength) / dayLength; } float GameTime::getSunlightIntensityFromTime(float time) { @@ -58,6 +58,10 @@ gk::Color GameTime::getSkyColorFromTime(const Sky &sky, float time) { void GameTime::incrementTicks() { ++s_ticks; + updateTpsCounter(); +} + +void GameTime::updateTpsCounter() { static u64 tpsTimer = gk::GameClock::getInstance().getTicks(true); static u8 tpsCount = 0; @@ -71,7 +75,3 @@ void GameTime::incrementTicks() { } } -u16 GameTime::getTicksPerSecond() { - return s_ticksPerSecond; -} - diff --git a/source/common/core/GameTime.hpp b/source/common/core/GameTime.hpp index 5f5f0e465..8db896c90 100644 --- a/source/common/core/GameTime.hpp +++ b/source/common/core/GameTime.hpp @@ -35,18 +35,30 @@ class GameTime { public: static constexpr float daySpeed = 1.f; static constexpr u32 dayLength = 24000; + static constexpr u32 dayStartOffset = 3000; - // Note: These functions are only needed in the client + // Note: These 3 functions are only needed in the client static float getCurrentTime(float offset = 0.f, float speed = 1.f); static float getSunlightIntensityFromTime(float time); static gk::Color getSkyColorFromTime(const Sky &sky, float time); - // Note: These functions are only needed in the server static void incrementTicks(); - static u16 getTicksPerSecond(); + static void setTicks(u64 ticks) { s_ticks = ticks; } + + static u16 getTicksPerSecond() { return s_ticksPerSecond; } static u64 getTicks() { return s_ticks; } + static u8 getCurrentHour() { + return u64((s_ticks + dayStartOffset + 3000.f) / 1000.f) % 24; + } + + static u8 getCurrentMinute() { + return u64((s_ticks + dayStartOffset + 3000.f) / 1000.f * 60.0f) % 60; + } + private: + static void updateTpsCounter(); + static u64 s_ticks; static u16 s_ticksPerSecond; }; diff --git a/source/server/network/ServerCommandHandler.cpp b/source/server/network/ServerCommandHandler.cpp index cc6e48388..bbbd57510 100644 --- a/source/server/network/ServerCommandHandler.cpp +++ b/source/server/network/ServerCommandHandler.cpp @@ -27,6 +27,7 @@ #include "AnimationComponent.hpp" #include "BlockData.hpp" #include "DrawableDef.hpp" +#include "GameTime.hpp" #include "NetworkComponent.hpp" #include "PlayerList.hpp" #include "Registry.hpp" @@ -39,7 +40,7 @@ void ServerCommandHandler::sendServerTick(const ClientInfo *client) const { Network::Packet packet; - packet << Network::Command::ServerTick; + packet << Network::Command::ServerTick << (sf::Uint64)GameTime::getTicks(); if (!client) m_server.sendToAllClients(packet); From 6629d3cca4ab0040ce7d861671881914a95e782e Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 03:28:55 +0200 Subject: [PATCH 16/25] [ChatCommandHandler] '/time ' command added. [CelestialObject|Skybox] Moon changes its phase everyday. --- source/client/graphics/CelestialObject.cpp | 4 +- source/client/graphics/CelestialObject.hpp | 4 +- source/client/graphics/Skybox.cpp | 2 + source/client/hud/DebugOverlay.cpp | 2 + source/common/core/GameTime.cpp | 17 +++---- source/common/core/GameTime.hpp | 8 +++- source/server/network/ChatCommandHandler.cpp | 48 +++++++++++++++++++- source/server/network/ChatCommandHandler.hpp | 6 ++- 8 files changed, 71 insertions(+), 20 deletions(-) diff --git a/source/client/graphics/CelestialObject.cpp b/source/client/graphics/CelestialObject.cpp index d639d8fcd..dc5d8e865 100644 --- a/source/client/graphics/CelestialObject.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -69,8 +69,8 @@ void CelestialObject::updateVertexBuffer() const { if (m_phaseCount && m_phaseSize && m_currentPhase < m_phaseCount) { u16 currentPhaseX = m_currentPhase % (m_texture->getSize().x / m_phaseSize); u16 currentPhaseY = m_currentPhase / (m_texture->getSize().x / m_phaseSize); - texRect.x = currentPhaseX / float(m_texture->getSize().x); - texRect.y = currentPhaseY / float(m_texture->getSize().y); + texRect.x = currentPhaseX * m_phaseSize / float(m_texture->getSize().x); + texRect.y = currentPhaseY * m_phaseSize / float(m_texture->getSize().y); texRect.sizeX = m_phaseSize / float(m_texture->getSize().x); texRect.sizeY = m_phaseSize / float(m_texture->getSize().y); } diff --git a/source/client/graphics/CelestialObject.hpp b/source/client/graphics/CelestialObject.hpp index b2fccf766..fa1c90f97 100644 --- a/source/client/graphics/CelestialObject.hpp +++ b/source/client/graphics/CelestialObject.hpp @@ -43,7 +43,7 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { void setSize(float width, float height) { m_width = width; m_height = height; m_isUpdateNeeded = true; } void setTexture(const std::string &textureName); void setPhaseCount(u16 phaseCount, u16 phaseSize) { m_phaseCount = phaseCount; m_phaseSize = phaseSize; m_isUpdateNeeded = true; } - void setCurrentPhase(u16 currentPhase) { m_currentPhase = currentPhase; m_isUpdateNeeded = true; } + void setCurrentPhase(u16 currentPhase) const { if (m_currentPhase != currentPhase) { m_currentPhase = currentPhase; m_isUpdateNeeded = true; } } void setRotationOffset(u16 rotationOffset) { m_rotationOffset = rotationOffset; } void setRotationSpeed(float rotationSpeed) { m_rotationSpeed = rotationSpeed; } void setRotationAxis(const gk::Vector3f &rotationAxis) { m_rotationAxis = rotationAxis; } @@ -66,7 +66,7 @@ class CelestialObject : public gk::Drawable, public gk::Transformable { u16 m_phaseCount = 0; u16 m_phaseSize = 0; - u16 m_currentPhase = 0; + mutable u16 m_currentPhase = 0; u16 m_rotationOffset = 0; float m_rotationSpeed = 1.f; diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index b38cdca1f..998350997 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -63,6 +63,8 @@ void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { gk::Shader::bind(nullptr); } + m_moon.setCurrentPhase((GameTime::getTicks() / 24000) % 8); + states.shader = &m_shader; // Subtract the camera position - see comment in ClientWorld::draw() diff --git a/source/client/hud/DebugOverlay.cpp b/source/client/hud/DebugOverlay.cpp index 9e31cd5dc..15ef4b30a 100644 --- a/source/client/hud/DebugOverlay.cpp +++ b/source/client/hud/DebugOverlay.cpp @@ -92,8 +92,10 @@ void DebugOverlay::update() { stream << '\n'; stream << "Game time: "; + u32 day = GameTime::getCurrentDay(); u16 hour = GameTime::getCurrentHour(); u16 minute = GameTime::getCurrentMinute(); + stream << "Day " << day << " "; stream << (hour < 10 ? "0" : "") << hour << ":"; stream << (minute < 10 ? "0" : "") << minute; diff --git a/source/common/core/GameTime.cpp b/source/common/core/GameTime.cpp index 969fcf6d9..ce5749de6 100644 --- a/source/common/core/GameTime.cpp +++ b/source/common/core/GameTime.cpp @@ -55,23 +55,18 @@ gk::Color GameTime::getSkyColorFromTime(const Sky &sky, float time) { return skyColor; } -void GameTime::incrementTicks() { - ++s_ticks; - - updateTpsCounter(); -} - void GameTime::updateTpsCounter() { static u64 tpsTimer = gk::GameClock::getInstance().getTicks(true); - static u8 tpsCount = 0; + static u64 tpsStart = s_ticks; - u64 currentClockTicks = gk::GameClock::getInstance().getTicks(true); - ++tpsCount; + if (tpsStart > s_ticks) + tpsStart = s_ticks; + u64 currentClockTicks = gk::GameClock::getInstance().getTicks(true); if (currentClockTicks - tpsTimer > 1000) { - s_ticksPerSecond = floor(tpsCount / ((currentClockTicks - tpsTimer) / 1000.0f) + 0.5f); + s_ticksPerSecond = floor((s_ticks - tpsStart) / ((currentClockTicks - tpsTimer) / 1000.0f) + 0.5f); tpsTimer = currentClockTicks; - tpsCount = 0; + tpsStart = s_ticks; } } diff --git a/source/common/core/GameTime.hpp b/source/common/core/GameTime.hpp index 8db896c90..f9139ceeb 100644 --- a/source/common/core/GameTime.hpp +++ b/source/common/core/GameTime.hpp @@ -42,12 +42,16 @@ class GameTime { static float getSunlightIntensityFromTime(float time); static gk::Color getSkyColorFromTime(const Sky &sky, float time); - static void incrementTicks(); - static void setTicks(u64 ticks) { s_ticks = ticks; } + static void incrementTicks() { ++s_ticks; updateTpsCounter(); } + static void setTicks(u64 ticks) { s_ticks = ticks; updateTpsCounter(); } static u16 getTicksPerSecond() { return s_ticksPerSecond; } static u64 getTicks() { return s_ticks; } + static u32 getCurrentDay() { + return (s_ticks + dayStartOffset + 3000.f) / 1000.f / 24 + 1; + } + static u8 getCurrentHour() { return u64((s_ticks + dayStartOffset + 3000.f) / 1000.f) % 24; } diff --git a/source/server/network/ChatCommandHandler.cpp b/source/server/network/ChatCommandHandler.cpp index 5a37e9fc9..72471593c 100644 --- a/source/server/network/ChatCommandHandler.cpp +++ b/source/server/network/ChatCommandHandler.cpp @@ -123,7 +123,53 @@ void ChatCommandHandler::stopCommand(const std::vector &command, Cl } } -void ChatCommandHandler::teleportationCommand(const std::vector &command, ClientInfo &client) const { +void ChatCommandHandler::timeCommand(const std::vector &command, ClientInfo &client) const { + if (command.size() != 3 || (command.at(1) != "set" && command.at(1) != "add")) { + m_server.sendChatMessage(0, "Usage: /time ", &client); + } + else if (command.at(1) == "set") { + static const std::unordered_map values = { + {"day", 1000}, + {"noon", 6000}, + {"sunset", 12000}, + {"night", 13000}, + {"midnight", 18000}, + {"sunrise", 23000}, + }; + + if (auto it = values.find(command.at(2)) ; it != values.end()) { + GameTime::setTicks(it->second); + + m_server.sendChatMessage(0, "Time set to " + std::to_string(it->second), &client); + } + else { + try { + u64 ticks = std::stoull(command.at(2)); + + GameTime::setTicks(ticks); + + m_server.sendChatMessage(0, "Time set to " + std::to_string(ticks), &client); + } + catch (std::out_of_range &e) { + m_server.sendChatMessage(0, "Invalid time", &client); + } + } + } + else if (command.at(1) == "add") { + try { + u64 ticks = std::stoull(command.at(2)); + + GameTime::setTicks(GameTime::getTicks() + ticks); + + m_server.sendChatMessage(0, "Added " + std::to_string(ticks) + " to the time", &client); + } + catch (std::out_of_range &e) { + m_server.sendChatMessage(0, "Invalid time", &client); + } + } +} + +void ChatCommandHandler::tpCommand(const std::vector &command, ClientInfo &client) const { if (command.size() != 4) { m_server.sendChatMessage(0, "Usage: /tp x y z", &client); } diff --git a/source/server/network/ChatCommandHandler.hpp b/source/server/network/ChatCommandHandler.hpp index 98f56bda9..023095c85 100644 --- a/source/server/network/ChatCommandHandler.hpp +++ b/source/server/network/ChatCommandHandler.hpp @@ -48,7 +48,8 @@ class ChatCommandHandler { void helpCommand(const std::vector &command, ClientInfo &client) const; void optionCommand(const std::vector &command, ClientInfo &client) const; void stopCommand(const std::vector &command, ClientInfo &client) const; - void teleportationCommand(const std::vector &command, ClientInfo &client) const; + void timeCommand(const std::vector &command, ClientInfo &client) const; + void tpCommand(const std::vector &command, ClientInfo &client) const; void tpsCommand(const std::vector &command, ClientInfo &client) const; ServerCommandHandler &m_server; @@ -58,7 +59,8 @@ class ChatCommandHandler { {"help", &ChatCommandHandler::helpCommand}, {"option", &ChatCommandHandler::optionCommand}, {"stop", &ChatCommandHandler::stopCommand}, - {"tp", &ChatCommandHandler::teleportationCommand}, + {"time", &ChatCommandHandler::timeCommand}, + {"tp", &ChatCommandHandler::tpCommand}, {"tps", &ChatCommandHandler::tpsCommand}, }; }; From dc3107a1f3985cb95b41528b7ed43b0adbf58a02 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 03:33:58 +0200 Subject: [PATCH 17/25] [WorldSaveBasicBackend] Now saving game time. --- source/server/world/save/WorldSaveBasicBackend.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/server/world/save/WorldSaveBasicBackend.cpp b/source/server/world/save/WorldSaveBasicBackend.cpp index 12e77c2c2..878b8cce6 100644 --- a/source/server/world/save/WorldSaveBasicBackend.cpp +++ b/source/server/world/save/WorldSaveBasicBackend.cpp @@ -31,6 +31,7 @@ #include #include "ComponentType.hpp" +#include "GameTime.hpp" #include "Network.hpp" #include "NetworkComponent.hpp" #include "Registry.hpp" @@ -112,6 +113,10 @@ void WorldSaveBasicBackend::load(const std::string &name) { auto &player = m_playerList.addPlayer(username, false); player.deserialize(save); } + + sf::Uint64 ticks; + save >> ticks; + GameTime::setTicks(ticks); } // gkInfo() << "Loading done."; @@ -168,6 +173,8 @@ void WorldSaveBasicBackend::save(const std::string &name) { save << it.second; } + save << (sf::Uint64)GameTime::getTicks(); + file.write((const char *)save.getData(), save.getDataSize()); // gkInfo() << "Saving done."; From accd1e52fecb87ef8b1d0ca76e9c0d5493bfd58f Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 03:50:48 +0200 Subject: [PATCH 18/25] [Config] Added option to disable star rendering. --- source/client/core/Config.cpp | 3 +++ source/client/core/Config.hpp | 1 + source/client/graphics/Skybox.cpp | 25 +++++++++++++--------- source/client/states/SettingsMenuState.cpp | 2 ++ 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/source/client/core/Config.cpp b/source/client/core/Config.cpp index 5cee9dd71..0147f72b4 100644 --- a/source/client/core/Config.cpp +++ b/source/client/core/Config.cpp @@ -55,6 +55,7 @@ bool Config::isSmoothLightingEnabled = true; bool Config::isWireframeModeEnabled = false; bool Config::isFullscreenModeEnabled = false; bool Config::isVerticalSyncEnabled = true; +bool Config::isStarRenderingEnabled = true; float Config::cameraFOV = 70.0f; u16 Config::screenWidth = 1600; u16 Config::screenHeight = 1050; @@ -95,6 +96,7 @@ void Config::loadConfigFromFile(const char *filename) { isWireframeModeEnabled = lua["isWireframeModeEnabled"].get_or(isWireframeModeEnabled); isFullscreenModeEnabled = lua["isFullscreenModeEnabled"].get_or(isFullscreenModeEnabled); isVerticalSyncEnabled = lua["isVerticalSyncEnabled"].get_or(isVerticalSyncEnabled); + isStarRenderingEnabled = lua["isStarRenderingEnabled"].get_or(isStarRenderingEnabled); cameraFOV = lua["cameraFOV"].get_or(cameraFOV); screenWidth = lua["screenWidth"].get_or(screenWidth); screenHeight = lua["screenHeight"].get_or(screenHeight); @@ -131,6 +133,7 @@ void Config::saveConfigToFile(const char *filename) { file << "isWireframeModeEnabled = " << (isWireframeModeEnabled ? "true" : "false") << std::endl; file << "isFullscreenModeEnabled = " << (isFullscreenModeEnabled ? "true" : "false") << std::endl; file << "isVerticalSyncEnabled = " << (isVerticalSyncEnabled ? "true" : "false") << std::endl; + file << "isStarRenderingEnabled = " << (isStarRenderingEnabled ? "true" : "false") << std::endl; file << "cameraFOV = " << cameraFOV << std::endl; file << "screenWidth = " << screenWidth << std::endl; file << "screenHeight = " << screenHeight << std::endl; diff --git a/source/client/core/Config.hpp b/source/client/core/Config.hpp index 2121196e3..3ce6aa17b 100644 --- a/source/client/core/Config.hpp +++ b/source/client/core/Config.hpp @@ -50,6 +50,7 @@ namespace Config { extern bool isWireframeModeEnabled; extern bool isFullscreenModeEnabled; extern bool isVerticalSyncEnabled; + extern bool isStarRenderingEnabled; extern float cameraFOV; extern u16 screenWidth; extern u16 screenHeight; diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 998350997..1e5331614 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -56,14 +56,17 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { - if (m_world.sky()) { - gk::Shader::bind(&m_shader); - 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); - } + if (!m_world.sky()) return; + + gk::Color skyColor = GameTime::getSkyColorFromTime(*m_world.sky(), GameTime::getCurrentTime()); + gk::Color starColor = m_world.sky()->color(); - m_moon.setCurrentPhase((GameTime::getTicks() / 24000) % 8); + gk::Shader::bind(&m_shader); + m_shader.setUniform("u_skyColor", skyColor); + m_shader.setUniform("u_starColor", starColor); + gk::Shader::bind(nullptr); + + m_moon.setCurrentPhase((GameTime::getTicks() / GameTime::dayLength) % 8); states.shader = &m_shader; @@ -74,9 +77,11 @@ void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { target.draw(m_sun, states); target.draw(m_moon, states); - glDisable(GL_CULL_FACE); + if (Config::isStarRenderingEnabled && skyColor != starColor) { + glDisable(GL_CULL_FACE); - for (auto &it : m_stars) - target.draw(it, states); + for (auto &it : m_stars) + target.draw(it, states); + } } diff --git a/source/client/states/SettingsMenuState.cpp b/source/client/states/SettingsMenuState.cpp index f226d8d17..887ea6cd4 100644 --- a/source/client/states/SettingsMenuState.cpp +++ b/source/client/states/SettingsMenuState.cpp @@ -267,6 +267,8 @@ void SettingsMenuState::addGraphicsButtons() { slider.setText("Mipmap Levels: " + std::to_string(Config::mipmapLevels)); }, 0, 4, Config::mipmapLevels); + addToggleButton("Star Rendering", Config::isStarRenderingEnabled, false); + updateWidgetPosition(); } From 5dd33ce68cd7d3063d2d5c6ac778b91bab0880dc Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 04:19:04 +0200 Subject: [PATCH 19/25] Small fixes. --- source/client/graphics/Skybox.cpp | 8 ++++---- source/common/core/GameTime.hpp | 8 ++++---- source/server/network/ChatCommandHandler.cpp | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 1e5331614..590d57690 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -35,11 +35,11 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/skybox.f.glsl"); m_shader.linkProgram(); - m_sun.setSize(200, 200); + m_sun.setSize(256, 256); m_sun.setPosition(500, -m_sun.width() / 2, -m_sun.height() / 2); m_sun.setTexture("texture-sun"); - m_moon.setSize(200, 200); + m_moon.setSize(256, 256); m_moon.setPosition(-500, -m_moon.width() / 2, -m_moon.height() / 2); m_moon.setTexture("texture-moon_phases"); m_moon.setPhaseCount(8, 32); @@ -48,8 +48,8 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor for (int i = 0 ; i < 1000 ; ++i) { auto &star = m_stars.emplace_back(); star.setColor(gk::Color{0, 0, 0, 0}); - star.setSize(5, 5); - star.setPosition(600 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); + star.setSize(4, 4); + star.setPosition(650 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); star.setRotationOffset(rand() % GameTime::dayLength); star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); } diff --git a/source/common/core/GameTime.hpp b/source/common/core/GameTime.hpp index f9139ceeb..01178c9da 100644 --- a/source/common/core/GameTime.hpp +++ b/source/common/core/GameTime.hpp @@ -35,7 +35,7 @@ class GameTime { public: static constexpr float daySpeed = 1.f; static constexpr u32 dayLength = 24000; - static constexpr u32 dayStartOffset = 3000; + static constexpr u32 dayStartOffset = 0; // Note: These 3 functions are only needed in the client static float getCurrentTime(float offset = 0.f, float speed = 1.f); @@ -49,15 +49,15 @@ class GameTime { static u64 getTicks() { return s_ticks; } static u32 getCurrentDay() { - return (s_ticks + dayStartOffset + 3000.f) / 1000.f / 24 + 1; + return (s_ticks + dayStartOffset + 6000.f) / 1000.f / 24 + 1; } static u8 getCurrentHour() { - return u64((s_ticks + dayStartOffset + 3000.f) / 1000.f) % 24; + return u64((s_ticks + dayStartOffset + 6000.f) / 1000.f) % 24; } static u8 getCurrentMinute() { - return u64((s_ticks + dayStartOffset + 3000.f) / 1000.f * 60.0f) % 60; + return u64((s_ticks + dayStartOffset + 6000.f) / 1000.f * 60.0f) % 60; } private: diff --git a/source/server/network/ChatCommandHandler.cpp b/source/server/network/ChatCommandHandler.cpp index 72471593c..34e0ce7e6 100644 --- a/source/server/network/ChatCommandHandler.cpp +++ b/source/server/network/ChatCommandHandler.cpp @@ -131,10 +131,10 @@ void ChatCommandHandler::timeCommand(const std::vector &command, Cl static const std::unordered_map values = { {"day", 1000}, {"noon", 6000}, - {"sunset", 12000}, + {"sunset", 11000}, {"night", 13000}, {"midnight", 18000}, - {"sunrise", 23000}, + {"sunrise", 1000}, }; if (auto it = values.find(command.at(2)) ; it != values.end()) { @@ -150,7 +150,7 @@ void ChatCommandHandler::timeCommand(const std::vector &command, Cl m_server.sendChatMessage(0, "Time set to " + std::to_string(ticks), &client); } - catch (std::out_of_range &e) { + catch (...) { m_server.sendChatMessage(0, "Invalid time", &client); } } @@ -163,7 +163,7 @@ void ChatCommandHandler::timeCommand(const std::vector &command, Cl m_server.sendChatMessage(0, "Added " + std::to_string(ticks) + " to the time", &client); } - catch (std::out_of_range &e) { + catch (...) { m_server.sendChatMessage(0, "Invalid time", &client); } } @@ -185,7 +185,7 @@ void ChatCommandHandler::tpCommand(const std::vector &command, Clie m_server.sendChatMessage(0, "Teleported to " + std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z), &client); } - catch (std::out_of_range &e) { + catch (...) { m_server.sendChatMessage(0, "Invalid coordinates", &client); } } From 0f91e8571059fb651ef9f4da38a88c0cd47514f2 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 05:47:48 +0200 Subject: [PATCH 20/25] [Lua API] Added moon, sun and stars attributes in sky definition. --- docs/lua-api-sky.md | 75 ++++++++++++++++++++++ mods/default/sky.lua | 21 ++++++ source/client/graphics/CelestialObject.cpp | 2 + source/client/graphics/Skybox.cpp | 44 ++++++++++--- source/client/graphics/Skybox.hpp | 3 + source/client/states/GameState.cpp | 6 ++ source/common/world/Sky.cpp | 12 +++- source/common/world/Sky.hpp | 29 +++++++++ source/server/lua/loader/LuaSkyLoader.cpp | 44 +++++++++++++ source/server/lua/loader/LuaSkyLoader.hpp | 3 + 10 files changed, 228 insertions(+), 11 deletions(-) diff --git a/docs/lua-api-sky.md b/docs/lua-api-sky.md index 6ed6cc01f..44a489f69 100644 --- a/docs/lua-api-sky.md +++ b/docs/lua-api-sky.md @@ -13,6 +13,27 @@ mod:sky { fog_color = { day = {50, 153, 204}, }, + + objects = { + sun = { + texture = "texture-sun", + size = 256, + }, + + moon = { + texture = "texture-moon_phases", + size = 256, + phases = { + count = 8, + size = 32 + } + }, + + stars = { + count = 1000, + size = 4, + } + } } ``` @@ -59,3 +80,57 @@ id = "sky_nether" IDs are usually of the form `mod:sky` but the `mod:` prefix is prepended automatically so it's not needed. +### `objects` + +#### `moon` + +Moon attributes table. Example: +```lua +moon = { + texture = "texture-moon_phases" + size = 256, + phases = { + count = 8, + size = 32 + } +}, +``` + +Attributes: + +- `texture`: texture to use (without texture, the moon will use this color: (240, 240, 240)) +- `size`: size of the moon (default: `256`) +- `phases` + - `count`: amount of phases (default: `1`) + - `size`: size of the phase texture (default: `32`) + +#### `sun` + +Sun attribute table. Example: +```lua +sun = { + texture = "texture-sun", + size = 256, +}, +``` + +Attributes: + +- `texture`: texture to use (without texture, the sun will use this color: (255, 255, 0)) +- `size`: size of the sun (default: `256`) + +#### `stars` + +Stars attribute table. Example: +```lua +stars = { + count = 1000, + size = 4, +} +``` + +Attributes: + +- `count`: size of the sun (default: `1000`) +- `size`: size of the sun (default: `4`) + diff --git a/mods/default/sky.lua b/mods/default/sky.lua index f7726df8f..bce188ca8 100644 --- a/mods/default/sky.lua +++ b/mods/default/sky.lua @@ -35,6 +35,27 @@ mod:sky { fog_color = { day = {50, 153, 204}, }, + + objects = { + sun = { + texture = "texture-sun", -- FIXME: Use a path instead like block attribute 'tiles' + size = 256, + }, + + moon = { + texture = "texture-moon_phases", -- FIXME: ^ + size = 256, + phases = { + count = 8, + size = 32 + } + }, + + stars = { + count = 1000, + size = 4, + } + } } mod:sky { diff --git a/source/client/graphics/CelestialObject.cpp b/source/client/graphics/CelestialObject.cpp index dc5d8e865..858199dec 100644 --- a/source/client/graphics/CelestialObject.cpp +++ b/source/client/graphics/CelestialObject.cpp @@ -37,6 +37,8 @@ CelestialObject::CelestialObject() { } void CelestialObject::setTexture(const std::string &textureName) { + if (textureName.empty()) return; + m_texture = &gk::ResourceHandler::getInstance().get(textureName); m_isUpdateNeeded = true; diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 590d57690..96277f246 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -34,21 +34,44 @@ Skybox::Skybox(gk::Camera &camera, ClientWorld &world) : m_camera(camera), m_wor m_shader.addShader(GL_VERTEX_SHADER, "resources/shaders/skybox.v.glsl"); m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/skybox.f.glsl"); m_shader.linkProgram(); +} - m_sun.setSize(256, 256); +void Skybox::loadSky(const Sky &sky) { + const Sky::SunDefinition &sun = sky.sunDefinition(); + m_sun = CelestialObject{}; + m_sun.setSize(sun.size, sun.size); m_sun.setPosition(500, -m_sun.width() / 2, -m_sun.height() / 2); - m_sun.setTexture("texture-sun"); - m_moon.setSize(256, 256); + try { + m_sun.setTexture(sun.texture); + } + catch (...) { + m_sun.setColor(gk::Color::Yellow); + gkWarning() << "Failed to load sun texture" << sun.texture; + } + + const Sky::MoonDefinition &moon = sky.moonDefinition(); + m_moon = CelestialObject{}; + m_moon.setSize(moon.size, moon.size); m_moon.setPosition(-500, -m_moon.width() / 2, -m_moon.height() / 2); - m_moon.setTexture("texture-moon_phases"); - m_moon.setPhaseCount(8, 32); + m_moon.setPhaseCount(moon.phaseCount, moon.phaseSize); m_moon.setCurrentPhase(0); - for (int i = 0 ; i < 1000 ; ++i) { + try { + m_moon.setTexture(moon.texture); + } + catch (...) { + m_moon.setColor(gk::Color{240, 240, 240}); + gkWarning() << "Failed to load moon texture" << sun.texture; + } + + const Sky::StarsDefinition &stars = sky.starsDefinition(); + m_stars.clear(); + m_stars.reserve(stars.count); + for (int i = 0 ; i < stars.count ; ++i) { auto &star = m_stars.emplace_back(); star.setColor(gk::Color{0, 0, 0, 0}); - star.setSize(4, 4); + star.setSize(stars.size, stars.size); star.setPosition(650 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); star.setRotationOffset(rand() % GameTime::dayLength); star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); @@ -74,8 +97,11 @@ void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { const gk::Vector3d &cameraPosition = m_camera.getDPosition(); states.transform.translate(cameraPosition.x, cameraPosition.y, cameraPosition.z - 50); - target.draw(m_sun, states); - target.draw(m_moon, states); + if (m_sun.width() && m_sun.height()) + target.draw(m_sun, states); + + if (m_moon.width() && m_moon.height()) + target.draw(m_moon, states); if (Config::isStarRenderingEnabled && skyColor != starColor) { glDisable(GL_CULL_FACE); diff --git a/source/client/graphics/Skybox.hpp b/source/client/graphics/Skybox.hpp index 07faf28c0..f54a9f7dc 100644 --- a/source/client/graphics/Skybox.hpp +++ b/source/client/graphics/Skybox.hpp @@ -33,11 +33,14 @@ #include "CelestialObject.hpp" class ClientWorld; +class Sky; class Skybox : public gk::Drawable, public gk::Transformable { public: Skybox(gk::Camera &camera, ClientWorld &world); + void loadSky(const Sky &sky); + private: void draw(gk::RenderTarget &target, gk::RenderStates states) const override; diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index b5fcf1569..a7f4e95ca 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -184,6 +184,12 @@ void GameState::update() { } m_client.update(); + + static const Sky *sky = nullptr; + if (sky != m_world.sky() && m_world.sky()) { + sky = m_world.sky(); + m_skybox.loadSky(*sky); + } } void GameState::initShaders() { diff --git a/source/common/world/Sky.cpp b/source/common/world/Sky.cpp index 0f69ac814..9195aa9cc 100644 --- a/source/common/world/Sky.cpp +++ b/source/common/world/Sky.cpp @@ -33,10 +33,18 @@ Sky::Sky(u16 id, const std::string &stringID) { } void Sky::serialize(sf::Packet &packet) const { - packet << m_id << m_stringID << m_color << m_fogColor; + packet << m_id << m_stringID << m_color << m_fogColor + << m_sunDefinition.texture << m_sunDefinition.size + << m_moonDefinition.texture << m_moonDefinition.size + << m_moonDefinition.phaseCount << m_moonDefinition.phaseSize + << m_starsDefinition.count << m_starsDefinition.size; } void Sky::deserialize(sf::Packet &packet) { - packet >> m_id >> m_stringID >> m_color >> m_fogColor; + packet >> m_id >> m_stringID >> m_color >> m_fogColor + >> m_sunDefinition.texture >> m_sunDefinition.size + >> m_moonDefinition.texture >> m_moonDefinition.size + >> m_moonDefinition.phaseCount >> m_moonDefinition.phaseSize + >> m_starsDefinition.count >> m_starsDefinition.size; } diff --git a/source/common/world/Sky.hpp b/source/common/world/Sky.hpp index 57b1ad35e..8e73dd953 100644 --- a/source/common/world/Sky.hpp +++ b/source/common/world/Sky.hpp @@ -49,12 +49,41 @@ class Sky : public gk::ISerializable { void setColor(const gk::Color &color) { m_color = color; } void setFogColor(const gk::Color &fogColor) { m_fogColor = fogColor; } + struct SunDefinition { + std::string texture; + float size; + }; + + struct MoonDefinition { + std::string texture; + float size; + u16 phaseCount; + u16 phaseSize; + }; + + struct StarsDefinition { + u16 count; + float size; + }; + + const SunDefinition &sunDefinition() const { return m_sunDefinition; } + const MoonDefinition &moonDefinition() const { return m_moonDefinition; } + const StarsDefinition &starsDefinition() const { return m_starsDefinition; } + + void setSunDefinition(const SunDefinition &sunDefinition) { m_sunDefinition = sunDefinition; } + void setMoonDefinition(const MoonDefinition &moonDefinition) { m_moonDefinition = moonDefinition; } + void setStarsDefinition(const StarsDefinition &starsDefinition) { m_starsDefinition = starsDefinition; } + private: u16 m_id; std::string m_stringID; gk::Color m_color; gk::Color m_fogColor; + + SunDefinition m_sunDefinition; + MoonDefinition m_moonDefinition; + StarsDefinition m_starsDefinition; }; #endif // SKY_HPP_ diff --git a/source/server/lua/loader/LuaSkyLoader.cpp b/source/server/lua/loader/LuaSkyLoader.cpp index 84fae4bb0..50e49fcf5 100644 --- a/source/server/lua/loader/LuaSkyLoader.cpp +++ b/source/server/lua/loader/LuaSkyLoader.cpp @@ -50,5 +50,49 @@ void LuaSkyLoader::loadSky(const sol::table &table) const { u8 a = fogColor["day"][4].get_or(255); sky.setFogColor(gk::Color{r, g, b, a}); } + + loadObjects(sky, table); +} + +void LuaSkyLoader::loadObjects(Sky &sky, const sol::table &table) const { + if (sol::object obj = table["objects"] ; obj.valid()) { + sol::table objectsTable = obj.as(); + + if (sol::object obj = objectsTable["sun"] ; obj.valid()) { + sol::table sunTable = obj.as(); + + Sky::SunDefinition sunDefinition; + sunDefinition.texture = sunTable["texture"].get_or(""); + sunDefinition.size = sunTable["size"].get_or(256); + + sky.setSunDefinition(sunDefinition); + } + + if (sol::object obj = objectsTable["moon"] ; obj.valid()) { + sol::table moonTable = obj.as(); + + Sky::MoonDefinition moonDefinition; + moonDefinition.texture = moonTable["texture"].get_or(""); + moonDefinition.size = moonTable["size"].get_or(256); + + if (sol::object obj = moonTable["phases"] ; obj.valid()) { + sol::table phasesTable = obj.as(); + moonDefinition.phaseCount = phasesTable["count"].get_or(1); + moonDefinition.phaseSize = phasesTable["size"].get_or(32); + } + + sky.setMoonDefinition(moonDefinition); + } + + if (sol::object obj = objectsTable["stars"] ; obj.valid()) { + sol::table starsTable = obj.as(); + + Sky::StarsDefinition starsDefinition; + starsDefinition.count = starsTable["count"].get_or(1000); + starsDefinition.size = starsTable["size"].get_or(4); + + sky.setStarsDefinition(starsDefinition); + } + } } diff --git a/source/server/lua/loader/LuaSkyLoader.hpp b/source/server/lua/loader/LuaSkyLoader.hpp index 9799b2201..599eea80d 100644 --- a/source/server/lua/loader/LuaSkyLoader.hpp +++ b/source/server/lua/loader/LuaSkyLoader.hpp @@ -30,6 +30,7 @@ #include class LuaMod; +class Sky; class LuaSkyLoader { public: @@ -38,6 +39,8 @@ class LuaSkyLoader { void loadSky(const sol::table &table) const; private: + void loadObjects(Sky &sky, const sol::table &table) const; + LuaMod &m_mod; }; From 5c677aad1d52ba7cf1cdea5df0cd38e285ece602 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 06:05:12 +0200 Subject: [PATCH 21/25] [Lua API] Added 'daylight_cycle' in sky definition to control its presence and speed. --- docs/lua-api-sky.md | 41 +++++++++++++++++++---- mods/default/sky.lua | 4 +++ source/client/graphics/Skybox.cpp | 6 +++- source/client/states/GameState.cpp | 19 ++++++++--- source/common/world/Sky.cpp | 6 ++-- source/common/world/Sky.hpp | 5 +++ source/server/lua/loader/LuaSkyLoader.cpp | 5 +++ 7 files changed, 71 insertions(+), 15 deletions(-) diff --git a/docs/lua-api-sky.md b/docs/lua-api-sky.md index 44a489f69..ebfe3ca52 100644 --- a/docs/lua-api-sky.md +++ b/docs/lua-api-sky.md @@ -14,6 +14,10 @@ mod:sky { day = {50, 153, 204}, }, + daylight_cycle = { + speed = 1.0 + }, + objects = { sun = { texture = "texture-sun", @@ -50,9 +54,26 @@ color = { } ``` -Possible values: +Attributes: + +- `day`: sky color at midday + +### `daylight_cycle` + +Day/night cycle parameters. + +Example: +```lua +daylight_cycle = { + speed = 1.0 +} +``` -- `day`: Sky color at midday +The example above is the minimal code required to add a day/night cycle to a sky. + +Attributes: + +- `speed`: speed of the cycle (default: `1.0`) ### `fog_color` @@ -65,9 +86,9 @@ fog_color = { } ``` -Possible values: +Attributes: -- `day`: Fog color at midday +- `day`: gog color at midday ### `id` @@ -84,7 +105,9 @@ IDs are usually of the form `mod:sky` but the `mod:` prefix is prepended automat #### `moon` -Moon attributes table. Example: +Moon attributes table. + +Example: ```lua moon = { texture = "texture-moon_phases" @@ -106,7 +129,9 @@ Attributes: #### `sun` -Sun attribute table. Example: +Sun attribute table. + +Example: ```lua sun = { texture = "texture-sun", @@ -121,7 +146,9 @@ Attributes: #### `stars` -Stars attribute table. Example: +Stars attribute table. + +Example: ```lua stars = { count = 1000, diff --git a/mods/default/sky.lua b/mods/default/sky.lua index bce188ca8..2c032ec5b 100644 --- a/mods/default/sky.lua +++ b/mods/default/sky.lua @@ -36,6 +36,10 @@ mod:sky { day = {50, 153, 204}, }, + daylight_cycle = { + speed = 1.0 + }, + objects = { sun = { texture = "texture-sun", -- FIXME: Use a path instead like block attribute 'tiles' diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 96277f246..4839547c8 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -41,6 +41,7 @@ void Skybox::loadSky(const Sky &sky) { m_sun = CelestialObject{}; m_sun.setSize(sun.size, sun.size); m_sun.setPosition(500, -m_sun.width() / 2, -m_sun.height() / 2); + m_sun.setRotationSpeed(sky.daylightCycleSpeed()); try { m_sun.setTexture(sun.texture); @@ -56,6 +57,7 @@ void Skybox::loadSky(const Sky &sky) { m_moon.setPosition(-500, -m_moon.width() / 2, -m_moon.height() / 2); m_moon.setPhaseCount(moon.phaseCount, moon.phaseSize); m_moon.setCurrentPhase(0); + m_moon.setRotationSpeed(sky.daylightCycleSpeed()); try { m_moon.setTexture(moon.texture); @@ -75,13 +77,15 @@ void Skybox::loadSky(const Sky &sky) { star.setPosition(650 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); star.setRotationOffset(rand() % GameTime::dayLength); star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); + star.setRotationSpeed(sky.daylightCycleSpeed()); } } void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { if (!m_world.sky()) return; - gk::Color skyColor = GameTime::getSkyColorFromTime(*m_world.sky(), GameTime::getCurrentTime()); + float time = GameTime::getCurrentTime(0, m_world.sky()->daylightCycleSpeed()); + gk::Color skyColor = GameTime::getSkyColorFromTime(*m_world.sky(), time); gk::Color starColor = m_world.sky()->color(); gk::Shader::bind(&m_shader); diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index a7f4e95ca..c86f1f9fa 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -210,13 +210,22 @@ void GameState::onGuiScaleChanged(const GuiScaleChangedEvent &event) { void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const { gk::Shader::bind(&m_shader); - 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); + if (m_world.sky()->daylightCycleSpeed()) { + float time = GameTime::getCurrentTime(0, m_world.sky()->daylightCycleSpeed()); + const gk::Color &color = GameTime::getSkyColorFromTime(*m_world.sky(), time); + glClearColor(color.r, color.g, color.b, color.a); - m_shader.setUniform("u_skyColor", color); - m_shader.setUniform("u_sunlightIntensity", GameTime::getSunlightIntensityFromTime(time)); + m_shader.setUniform("u_skyColor", color); + m_shader.setUniform("u_sunlightIntensity", GameTime::getSunlightIntensityFromTime(time)); + } + else { + const gk::Color &color = m_world.sky()->color(); + glClearColor(color.r, color.g, color.b, color.a); + + m_shader.setUniform("u_skyColor", m_world.sky()->color()); + m_shader.setUniform("u_sunlightIntensity", 1.f); + } } gk::Shader::bind(nullptr); diff --git a/source/common/world/Sky.cpp b/source/common/world/Sky.cpp index 9195aa9cc..820b51134 100644 --- a/source/common/world/Sky.cpp +++ b/source/common/world/Sky.cpp @@ -37,7 +37,8 @@ void Sky::serialize(sf::Packet &packet) const { << m_sunDefinition.texture << m_sunDefinition.size << m_moonDefinition.texture << m_moonDefinition.size << m_moonDefinition.phaseCount << m_moonDefinition.phaseSize - << m_starsDefinition.count << m_starsDefinition.size; + << m_starsDefinition.count << m_starsDefinition.size + << m_daylightCycleSpeed; } void Sky::deserialize(sf::Packet &packet) { @@ -45,6 +46,7 @@ void Sky::deserialize(sf::Packet &packet) { >> m_sunDefinition.texture >> m_sunDefinition.size >> m_moonDefinition.texture >> m_moonDefinition.size >> m_moonDefinition.phaseCount >> m_moonDefinition.phaseSize - >> m_starsDefinition.count >> m_starsDefinition.size; + >> m_starsDefinition.count >> m_starsDefinition.size + >> m_daylightCycleSpeed; } diff --git a/source/common/world/Sky.hpp b/source/common/world/Sky.hpp index 8e73dd953..31b20d75e 100644 --- a/source/common/world/Sky.hpp +++ b/source/common/world/Sky.hpp @@ -74,6 +74,9 @@ class Sky : public gk::ISerializable { void setMoonDefinition(const MoonDefinition &moonDefinition) { m_moonDefinition = moonDefinition; } void setStarsDefinition(const StarsDefinition &starsDefinition) { m_starsDefinition = starsDefinition; } + float daylightCycleSpeed() const { return m_daylightCycleSpeed; } + void setDaylightCycleSpeed(float daylightCycleSpeed) { m_daylightCycleSpeed = daylightCycleSpeed; } + private: u16 m_id; std::string m_stringID; @@ -84,6 +87,8 @@ class Sky : public gk::ISerializable { SunDefinition m_sunDefinition; MoonDefinition m_moonDefinition; StarsDefinition m_starsDefinition; + + float m_daylightCycleSpeed = 0.f; }; #endif // SKY_HPP_ diff --git a/source/server/lua/loader/LuaSkyLoader.cpp b/source/server/lua/loader/LuaSkyLoader.cpp index 50e49fcf5..b2b775abc 100644 --- a/source/server/lua/loader/LuaSkyLoader.cpp +++ b/source/server/lua/loader/LuaSkyLoader.cpp @@ -51,6 +51,11 @@ void LuaSkyLoader::loadSky(const sol::table &table) const { sky.setFogColor(gk::Color{r, g, b, a}); } + if (sol::object obj = table["daylight_cycle"] ; obj.valid()) { + sol::table daylightCycleTable = obj.as(); + sky.setDaylightCycleSpeed(daylightCycleTable["speed"].get_or(0.f)); + } + loadObjects(sky, table); } From 36c5660bf2d508ac825b47ffaf03172e96a8c47b Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 18:15:48 +0200 Subject: [PATCH 22/25] [Skybox] Stars now follow sky rotation. --- source/client/graphics/Skybox.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source/client/graphics/Skybox.cpp b/source/client/graphics/Skybox.cpp index 4839547c8..ed714b777 100644 --- a/source/client/graphics/Skybox.cpp +++ b/source/client/graphics/Skybox.cpp @@ -74,10 +74,18 @@ void Skybox::loadSky(const Sky &sky) { auto &star = m_stars.emplace_back(); star.setColor(gk::Color{0, 0, 0, 0}); star.setSize(stars.size, stars.size); - star.setPosition(650 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); + + glm::vec3 v{rand() % 256, rand() % 256, rand() % 256}; + v = glm::normalize(v); + v *= 600 * (rand() % 2 * 2 - 1); + star.setPosition(v.x, v.y, v.z); + // star.setPosition(650 * ((rand() % 2) * 2 - 1), (rand() % 500) * 2 - 500, (rand() % 500) * 2 - 500); + star.setRotationOffset(rand() % GameTime::dayLength); - star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); star.setRotationSpeed(sky.daylightCycleSpeed()); + star.setRotationAxis({0, 1, 0}); + // Maybe sometimes stars could have a random axis? + // star.setRotationAxis({rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f}); } } @@ -108,8 +116,6 @@ void Skybox::draw(gk::RenderTarget &target, gk::RenderStates states) const { target.draw(m_moon, states); if (Config::isStarRenderingEnabled && skyColor != starColor) { - glDisable(GL_CULL_FACE); - for (auto &it : m_stars) target.draw(it, states); } From 7a6c5665bad13771666d002905eb934f7b4c0b18 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 19:18:09 +0200 Subject: [PATCH 23/25] [Config] Now using 'Fast' AO setting by default. --- mods/default/tools.lua | 2 +- resources/shaders/game.v.glsl | 2 +- source/client/core/Config.cpp | 2 +- source/client/states/SettingsMenuState.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/default/tools.lua b/mods/default/tools.lua index 160a529ee..002abc92e 100644 --- a/mods/default/tools.lua +++ b/mods/default/tools.lua @@ -49,7 +49,7 @@ function register_tool(name, material, mining_speed, harvest_capability) elseif name == "shovel" then tool_def.effective_on = { "group:om_material_dirt", - "group:om_material:sand" + "group:om_material_sand" } tool_def.on_item_activated = function(pos, block, player, world, client, server) diff --git a/resources/shaders/game.v.glsl b/resources/shaders/game.v.glsl index 5f3fe4ccc..09d89bcfd 100644 --- a/resources/shaders/game.v.glsl +++ b/resources/shaders/game.v.glsl @@ -49,7 +49,7 @@ void main() { v_lightValue = lightValue; if (ambientOcclusion != 5) { - const float aovalues[] = float[](0.5, 0.75, 0.9, 1.0); + const float aovalues[] = float[](0.25, 0.5, 0.75, 1.0); v_ambientOcclusion = aovalues[int(ambientOcclusion)]; } else { v_ambientOcclusion = 1.0; diff --git a/source/client/core/Config.cpp b/source/client/core/Config.cpp index 0147f72b4..1a893c170 100644 --- a/source/client/core/Config.cpp +++ b/source/client/core/Config.cpp @@ -50,7 +50,7 @@ bool Config::isCrosshairVisible = true; // Graphics u16 Config::renderDistance = 8; -u8 Config::ambientOcclusion = 2; +u8 Config::ambientOcclusion = 1; bool Config::isSmoothLightingEnabled = true; bool Config::isWireframeModeEnabled = false; bool Config::isFullscreenModeEnabled = false; diff --git a/source/client/states/SettingsMenuState.cpp b/source/client/states/SettingsMenuState.cpp index 887ea6cd4..a2874572d 100644 --- a/source/client/states/SettingsMenuState.cpp +++ b/source/client/states/SettingsMenuState.cpp @@ -220,8 +220,8 @@ void SettingsMenuState::addGraphicsButtons() { const std::string aoValueNames[3] = { "OFF", - "Normal", - "Smooth Lighting" + "Fast", + "Fancy" }; m_menuWidget.addButton(std::string("Ambient Occlusion: ") + aoValueNames[Config::ambientOcclusion], [&, aoValueNames] (TextButton &button) { From 5db8f6cd85859df23e4c2edff8b6caeb51f1ba26 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 19:24:28 +0200 Subject: [PATCH 24/25] [README.md] Updated. --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d59d93e48..bc42f8e98 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,9 @@ The long-term goal of this project is to provide a viable alternative to Minecra ## Project status -This list is non exhaustive. +This list is non complete. + +See also the roadmap for 1.0.0 [here](https://github.com/Unarelith/OpenMiner/wiki/Roadmap). ### Implemented features @@ -97,15 +99,15 @@ This list is non exhaustive. - World loading/saving (see [#26](https://github.com/Unarelith/OpenMiner/issues/26)) - Texture pack system (partially implemented, see [#34](https://github.com/Unarelith/OpenMiner/issues/34)) - Entities ([#90](https://github.com/Unarelith/OpenMiner/pull/90)) +- Day/night cycle with sun/moon/stars ([#154](https://github.com/Unarelith/OpenMiner/pull/154)) ### Missing features - Fluid propagation ([#62](https://github.com/Unarelith/OpenMiner/issues/62)) -- Day/night cycle with sun/moon display ([#73](https://github.com/Unarelith/OpenMiner/issues/73)) - Seed-based worldgen ([#116](https://github.com/Unarelith/OpenMiner/issues/116)) - Cave tunnels ([#118](https://github.com/Unarelith/OpenMiner/issues/118)) - Clouds ([#52](https://github.com/Unarelith/OpenMiner/pull/52)) -- Particle system +- Particle system ([#155](https://github.com/Unarelith/OpenMiner/issues/155)) ## Screenshots From 5f262bf7588322fb4c11db2bbf34c16be56f8b28 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Fri, 17 Jul 2020 19:44:28 +0200 Subject: [PATCH 25/25] [ChunkBuilder] Don't apply AO on light sources. --- README.md | 2 +- docs/lua-api-sky.md | 2 +- resources/shaders/game.f.glsl | 2 +- resources/shaders/game.v.glsl | 2 +- source/client/world/ChunkBuilder.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bc42f8e98..9fb3ca438 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ See also the roadmap for 1.0.0 [here](https://github.com/Unarelith/OpenMiner/wik - Fluid propagation ([#62](https://github.com/Unarelith/OpenMiner/issues/62)) - Seed-based worldgen ([#116](https://github.com/Unarelith/OpenMiner/issues/116)) - Cave tunnels ([#118](https://github.com/Unarelith/OpenMiner/issues/118)) -- Clouds ([#52](https://github.com/Unarelith/OpenMiner/pull/52)) +- Clouds ([#156](https://github.com/Unarelith/OpenMiner/issues/156)) - Particle system ([#155](https://github.com/Unarelith/OpenMiner/issues/155)) ## Screenshots diff --git a/docs/lua-api-sky.md b/docs/lua-api-sky.md index ebfe3ca52..7f0ec5abd 100644 --- a/docs/lua-api-sky.md +++ b/docs/lua-api-sky.md @@ -88,7 +88,7 @@ fog_color = { Attributes: -- `day`: gog color at midday +- `day`: fog color at midday ### `id` diff --git a/resources/shaders/game.f.glsl b/resources/shaders/game.f.glsl index 0ad478e0a..714baacb6 100644 --- a/resources/shaders/game.f.glsl +++ b/resources/shaders/game.f.glsl @@ -73,7 +73,7 @@ void main() { if (blockFace == 2. || blockFace == 3.) ambientIntensity = max(ambientIntensity * 0.9, minBrightness); - float lightval = clamp(sunlight / 16.0, v_lightValue.y / 16.0, 1.0); + float lightval = clamp(sunlight / 15.0, v_lightValue.y / 15.0, 1.0); color = light(color, vec3(lightval, lightval, lightval), v_coord3d, ambientIntensity, diffuseIntensity); } diff --git a/resources/shaders/game.v.glsl b/resources/shaders/game.v.glsl index 09d89bcfd..1205300a3 100644 --- a/resources/shaders/game.v.glsl +++ b/resources/shaders/game.v.glsl @@ -49,7 +49,7 @@ void main() { v_lightValue = lightValue; if (ambientOcclusion != 5) { - const float aovalues[] = float[](0.25, 0.5, 0.75, 1.0); + const float aovalues[] = float[](0.2, 0.45, 0.75, 1.0); v_ambientOcclusion = aovalues[int(ambientOcclusion)]; } else { v_ambientOcclusion = 1.0; diff --git a/source/client/world/ChunkBuilder.cpp b/source/client/world/ChunkBuilder.cpp index 3d6d954d8..6aabef520 100644 --- a/source/client/world/ChunkBuilder.cpp +++ b/source/client/world/ChunkBuilder.cpp @@ -260,7 +260,7 @@ inline void ChunkBuilder::addFace(s8f x, s8f y, s8f z, s8f f, const ClientChunk } auto addVertex = [&](u8 v) { - if (Config::ambientOcclusion != 1) + if (Config::ambientOcclusion != 1 || blockState.isLightSource()) vertices[v].ambientOcclusion = 5; if (blockState.drawType() == BlockDrawType::Liquid)