diff --git a/Block Forge.vcxproj b/Block Forge.vcxproj
index ec927c6b..2d07703c 100644
--- a/Block Forge.vcxproj
+++ b/Block Forge.vcxproj
@@ -150,24 +150,27 @@
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -176,58 +179,66 @@
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
@@ -238,17 +249,16 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Block Forge.vcxproj.user b/Block Forge.vcxproj.user
index ae53a810..07b8d691 100644
--- a/Block Forge.vcxproj.user
+++ b/Block Forge.vcxproj.user
@@ -4,11 +4,11 @@
true
- --trace
+ --debug
WindowsLocalDebugger
- --trace
+ --debug
WindowsLocalDebugger
\ No newline at end of file
diff --git a/Doxyfile b/Doxyfile
index 658f50d7..72e57ea7 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -47,7 +47,7 @@ PROJECT_NAME = "Block Forge"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = v0.5
+PROJECT_NUMBER = v0.6
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/src/Application/Application.cpp b/src/Application/Application.cpp
index 5d307240..e25f76a5 100644
--- a/src/Application/Application.cpp
+++ b/src/Application/Application.cpp
@@ -1,7 +1,7 @@
#include "Application.h"
#include "Core/EngineExceptions.h"
-#include "Sandbox/Sandbox.h"
+#include "LayerStack/Stack/SandboxStack.h"
// As a static member of class this variable
// must be here initialized
@@ -15,6 +15,7 @@ void Application::WindowResizeEvent(GLFWwindow* const, const int width, const in
_window.SetHeight(static_cast(height));
}
+
void Application::CentralizeWindow() const
{
const auto& x = _fullscreenWidth / 2 - _window.GetWidth() / 2;
@@ -67,13 +68,18 @@ void Application::Initialize()
);
}
- glfwSetFramebufferSizeCallback(_window.GetHandle(), WindowResizeEvent);
+ SetCallbacks();
CentralizeWindow();
_log.Info("Block Forge initialized!");
}
+void Application::SetCallbacks()
+{
+ glfwSetFramebufferSizeCallback(_window.GetHandle(), WindowResizeEvent);
+}
+
Application::Application(const std::string& filenameWithSettings)
{
_settings.Load(filenameWithSettings);
@@ -87,8 +93,22 @@ void Application::Run()
{
Initialize();
- const auto sandbox = std::make_unique(_window);
- sandbox->Run();
+ const auto sandbox = SandboxStack(_window);
+ _hid.DisableCursor();
+
+ while(!glfwWindowShouldClose(_window.GetHandle()))
+ {
+ if (_window.GetWidth() <= 0 || _window.GetHeight() <= 0) continue;
+
+ glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ sandbox.Update();
+ sandbox.ProcessEvents(_hid);
+
+ glfwSwapBuffers(_window.GetHandle());
+ glfwPollEvents();
+ }
_log.Info("Quitting...");
diff --git a/src/Application/Application.h b/src/Application/Application.h
index 50562aff..a4d8cc74 100644
--- a/src/Application/Application.h
+++ b/src/Application/Application.h
@@ -2,6 +2,7 @@
#include "Core/Log.h"
#include "Core/Metadata.h"
#include "Window.h"
+#include "HID/HumanInterfaceDevice.h"
/// @class Application
/// @brief Represents the application context.
@@ -12,16 +13,20 @@
class Application
{
static Window _window;
+ HumanInterfaceDevice _hid{_window};
Log& _log = Log::Get();
+
Metadata _settings;
size_t _fullscreenWidth{};
size_t _fullscreenHeight{};
static void WindowResizeEvent(GLFWwindow*, int width, int height);
+
void CentralizeWindow() const;
void Initialize();
+ static void SetCallbacks();
public:
diff --git a/src/Application/HID/HumanInterfaceDevice.cpp b/src/Application/HID/HumanInterfaceDevice.cpp
new file mode 100644
index 00000000..275270ca
--- /dev/null
+++ b/src/Application/HID/HumanInterfaceDevice.cpp
@@ -0,0 +1,91 @@
+#include "HumanInterfaceDevice.h"
+
+int HumanInterfaceDevice::GetState(const KeyboardKey& key) const
+{
+ return glfwGetKey(_window.GetHandle(), static_cast(key));
+}
+
+int HumanInterfaceDevice::GetState(const MouseButton& button) const
+{
+ return glfwGetMouseButton(_window.GetHandle(), static_cast(button));
+}
+
+HumanInterfaceDevice::HumanInterfaceDevice(Window& window) : _window(window)
+{
+}
+
+bool HumanInterfaceDevice::IsPressed(const KeyboardKey& key) const
+{
+ if (GetState(key) == GLFW_PRESS)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool HumanInterfaceDevice::IsPressedOnce(const KeyboardKey& key)
+{
+ if (GetState(key) == GLFW_PRESS && _onceHandledKeyboardKeys.find(key) == _onceHandledKeyboardKeys.end())
+ {
+ _onceHandledKeyboardKeys.insert(key);
+ return IsPressed(key);
+ }
+
+ if (GetState(key) == GLFW_RELEASE)
+ {
+ _onceHandledKeyboardKeys.erase(key);
+ }
+
+ return false;
+}
+
+bool HumanInterfaceDevice::IsPressed(const MouseButton& button) const
+{
+ if (GetState(button) == GLFW_PRESS)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool HumanInterfaceDevice::IsPressedOnce(const MouseButton& button)
+{
+ if (GetState(button) == GLFW_PRESS && _onceHandledMouseButtons.find(button) == _onceHandledMouseButtons.end())
+ {
+ _onceHandledMouseButtons.insert(button);
+ return IsPressed(button);
+ }
+
+ if (GetState(button) == GLFW_RELEASE)
+ {
+ _onceHandledMouseButtons.erase(button);
+ }
+
+ return false;
+}
+
+std::pair HumanInterfaceDevice::GetCursorPosition() const
+{
+ double x;
+ double y;
+ glfwGetCursorPos(_window.GetHandle(), &x, &y);
+
+ return {x, y};
+}
+
+void HumanInterfaceDevice::SetCursorPosition(const double x, const double y) const
+{
+ glfwSetCursorPos(_window.GetHandle(), x, y);
+}
+
+void HumanInterfaceDevice::EnableCursor() const
+{
+ glfwSetInputMode(_window.GetHandle(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+}
+
+void HumanInterfaceDevice::DisableCursor() const
+{
+ glfwSetInputMode(_window.GetHandle(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+}
diff --git a/src/Application/Sandbox/Events/HumanInterfaceDevice.h b/src/Application/HID/HumanInterfaceDevice.h
similarity index 71%
rename from src/Application/Sandbox/Events/HumanInterfaceDevice.h
rename to src/Application/HID/HumanInterfaceDevice.h
index 626bd6be..a724f74a 100644
--- a/src/Application/Sandbox/Events/HumanInterfaceDevice.h
+++ b/src/Application/HID/HumanInterfaceDevice.h
@@ -1,7 +1,10 @@
#pragma once
#include
+
#include "Core/Log.h"
#include "KeyCodes.h"
+#include "Application/Window.h"
+
/// @class HumanInterfaceDevice
/// @brief Handles and defines input devices.
@@ -9,20 +12,19 @@
class HumanInterfaceDevice
{
Log& _log = Log::Get();
- GLFWwindow* _window;
+ Window& _window;
+
std::unordered_set _onceHandledKeyboardKeys;
std::unordered_set _onceHandledMouseButtons;
- std::string KeyDescription(const KeyboardKey& key) const;
- std::string ButtonDescription(const MouseButton& button) const;
-
int GetState(const KeyboardKey& key) const;
int GetState(const MouseButton& button) const;
public:
+
/// @brief The constructor.
/// @param window - The window in which the simulation is played.
- explicit HumanInterfaceDevice(GLFWwindow* window);
+ explicit HumanInterfaceDevice(Window& window);
/// @brief Checks if the requested key is pressed.
/// @param key - The key from keyboard.
@@ -34,11 +36,6 @@ class HumanInterfaceDevice
/// @return Returns true is the key is pressed and was not before, otherwise false.
bool IsPressedOnce(const KeyboardKey& key);
- /// @brief Checks if the requested key is released.
- /// @param key - The key from keyboard.
- /// @return Returns true is the key is released, otherwise false.
- bool IsReleased(const KeyboardKey& key) const;
-
/// @brief Checks if the requested button is pressed.
/// @param button - The button from mouse.
/// @return Returns true is the button is pressed, otherwise false.
@@ -49,8 +46,17 @@ class HumanInterfaceDevice
/// @return Returns true is the button is pressed and was not before, otherwise false.
bool IsPressedOnce(const MouseButton& button);
- /// @brief Checks if the requested button is released.
- /// @param button - The button from keyboard.
- /// @return Returns true is the button is released, otherwise false.
- bool IsReleased(const MouseButton& button) const;
+ /// @brief Returns the current cursor position.
+ std::pair GetCursorPosition() const;
+
+ /// @brief Sets the cursor position to the desired location.
+ /// @param x - Cursor X location.
+ /// @param y - Cursor Y location.
+ void SetCursorPosition(double x, double y) const;
+
+ /// @brief Enables cursor making it visible.
+ void EnableCursor() const;
+
+ /// @brief Disables cursor making it invisible.
+ void DisableCursor() const;
};
\ No newline at end of file
diff --git a/src/Application/Sandbox/Events/KeyCodes.h b/src/Application/HID/KeyCodes.h
similarity index 100%
rename from src/Application/Sandbox/Events/KeyCodes.h
rename to src/Application/HID/KeyCodes.h
diff --git a/src/Application/Layer/Layer.h b/src/Application/Layer/Layer.h
new file mode 100644
index 00000000..3d3992b7
--- /dev/null
+++ b/src/Application/Layer/Layer.h
@@ -0,0 +1,62 @@
+#pragma once
+
+/// @class Layer
+/// @brief Represents a layer that is used by the layer stack.
+/// @see LayerStack
+class Layer
+{
+ bool _isLocked = false;
+
+protected:
+
+ /// @brief Locks the layer, so the next ones won't be processed
+ /// by the OnEvent() method.
+ void LockLayer()
+ {
+ _isLocked = true;
+ }
+
+ /// @brief Unlocks the layer.
+ void UnlockLayer()
+ {
+ _isLocked = false;
+ }
+
+public:
+ Layer() = default;
+
+ /// @brief Copy constructor.
+ Layer(const Layer&) = default;
+
+ /// @brief Move constructor.
+ Layer(Layer&&) = default;
+ Layer& operator=(const Layer&) = delete;
+ Layer& operator=(Layer&&) = delete;
+
+ /// @brief This method is responsible for drawing data on the screen.
+ /// @details This method is used basically for rendering.
+ /// Add the functionality that handles drawing every frame.
+ virtual void OnUpdate() = 0;
+
+ /// @brief This method is used to handle events.
+ /// @details This method should be used when you want to declare functionality that is strongly related to this layer.
+ /// For example, when you are playing a simulation and you pause the game.
+ /// Then you may want to freeze input events that are related to this layer,
+ /// but you would like to render the content of this layer.
+ ///
+ /// Using this method, you can tell it to freeze when necessary and
+ /// use the OnUpdate() method to render continuously.
+ /// @param hid - Reference to the Human Interface Device.
+ virtual void OnEvent(HumanInterfaceDevice& hid) = 0;
+
+ /// @brief Checks if this layer is locked.
+ /// @details If the layer is locked,
+ /// it means that the lower layers from the layer stack should be skipped.
+ bool IsLocked() const
+ {
+ return _isLocked;
+ }
+
+ virtual ~Layer() = default;
+};
+
diff --git a/src/Application/Layer/PauseMenu/PauseMenuLayer.h b/src/Application/Layer/PauseMenu/PauseMenuLayer.h
new file mode 100644
index 00000000..335e1850
--- /dev/null
+++ b/src/Application/Layer/PauseMenu/PauseMenuLayer.h
@@ -0,0 +1,33 @@
+#pragma once
+#include "Application/HID/HumanInterfaceDevice.h"
+#include "Application/Layer/Layer.h"
+
+/// @class PauseMenuLayer
+/// @brief Represents the pause menu.
+class PauseMenuLayer final : public Layer
+{
+public:
+
+ void OnUpdate() override
+ {
+ // For now there is nothing to render.
+ // That's why this method is empty.
+ }
+
+ void OnEvent(HumanInterfaceDevice& hid) override
+ {
+ if (hid.IsPressedOnce(KeyboardKey::escape))
+ {
+ if (IsLocked())
+ {
+ hid.DisableCursor();
+
+ UnlockLayer();
+ return;
+ }
+
+ hid.EnableCursor();
+ LockLayer();
+ }
+ }
+};
diff --git a/src/Application/Layer/Sandbox/Camera.cpp b/src/Application/Layer/Sandbox/Camera.cpp
new file mode 100644
index 00000000..99ab16f9
--- /dev/null
+++ b/src/Application/Layer/Sandbox/Camera.cpp
@@ -0,0 +1,164 @@
+#include "Camera.h"
+
+void Camera::Update()
+{
+ // ReSharper disable once CppInitializedValueIsAlwaysRewritten
+ auto view = glm::mat4(1.0f);
+ view = lookAt(_position, _position + _orientation, _upVector);
+
+ const float aspectRatio = static_cast(_window.GetWidth()) / static_cast(_window.GetHeight());
+
+ // ReSharper disable once CppInitializedValueIsAlwaysRewritten
+ auto projection = glm::mat4(1.0f);
+ projection = glm::perspective(glm::radians(_fieldOfView), aspectRatio, _nearPane, _farPane);
+
+ _orthographicProjection = projection * view;
+}
+
+void Camera::HandleHorizontalMovement(const HumanInterfaceDevice& hid)
+{
+ if (hid.IsPressed(_left))
+ {
+ _position += _speed * -normalize(cross(_orientation, _upVector));
+ }
+ if (hid.IsPressed(_right))
+ {
+ _position += _speed * normalize(cross(_orientation, _upVector));
+ }
+ if (hid.IsPressed(_forward))
+ {
+ _position += _speed * _orientation;
+ }
+ if (hid.IsPressed(_backward))
+ {
+ _position += _speed * -_orientation;
+ }
+}
+
+void Camera::HandleVerticalMovement(const HumanInterfaceDevice& hid)
+{
+ if (hid.IsPressed(_up))
+ {
+ _position += _speed * _upVector;
+ }
+ if (hid.IsPressed(_down))
+ {
+ _position += _speed * -_upVector;
+ }
+}
+
+void Camera::HandleSpeed(const float boostSpeed, const HumanInterfaceDevice& hid)
+{
+ _speed = hid.IsPressed(_boost) ? boostSpeed : _defaultSpeed;
+}
+
+void Camera::UpdateCursorMovement(const HumanInterfaceDevice& hid)
+{
+ const auto& mousePosition = hid.GetCursorPosition();
+ const auto& mouseX = mousePosition.first;
+ const auto& mouseY = mousePosition.second;
+
+ const auto& middleAxisX = mouseX / 2.0;
+ const auto& middleAxisY = mouseY / 2.0;
+
+ const float xAxisRotation = _sensitivity * (static_cast(middleAxisY) / static_cast(_window.GetHeight()));
+ const float yAxisRotation = _sensitivity * (static_cast(middleAxisX) / static_cast(_window.GetWidth()));
+
+ const auto orientation = rotate(_orientation, glm::radians(-xAxisRotation), normalize(cross(_orientation, _upVector)));
+ const auto angleWithXAxis = abs(angle(orientation, _upVector) - glm::radians(90.0f));
+
+ // This prevents the barrel roll situation when looking up
+ if (angleWithXAxis < glm::radians(85.0f))
+ {
+ _orientation = orientation;
+ }
+
+ _orientation = rotate(_orientation, glm::radians(-yAxisRotation), _upVector);
+
+ hid.SetCursorPosition(middleAxisX, middleAxisY);
+}
+
+Camera::Camera(Window& window, const glm::vec3 position)
+ : _window(window),
+ _position(position)
+{
+}
+
+void Camera::Bind(Shader const& shader) const
+{
+ shader.Load();
+ glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "camera"), 1, GL_FALSE, value_ptr(_orthographicProjection));
+}
+
+void Camera::HandleInput(const HumanInterfaceDevice& hid)
+{
+ HandleHorizontalMovement(hid);
+ HandleVerticalMovement(hid);
+ HandleSpeed(0.4f, hid);
+ UpdateCursorMovement(hid);
+}
+
+glm::vec3 Camera::GetPosition() const
+{
+ return _position;
+}
+
+inline float Camera::GetDefaultSpeed() const
+{
+ return _defaultSpeed;
+}
+
+inline void Camera::SetDefaultSpeed(const float defaultSpeed)
+{
+ _defaultSpeed = defaultSpeed;
+}
+
+inline float Camera::GetSpeed() const
+{
+ return _speed;
+}
+
+inline void Camera::SetSpeed(const float speed)
+{
+ _speed = speed;
+}
+
+inline float Camera::GetSensitivity() const
+{
+ return _sensitivity;
+}
+
+inline void Camera::SetSensitivity(const float sensitivity)
+{
+ _sensitivity = sensitivity;
+}
+
+inline float Camera::GetFieldOfView() const
+{
+ return _fieldOfView;
+}
+
+inline void Camera::SetFieldOfView(const float fieldOfView)
+{
+ _fieldOfView = fieldOfView;
+}
+
+inline float Camera::GetNearPane() const
+{
+ return _nearPane;
+}
+
+inline void Camera::SetNearPane(const float nearPane)
+{
+ _nearPane = nearPane;
+}
+
+inline float Camera::GetFarPane() const
+{
+ return _farPane;
+}
+
+inline void Camera::SetFarPane(const float farPane)
+{
+ _farPane = farPane;
+}
\ No newline at end of file
diff --git a/src/Application/Sandbox/Camera.h b/src/Application/Layer/Sandbox/Camera.h
similarity index 74%
rename from src/Application/Sandbox/Camera.h
rename to src/Application/Layer/Sandbox/Camera.h
index fbd37187..59084ad1 100644
--- a/src/Application/Sandbox/Camera.h
+++ b/src/Application/Layer/Sandbox/Camera.h
@@ -4,9 +4,9 @@
#include
#include
-#include "Events/HumanInterfaceDevice.h"
#include "Model/Mesh/Geometry/Shader.h"
-#include "Application/Window.h"
+#include "Application/HID/HumanInterfaceDevice.h"
+
/// @class Camera
/// @brief Handles input to allow spectating the world.
@@ -18,7 +18,7 @@ class Camera
glm::vec3 _position{};
glm::vec3 _orientation = glm::vec3(0.0f, 0.0f, -1.0f);
- glm::vec3 _up = glm::vec3(0.0f, 1.0f, 0.0f);
+ glm::vec3 _upVector = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 _orthographicProjection = glm::mat4(1.0f);
float _defaultSpeed = 0.1f;
@@ -28,20 +28,26 @@ class Camera
float _nearPane = 0.1f;
float _farPane = 100.0f;
- HumanInterfaceDevice& _hid;
- bool _isPaused = false;
+ const KeyboardKey _left = KeyboardKey::a;
+ const KeyboardKey _right = KeyboardKey::d;
+ const KeyboardKey _forward = KeyboardKey::w;
+ const KeyboardKey _backward = KeyboardKey::s;
+
+ const KeyboardKey _up = KeyboardKey::space;
+ const KeyboardKey _down = KeyboardKey::leftCtrl;
+
+ const KeyboardKey _boost = KeyboardKey::leftShift;
- void HandleHorizontalMovement(const KeyboardKey& left, const KeyboardKey& right, const KeyboardKey& forward, const KeyboardKey& backward);
- void HandleVerticalMovement(const KeyboardKey& up, const KeyboardKey& down);
- void HandleSpeed(const KeyboardKey& boost, float boostSpeed);
- void HandleCursorMovement();
+ void HandleHorizontalMovement(const HumanInterfaceDevice& hid);
+ void HandleVerticalMovement(const HumanInterfaceDevice& hid);
+ void HandleSpeed(float boostSpeed, const HumanInterfaceDevice& hid);
+ void UpdateCursorMovement(const HumanInterfaceDevice& hid);
public:
/// @brief The constructor.
/// @param window - Reference to the application window.
/// @param position - Spawn point of the camera.
- /// @param hid - Pointer to the HID handler.
- Camera(Window& window, glm::vec3 position, HumanInterfaceDevice& hid);
+ Camera(Window& window, glm::vec3 position);
/// @brief Update the camera orthogonal projection settings.
void Update();
@@ -51,18 +57,13 @@ class Camera
void Bind(Shader const& shader) const;
/// @brief Captures input and moves the camera accordingly.
- void HandleInput();
+ /// @param hid - Reference to the Human Interface Device controller.
+ void HandleInput(const HumanInterfaceDevice& hid);
/// @brief Get camera position.
/// @return Returns 3D vector representation.
glm::vec3 GetPosition() const;
- /// @brief Get width.
- size_t GetWidth() const;
-
- /// @brief Get height.
- size_t GetHeight() const;
-
/// @brief Get default speed.
/// @details The default speed is the normal speed of the camera.
float GetDefaultSpeed() const;
diff --git a/src/Application/Layer/Sandbox/Model/BlockFaceModel.cpp b/src/Application/Layer/Sandbox/Model/BlockFaceModel.cpp
new file mode 100644
index 00000000..b7ff6d9b
--- /dev/null
+++ b/src/Application/Layer/Sandbox/Model/BlockFaceModel.cpp
@@ -0,0 +1,10 @@
+#include "BlockFaceModel.h"
+
+BlockFaceModel::BlockFaceModel(const std::array& uvTextureCoordinates) : _textureCoordinates(uvTextureCoordinates)
+{
+}
+
+std::array& BlockFaceModel::GetUvCoordinates()
+{
+ return _textureCoordinates;
+}
diff --git a/src/Application/Layer/Sandbox/Model/BlockFaceModel.h b/src/Application/Layer/Sandbox/Model/BlockFaceModel.h
new file mode 100644
index 00000000..0318f58e
--- /dev/null
+++ b/src/Application/Layer/Sandbox/Model/BlockFaceModel.h
@@ -0,0 +1,18 @@
+#pragma once
+#include "Mesh/Mesh.h"
+
+/// @class BlockFaceModel
+/// @brief Represents face of a @see BlockModel.
+class BlockFaceModel
+{
+ std::array _textureCoordinates{};
+
+public:
+
+ /// @brief The constructor.
+ /// @param uvTextureCoordinates - UV texture coordinates.
+ explicit BlockFaceModel(const std::array& uvTextureCoordinates);
+
+ /// @brief Returns the uv coordinates associated with the face model.
+ std::array& GetUvCoordinates();
+};
diff --git a/src/Application/Layer/Sandbox/Model/BlockModel.h b/src/Application/Layer/Sandbox/Model/BlockModel.h
new file mode 100644
index 00000000..0241259d
--- /dev/null
+++ b/src/Application/Layer/Sandbox/Model/BlockModel.h
@@ -0,0 +1,71 @@
+#pragma once
+#include "BlockFaceModel.h"
+
+/// @brief Container for the face models of a block.
+struct BlockFaces
+{
+ /// @brief Model of the block front face.
+ BlockFaceModel front;
+
+ /// @brief Model of the block back face.
+ BlockFaceModel back;
+
+ /// @brief Model of the block left face.
+ BlockFaceModel left;
+
+ /// @brief Model of the block right face.
+ BlockFaceModel right;
+
+ /// @brief Model of the block top face.
+ BlockFaceModel top;
+
+ /// @brief Model of the block bottom face.
+ BlockFaceModel bottom;
+};
+
+
+/// @brief Represents visibility of the faces.
+struct FacesVisibility
+{
+ /// @brief Answers the question "Is the front face of this block visible?".
+ bool front;
+
+ /// @brief Answers the question "Is the back face of this block visible?".
+ bool back;
+
+ /// @brief Answers the question "Is the left face of this block visible?".
+ bool left;
+
+ /// @brief Answers the question "Is the right face of this block visible?".
+ bool right;
+
+ /// @brief Answers the question "Is the top face of this block visible?".
+ bool top;
+
+ /// @brief Answers the question "Is the bottom face of this block visible?".
+ bool bottom;
+};
+
+/// @class BlockModel
+/// @brief Represents a graphical model of a block.
+/// @note This class is not an actual model.
+/// More like container for the @see BlockFaceModel objects. But it suits well it's definition and
+/// has functionality that makes sense.
+class BlockModel
+{
+ BlockFaces _blockFaces;
+
+public:
+
+ /// @brief The constructor.
+ /// @param faces - The faces of the block.
+ explicit BlockModel(const BlockFaces& faces)
+ : _blockFaces(faces)
+ {}
+
+ /// @brief Returns the faces data of the block.
+ BlockFaces& GetFaces()
+ {
+ return _blockFaces;
+ }
+};
\ No newline at end of file
diff --git a/src/Application/Layer/Sandbox/Model/Mesh/DynamicMesh.cpp b/src/Application/Layer/Sandbox/Model/Mesh/DynamicMesh.cpp
new file mode 100644
index 00000000..7418a784
--- /dev/null
+++ b/src/Application/Layer/Sandbox/Model/Mesh/DynamicMesh.cpp
@@ -0,0 +1,79 @@
+#include "DynamicMesh.h"
+
+#include "Application/Layer/Sandbox/World/Biomes/Biome.h"
+
+std::vector DynamicMesh::GenerateIndicesFromPattern(const std::vector& pattern, const size_t& maxVerticesAmount) const
+{
+ std::vector indices;
+ for (size_t i = 0; i < maxVerticesAmount; ++i)
+ {
+ const auto& multiplier = i * _indicesInOneInstance;
+
+ constexpr auto indicesInOneTriangle = 3;
+ for (auto j = 0; j < _indicesInPatternAmount / indicesInOneTriangle; ++j)
+ {
+ indices.emplace_back(pattern[j] + static_cast(multiplier));
+ }
+ }
+
+ return indices;
+}
+
+DynamicMesh::DynamicMesh(
+ std::vector vertices,
+ const std::vector& indicesPattern,
+ Shader& shader,
+ const size_t& maxInstancesAmount) : _shader(shader), _vertices(std::move(vertices))
+{
+ constexpr auto indexesInOneTriangle = 3;
+ _indicesInPatternAmount = static_cast(indicesPattern.size()) * indexesInOneTriangle;
+
+ const auto& triangleWithMaxValue = std::max_element(
+ indicesPattern.begin(),
+ indicesPattern.end(),
+ [](const TriangleIndexes &a, const TriangleIndexes &b)
+ {
+ return std::max({a.x, a.y, a.z}) < std::max({b.x, b.y, b.z});
+ }
+ );
+ _indicesInOneInstance = std::max({triangleWithMaxValue->x, triangleWithMaxValue->y, triangleWithMaxValue->z}) + 1;
+
+ const auto& indices = GenerateIndicesFromPattern(indicesPattern, maxInstancesAmount);
+
+ GetVao().Bind();
+ _vbo = std::make_unique(sizeof(Vertex), maxInstancesAmount * _indicesInOneInstance);
+ const auto ebo = ElementBuffer(indices);
+
+ constexpr auto stride = sizeof(Vertex) / sizeof(float);
+ constexpr auto vector2dSize = 2;
+ constexpr auto vector3dSize = 3;
+
+ GetVao().Link(*_vbo, 0, vector3dSize, stride, 0);
+ GetVao().Link(*_vbo, 1, vector2dSize, stride, vector3dSize);
+
+ GetVao().Unbind();
+ _vbo->Unbind();
+ ebo.Unbind();
+}
+
+void DynamicMesh::Update(const std::vector& vertices)
+{
+ _vertices = vertices;
+
+ _vbo->Bind();
+ glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast(_vertices.size()) * static_cast(sizeof(Vertex)), _vertices.data());
+ _vbo->Unbind();
+}
+
+void DynamicMesh::Draw(const Texture& texture, const Camera& camera)
+{
+ if (_vertices.empty()) return;
+
+ camera.Bind(_shader);
+
+ GetVao().Bind();
+ texture.Bind(_shader);
+ glDrawElements(GL_TRIANGLES, static_cast(_vertices.size()) / _indicesInOneInstance * _indicesInPatternAmount, GL_UNSIGNED_INT, nullptr);
+ texture.Unbind();
+ GetVao().Unbind();
+}
diff --git a/src/Application/Layer/Sandbox/Model/Mesh/DynamicMesh.h b/src/Application/Layer/Sandbox/Model/Mesh/DynamicMesh.h
new file mode 100644
index 00000000..a010543c
--- /dev/null
+++ b/src/Application/Layer/Sandbox/Model/Mesh/DynamicMesh.h
@@ -0,0 +1,37 @@
+#pragma once
+#include "Mesh.h"
+
+/// @class DynamicMesh
+/// @brief Represents a dynamic mesh of a Model.
+/// @details Dynamic mesh is a mesh that it's vertices could be changed in a runtime.
+/// @note If your object won't change its structure, you should use StaticMesh.
+class DynamicMesh final : protected Mesh
+{
+ std::unique_ptr _vbo;
+
+ Shader& _shader;
+ std::vector _vertices;
+ GLsizei _indicesInPatternAmount{};
+ GLsizei _indicesInOneInstance{};
+
+ std::vector GenerateIndicesFromPattern(const std::vector& pattern, const size_t& maxVerticesAmount) const;
+
+public:
+
+ /// @brief The constructor.
+ /// @param vertices - The vertices of the mesh.
+ /// @param indicesPattern - The indices pattern sequence of the vertices position (to replicate for allocating the buffer).
+ /// @param shader - The shader that the mesh is using.
+ /// @param maxInstancesAmount - Amount of maximum possible instances to create within this mesh.
+ DynamicMesh(std::vector vertices, const std::vector& indicesPattern, Shader& shader, const size_t& maxInstancesAmount);
+
+ /// @brief Rebuilds the mesh.
+ /// @param vertices - new mesh vertices.
+ void Update(const std::vector& vertices);
+
+ /// @brief Draws the mesh.
+ /// @param texture - The texture to cover the mesh.
+ /// @param camera - It is used to bind a shader to see the drawn mesh.
+ void Draw(const Texture& texture, const Camera& camera);
+};
+
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/ElementBuffer.cpp b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/ElementBuffer.cpp
similarity index 92%
rename from src/Application/Sandbox/Model/Mesh/Geometry/ElementBuffer.cpp
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/ElementBuffer.cpp
index ed48185d..ee847d3b 100644
--- a/src/Application/Sandbox/Model/Mesh/Geometry/ElementBuffer.cpp
+++ b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/ElementBuffer.cpp
@@ -5,7 +5,7 @@ ElementBuffer::ElementBuffer(const std::vector& indices)
const auto verticesDataSize = static_cast(indices.size()) * static_cast(sizeof(TriangleIndexes));
glGenBuffers(1, &_bufferRef);
- Bind();
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _bufferRef);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, verticesDataSize, indices.data(), GL_STATIC_DRAW);
}
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/ElementBuffer.h b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/ElementBuffer.h
similarity index 100%
rename from src/Application/Sandbox/Model/Mesh/Geometry/ElementBuffer.h
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/ElementBuffer.h
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/Shader.cpp b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/Shader.cpp
similarity index 94%
rename from src/Application/Sandbox/Model/Mesh/Geometry/Shader.cpp
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/Shader.cpp
index 0dbda64f..ae890b1a 100644
--- a/src/Application/Sandbox/Model/Mesh/Geometry/Shader.cpp
+++ b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/Shader.cpp
@@ -19,7 +19,7 @@ std::string Shader::GetFileContents(const std::string& filename) const
contents.resize(static_cast(file.tellg()));
file.seekg(0, std::ios::beg);
- file.read(&contents[0], contents.size()); // NOLINT(readability-container-data-pointer)
+ file.read(&contents[0], static_cast(contents.size())); // NOLINT(readability-container-data-pointer)
file.close();
return contents;
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/Shader.h b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/Shader.h
similarity index 100%
rename from src/Application/Sandbox/Model/Mesh/Geometry/Shader.h
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/Shader.h
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/Structures.h b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/Structures.h
similarity index 58%
rename from src/Application/Sandbox/Model/Mesh/Geometry/Structures.h
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/Structures.h
index 0fdbf214..3d857aa5 100644
--- a/src/Application/Sandbox/Model/Mesh/Geometry/Structures.h
+++ b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/Structures.h
@@ -9,17 +9,23 @@ using Matrix = glm::mat4;
/// @brief The group of indexes that represent the indices of the mesh.
using TriangleIndexes = glm::ivec3;
-/// @brief A position in space of the object.
-using Position = glm::vec3;
+/// @brief A position of an object.
+using Position = glm::ivec3;
+
+/// @brief A point in the 3D space.
+using Point3D = glm::vec3;
/// @brief A point in the 2D space.
using Point = glm::vec2;
+/// @brief Tells how many vertices a quad (two triangles connected by a hypotenuse) has.
+constexpr size_t VerticesInQuad = 4;
+
/// @brief Represent a single vertex that is used by the shader.
struct Vertex
{
- /// @brief The position of the vertex in space.
- Position position;
+ /// @brief The position of the vertex in the mesh.
+ Point3D position;
/// @brief The texture UV coordinate.
Point uvCoordinate;
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/VertexArray.cpp b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexArray.cpp
similarity index 88%
rename from src/Application/Sandbox/Model/Mesh/Geometry/VertexArray.cpp
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexArray.cpp
index 34d7fd88..f4461b3c 100644
--- a/src/Application/Sandbox/Model/Mesh/Geometry/VertexArray.cpp
+++ b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexArray.cpp
@@ -11,14 +11,15 @@ VertexArray::VertexArray()
void VertexArray::Link(const VertexBuffer& vbo, const GLuint layout, const GLint size, const GLsizei stride, const GLint offset) const
{
vbo.Bind();
+
glVertexAttribPointer(
layout, size,
GL_FLOAT, GL_FALSE,
static_cast(stride * sizeof(float)),
- reinterpret_cast(offset * sizeof(float))
+ reinterpret_cast(offset * sizeof(float)) // NOLINT(performance-no-int-to-ptr)
);
-
glEnableVertexAttribArray(layout);
+
vbo.Unbind();
}
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/VertexArray.h b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexArray.h
similarity index 100%
rename from src/Application/Sandbox/Model/Mesh/Geometry/VertexArray.h
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexArray.h
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/VertexBuffer.cpp b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexBuffer.cpp
similarity index 67%
rename from src/Application/Sandbox/Model/Mesh/Geometry/VertexBuffer.cpp
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexBuffer.cpp
index bacae7ba..0764a2e4 100644
--- a/src/Application/Sandbox/Model/Mesh/Geometry/VertexBuffer.cpp
+++ b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexBuffer.cpp
@@ -11,6 +11,13 @@ VertexBuffer::VertexBuffer(const std::vector& vertices)
glBufferData(GL_ARRAY_BUFFER, verticesSize, vertices.data(), GL_STATIC_DRAW);
}
+VertexBuffer::VertexBuffer(const size_t& vertexSize, const size_t& maxAmountOfVertices)
+{
+ glGenBuffers(1, &_bufferRef);
+ glBindBuffer(GL_ARRAY_BUFFER, _bufferRef);
+ glBufferData(GL_ARRAY_BUFFER, static_cast(vertexSize) * static_cast(maxAmountOfVertices), nullptr, GL_DYNAMIC_DRAW);
+}
+
void VertexBuffer::Bind() const
{
glBindBuffer(GL_ARRAY_BUFFER, _bufferRef);
diff --git a/src/Application/Sandbox/Model/Mesh/Geometry/VertexBuffer.h b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexBuffer.h
similarity index 64%
rename from src/Application/Sandbox/Model/Mesh/Geometry/VertexBuffer.h
rename to src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexBuffer.h
index d5ec9a9e..fda9b30d 100644
--- a/src/Application/Sandbox/Model/Mesh/Geometry/VertexBuffer.h
+++ b/src/Application/Layer/Sandbox/Model/Mesh/Geometry/VertexBuffer.h
@@ -12,8 +12,15 @@ class VertexBuffer
public:
/// @brief The constructor creates VBO, binds it immediately and sets its data.
+ /// @warning This constructor creates **STATIC** vertex buffer object.
+ /// It's meant to represent single objects or to be used with instancing.
explicit VertexBuffer(const std::vector& vertices);
+ /// @brief The constructor creates VBO, binds it immediately and sets its data.
+ /// @warning This constructor **allocates** **DYNAMIC** vertex buffer object.
+ /// It's meant to be flexible and it's empty!
+ explicit VertexBuffer(const size_t& vertexSize, const size_t& maxAmountOfVertices);
+
VertexBuffer(const VertexBuffer&) = delete;
/// @brief Move constructor.
diff --git a/src/Application/Layer/Sandbox/Model/Mesh/Mesh.h b/src/Application/Layer/Sandbox/Model/Mesh/Mesh.h
new file mode 100644
index 00000000..2d98a0a5
--- /dev/null
+++ b/src/Application/Layer/Sandbox/Model/Mesh/Mesh.h
@@ -0,0 +1,26 @@
+// ReSharper disable CppUnusedIncludeDirective
+#pragma once
+#include "Geometry/Structures.h"
+#include "Geometry/Shader.h"
+#include "Geometry/VertexArray.h"
+#include "Geometry/ElementBuffer.h"
+#include "Application/Layer/Sandbox/Camera.h"
+#include "Application/Layer/Sandbox/Model/Surface/Texture.h"
+
+/// @class Mesh
+/// @brief The interface for the classes which purpose is to create mesh for the models.
+class Mesh // NOLINT(cppcoreguidelines-special-member-functions)
+{
+ /// @brief Vertex array object of the meshes.
+ VertexArray _vao;
+
+public:
+
+ /// @brief Returns mesh Vertex Array Object.
+ VertexArray& GetVao()
+ {
+ return _vao;
+ }
+
+ virtual ~Mesh() = default;
+};
\ No newline at end of file
diff --git a/src/Application/Sandbox/Model/Mesh/Mesh.cpp b/src/Application/Layer/Sandbox/Model/Mesh/StaticMesh.cpp
similarity index 54%
rename from src/Application/Sandbox/Model/Mesh/Mesh.cpp
rename to src/Application/Layer/Sandbox/Model/Mesh/StaticMesh.cpp
index fc9ff040..7db11655 100644
--- a/src/Application/Sandbox/Model/Mesh/Mesh.cpp
+++ b/src/Application/Layer/Sandbox/Model/Mesh/StaticMesh.cpp
@@ -1,12 +1,12 @@
-#include "Mesh.h"
+#include "StaticMesh.h"
-Mesh::Mesh(const std::vector& vertices, const std::vector& indices, Shader& shader)
+StaticMesh::StaticMesh(const std::vector& vertices, const std::vector& indices, Shader& shader)
: _shader(shader)
{
constexpr auto indexesInOneTriangle = 3;
_indicesAmount = static_cast(indices.size()) * indexesInOneTriangle;
- _vao.Bind();
+ GetVao().Bind();
const auto vbo = VertexBuffer(vertices);
const auto ebo = ElementBuffer(indices);
@@ -14,24 +14,29 @@ Mesh::Mesh(const std::vector& vertices, const std::vectormesh of a @see Model.
-class Mesh
+/// @class StaticMesh
+/// @brief Represents a static mesh of a Model.
+/// @details Static mesh is a mesh that it's vertices will never change.
+class StaticMesh final : protected Mesh
{
- VertexArray _vao;
Shader& _shader;
GLsizei _indicesAmount{};
@@ -20,12 +15,12 @@ class Mesh
/// @param vertices - The vertices of the mesh.
/// @param indices - The indices sequence of the vertices position.
/// @param shader - The shader that the mesh is using.
- Mesh(const std::vector& vertices, const std::vector& indices, Shader& shader);
+ StaticMesh(const std::vector& vertices, const std::vector& indices, Shader& shader);
/// @brief Draws the mesh.
/// @param origin - A position in the world to place the mesh.
/// @param texture - The texture to cover the mesh.
/// @param camera - It is used to bind a shader to see the drawn mesh.
- void Draw(const Position& origin, const Texture& texture, const Camera& camera) const;
+ void Draw(const Position& origin, const Texture& texture, const Camera& camera);
};
diff --git a/src/Application/Sandbox/Model/Surface/Texture.cpp b/src/Application/Layer/Sandbox/Model/Surface/Texture.cpp
similarity index 100%
rename from src/Application/Sandbox/Model/Surface/Texture.cpp
rename to src/Application/Layer/Sandbox/Model/Surface/Texture.cpp
diff --git a/src/Application/Sandbox/Model/Surface/Texture.h b/src/Application/Layer/Sandbox/Model/Surface/Texture.h
similarity index 89%
rename from src/Application/Sandbox/Model/Surface/Texture.h
rename to src/Application/Layer/Sandbox/Model/Surface/Texture.h
index 30b02b5b..d2dcbf50 100644
--- a/src/Application/Sandbox/Model/Surface/Texture.h
+++ b/src/Application/Layer/Sandbox/Model/Surface/Texture.h
@@ -1,6 +1,6 @@
#pragma once
-#include "Application/Sandbox/Model/Mesh/Geometry/Shader.h"
-#include "Application/Sandbox/Model/Mesh/Geometry/Structures.h"
+#include "Application/Layer/Sandbox/Model/Mesh/Geometry/Shader.h"
+#include "Application/Layer/Sandbox/Model/Mesh/Geometry/Structures.h"
/// @class Texture
/// @brief Texture represents an image that is displayed on the @see Mesh.
diff --git a/src/Application/Sandbox/Model/Surface/TextureAtlas.cpp b/src/Application/Layer/Sandbox/Model/Surface/TextureAtlas.cpp
similarity index 63%
rename from src/Application/Sandbox/Model/Surface/TextureAtlas.cpp
rename to src/Application/Layer/Sandbox/Model/Surface/TextureAtlas.cpp
index ac4bbbca..595f5adf 100644
--- a/src/Application/Sandbox/Model/Surface/TextureAtlas.cpp
+++ b/src/Application/Layer/Sandbox/Model/Surface/TextureAtlas.cpp
@@ -1,17 +1,13 @@
#include "TextureAtlas.h"
-TextureAtlas::TextureAtlas(const std::string& filenameWithImage, const size_t spriteSize) : Texture(filenameWithImage), _spriteSize(spriteSize)
-{
-}
-
-void TextureAtlas::SetSprite(std::vector& vertices, const unsigned x, const unsigned y, const bool flip)
+std::array TextureAtlas::GetTextureCoordinatesAt(const unsigned x, const unsigned y)
{
const auto& width = GetWidth();
const auto& height = GetHeight();
const auto invertedY = height / _spriteSize - y - 1;
- const std::array textureCoords =
+ const std::array textureCoords =
{{
{
static_cast(x) * static_cast(_spriteSize) / static_cast(width),
@@ -31,12 +27,22 @@ void TextureAtlas::SetSprite(std::vector& vertices, const unsigned x, co
}
}};
- constexpr auto verticesAmount = 4;
- for (auto i = 0; i < verticesAmount; ++i)
+ return textureCoords;
+}
+
+TextureAtlas::TextureAtlas(const std::string& filenameWithImage, const size_t spriteSize) : Texture(filenameWithImage), _spriteSize(spriteSize)
+{
+}
+
+void TextureAtlas::SetSprite(std::vector& vertices, const unsigned x, const unsigned y, const bool flip)
+{
+ const auto& textureCoords = GetTextureCoordinatesAt(x, y);
+
+ for (size_t i = 0; i < VerticesInQuad; ++i)
{
if (flip)
{
- vertices.at((i + verticesAmount - 1) % verticesAmount).uvCoordinate = textureCoords[i];
+ vertices.at((i + VerticesInQuad - 1) % VerticesInQuad).uvCoordinate = textureCoords[i];
}
else
{
@@ -44,3 +50,19 @@ void TextureAtlas::SetSprite(std::vector& vertices, const unsigned x, co
}
}
}
+
+void TextureAtlas::SetSprite(std::array& textureUvCoordinates, const unsigned x, const unsigned y, const bool flip)
+{
+ const auto& textureCoords = GetTextureCoordinatesAt(x, y);
+
+ if (!flip)
+ {
+ textureUvCoordinates = textureCoords;
+ return;
+ }
+
+ for (size_t i = 0; i < VerticesInQuad; ++i)
+ {
+ textureUvCoordinates[(i + VerticesInQuad - 1) % VerticesInQuad] = textureCoords[i];
+ }
+}
diff --git a/src/Application/Sandbox/Model/Surface/TextureAtlas.h b/src/Application/Layer/Sandbox/Model/Surface/TextureAtlas.h
similarity index 63%
rename from src/Application/Sandbox/Model/Surface/TextureAtlas.h
rename to src/Application/Layer/Sandbox/Model/Surface/TextureAtlas.h
index 2b3bd086..983423c6 100644
--- a/src/Application/Sandbox/Model/Surface/TextureAtlas.h
+++ b/src/Application/Layer/Sandbox/Model/Surface/TextureAtlas.h
@@ -6,6 +6,7 @@
class TextureAtlas : public Texture
{
size_t _spriteSize;
+ std::array GetTextureCoordinatesAt(unsigned x, unsigned y);
public:
@@ -20,5 +21,12 @@ class TextureAtlas : public Texture
/// @param y - The row index of the texture.
/// @param flip - If true, it flips the texture coordinates 180 degrees.
void SetSprite(std::vector& vertices, unsigned x, unsigned y, bool flip = false);
+
+ /// @brief Sets the vertices according to the sprite from the texture atlas.
+ /// @param textureUvCoordinates - UV coordinates of a texture.
+ /// @param x - The column index of the texture.
+ /// @param y - The row index of the texture.
+ /// @param flip - If true, it flips the texture coordinates 180 degrees.
+ void SetSprite(std::array& textureUvCoordinates, unsigned x, unsigned y, bool flip = false);
};
diff --git a/src/Application/Sandbox/Noise/Noise.h b/src/Application/Layer/Sandbox/Noise/Noise.h
similarity index 100%
rename from src/Application/Sandbox/Noise/Noise.h
rename to src/Application/Layer/Sandbox/Noise/Noise.h
diff --git a/src/Application/Sandbox/Noise/Noise2D.cpp b/src/Application/Layer/Sandbox/Noise/Noise2D.cpp
similarity index 100%
rename from src/Application/Sandbox/Noise/Noise2D.cpp
rename to src/Application/Layer/Sandbox/Noise/Noise2D.cpp
diff --git a/src/Application/Sandbox/Noise/Noise2D.h b/src/Application/Layer/Sandbox/Noise/Noise2D.h
similarity index 95%
rename from src/Application/Sandbox/Noise/Noise2D.h
rename to src/Application/Layer/Sandbox/Noise/Noise2D.h
index 9de8560b..cc44d6b2 100644
--- a/src/Application/Sandbox/Noise/Noise2D.h
+++ b/src/Application/Layer/Sandbox/Noise/Noise2D.h
@@ -2,7 +2,7 @@
#include
#include "Noise.h"
-#include "Application/Sandbox/World/Chunks/Structure/ChunkFrame.h"
+#include "Application/Layer/Sandbox/World/Chunks/Structure/ChunkFrame.h"
/// @class Noise2D
/// @brief Used for gathering data from the defined 2D noise.
diff --git a/src/Application/Sandbox/Noise/Noise3D.cpp b/src/Application/Layer/Sandbox/Noise/Noise3D.cpp
similarity index 100%
rename from src/Application/Sandbox/Noise/Noise3D.cpp
rename to src/Application/Layer/Sandbox/Noise/Noise3D.cpp
diff --git a/src/Application/Sandbox/Noise/Noise3D.h b/src/Application/Layer/Sandbox/Noise/Noise3D.h
similarity index 95%
rename from src/Application/Sandbox/Noise/Noise3D.h
rename to src/Application/Layer/Sandbox/Noise/Noise3D.h
index 1554932a..ae5efea0 100644
--- a/src/Application/Sandbox/Noise/Noise3D.h
+++ b/src/Application/Layer/Sandbox/Noise/Noise3D.h
@@ -2,8 +2,8 @@
#include
#include "Noise.h"
-#include "Application/Sandbox/Model/Mesh/Geometry/Structures.h"
-#include "Application/Sandbox/World/Chunks/Structure/ChunkFrame.h"
+#include "Application/Layer/Sandbox/Model/Mesh/Geometry/Structures.h"
+#include "Application/Layer/Sandbox/World/Chunks/Structure/ChunkFrame.h"
/// @class Noise3D
diff --git a/src/Application/Layer/Sandbox/SandboxLayer.h b/src/Application/Layer/Sandbox/SandboxLayer.h
new file mode 100644
index 00000000..40386674
--- /dev/null
+++ b/src/Application/Layer/Sandbox/SandboxLayer.h
@@ -0,0 +1,66 @@
+#pragma once
+#include
+
+#include "Application/Layer/Layer.h"
+#include "Application/Layer/Sandbox/Camera.h"
+#include "Application/Layer/Sandbox/Utils/FPSCounter.h"
+#include "Application/Layer/Sandbox/World/WorldGenerator.h"
+#include "Application/Layer/Sandbox/World/Chunks/ChunkPlacer.h"
+#include "Application/Layer/Sandbox/World/Chunks/ChunkRenderer.h"
+
+/// @class SandboxLayer
+/// @brief Represents sandbox that is played as an simulation.
+class SandboxLayer final : public Layer
+{
+ std::unique_ptr _camera{};
+ std::unique_ptr _chunkPlacer{};
+ std::unique_ptr _fpsCounter{};
+
+ std::shared_ptr _worldGenerator;
+
+public:
+
+ SandboxLayer(const SandboxLayer&) = delete;
+ SandboxLayer(SandboxLayer&&) = delete;
+ SandboxLayer& operator=(const SandboxLayer&) = delete;
+ SandboxLayer& operator=(SandboxLayer&&) = delete;
+
+ /// @brief The constructor.
+ /// @param window - Reference to the window.
+ explicit SandboxLayer(Window& window)
+ {
+ glEnable(GL_DEPTH_TEST);
+
+ constexpr auto worldSeed = 69;
+ constexpr auto chunkSize = 32;
+ constexpr auto renderDistance = 2;
+
+ _camera = std::make_unique(window, glm::vec3(0.0f, 0.0f, 0.0f));
+ _worldGenerator = std::make_shared(worldSeed);
+
+ _chunkPlacer = std::make_unique(OrderType::tiltedCube, chunkSize, renderDistance, _camera->GetPosition());
+ _chunkPlacer->Bind(_worldGenerator);
+
+ _fpsCounter = std::make_unique();
+ }
+
+ void OnUpdate() override
+ {
+ const ChunkRenderer chunkRenderer;
+
+ _camera->Update();
+ chunkRenderer.Render(_chunkPlacer->GetChunks(), *_camera);
+ _fpsCounter->Update();
+ }
+
+ void OnEvent(HumanInterfaceDevice& hid) override
+ {
+ _camera->HandleInput(hid);
+ _chunkPlacer->Update(_camera->GetPosition());
+ }
+
+ ~SandboxLayer() override
+ {
+ gltTerminate();
+ }
+};
diff --git a/src/Application/Sandbox/Utils/FPSCounter.cpp b/src/Application/Layer/Sandbox/Utils/FPSCounter.cpp
similarity index 100%
rename from src/Application/Sandbox/Utils/FPSCounter.cpp
rename to src/Application/Layer/Sandbox/Utils/FPSCounter.cpp
diff --git a/src/Application/Sandbox/Utils/FPSCounter.h b/src/Application/Layer/Sandbox/Utils/FPSCounter.h
similarity index 100%
rename from src/Application/Sandbox/Utils/FPSCounter.h
rename to src/Application/Layer/Sandbox/Utils/FPSCounter.h
diff --git a/src/Application/Sandbox/World.h b/src/Application/Layer/Sandbox/World.h
similarity index 100%
rename from src/Application/Sandbox/World.h
rename to src/Application/Layer/Sandbox/World.h
diff --git a/src/Application/Sandbox/World/Biomes/Biome.cpp b/src/Application/Layer/Sandbox/World/Biomes/Biome.cpp
similarity index 97%
rename from src/Application/Sandbox/World/Biomes/Biome.cpp
rename to src/Application/Layer/Sandbox/World/Biomes/Biome.cpp
index b768335b..daddb690 100644
--- a/src/Application/Sandbox/World/Biomes/Biome.cpp
+++ b/src/Application/Layer/Sandbox/World/Biomes/Biome.cpp
@@ -22,7 +22,7 @@ void Biome::SetBlockAccordingToNoise(ChunkBlocks& blocks, const glm::ivec3 origi
_blocksMap.Get(_depthLevel[blockIndex].second)
};
- blocks.block[origin] = blockData;
+ blocks[origin] = blockData;
}
Biome::Biome(std::string name, const Noise3D& noise, std::vector> depthLevels, BlockMap& blocksMap)
diff --git a/src/Application/Sandbox/World/Biomes/Biome.h b/src/Application/Layer/Sandbox/World/Biomes/Biome.h
similarity index 89%
rename from src/Application/Sandbox/World/Biomes/Biome.h
rename to src/Application/Layer/Sandbox/World/Biomes/Biome.h
index 75bac5f2..6b6634d3 100644
--- a/src/Application/Sandbox/World/Biomes/Biome.h
+++ b/src/Application/Layer/Sandbox/World/Biomes/Biome.h
@@ -1,7 +1,7 @@
#pragma once
-#include "Application/Sandbox/Noise/Noise3D.h"
-#include "Application/Sandbox/World/Blocks/BlockMap.h"
-#include "Application/Sandbox/World/Chunks/Structure/ChunkBlocks.h"
+#include "Application/Layer/Sandbox/Noise/Noise3D.h"
+#include "Application/Layer/Sandbox/World/Blocks/BlockMap.h"
+#include "Application/Layer/Sandbox/World/Chunks/Structure/ChunkBlocks.h"
/// @class Biome
/// @brief Represents biome that could be used for terrain generation.
diff --git a/src/Application/Sandbox/World/Biomes/BiomePlacer.cpp b/src/Application/Layer/Sandbox/World/Biomes/BiomePlacer.cpp
similarity index 100%
rename from src/Application/Sandbox/World/Biomes/BiomePlacer.cpp
rename to src/Application/Layer/Sandbox/World/Biomes/BiomePlacer.cpp
diff --git a/src/Application/Sandbox/World/Biomes/BiomePlacer.h b/src/Application/Layer/Sandbox/World/Biomes/BiomePlacer.h
similarity index 96%
rename from src/Application/Sandbox/World/Biomes/BiomePlacer.h
rename to src/Application/Layer/Sandbox/World/Biomes/BiomePlacer.h
index da62a5f4..c2d08f4e 100644
--- a/src/Application/Sandbox/World/Biomes/BiomePlacer.h
+++ b/src/Application/Layer/Sandbox/World/Biomes/BiomePlacer.h
@@ -1,6 +1,6 @@
#pragma once
#include "Biome.h"
-#include "Application/Sandbox/Noise/Noise2D.h"
+#include "Application/Layer/Sandbox/Noise/Noise2D.h"
/// @class BiomePlacer
/// @brief Places biomes according to the biomes map.
diff --git a/src/Application/Sandbox/World/Biomes/BiomeProvider.cpp b/src/Application/Layer/Sandbox/World/Biomes/BiomeProvider.cpp
similarity index 100%
rename from src/Application/Sandbox/World/Biomes/BiomeProvider.cpp
rename to src/Application/Layer/Sandbox/World/Biomes/BiomeProvider.cpp
diff --git a/src/Application/Sandbox/World/Biomes/BiomeProvider.h b/src/Application/Layer/Sandbox/World/Biomes/BiomeProvider.h
similarity index 96%
rename from src/Application/Sandbox/World/Biomes/BiomeProvider.h
rename to src/Application/Layer/Sandbox/World/Biomes/BiomeProvider.h
index 021967a7..29411c2c 100644
--- a/src/Application/Sandbox/World/Biomes/BiomeProvider.h
+++ b/src/Application/Layer/Sandbox/World/Biomes/BiomeProvider.h
@@ -1,7 +1,7 @@
#pragma once
#include "Biome.h"
#include "Core/Metadata.h"
-#include "Application/Sandbox/Noise/Noise2D.h"
+#include "Application/Layer/Sandbox/Noise/Noise2D.h"
/// @class BiomeProvider
/// @brief Provides the biomes specified in the JSON file.
diff --git a/src/Application/Layer/Sandbox/World/Blocks/BlockBuilder.cpp b/src/Application/Layer/Sandbox/World/Blocks/BlockBuilder.cpp
new file mode 100644
index 00000000..70e1f398
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Blocks/BlockBuilder.cpp
@@ -0,0 +1,41 @@
+#include "BlockBuilder.h"
+
+
+void BlockBuilder::DetermineAndSetFaceTexture(const std::string& face, const int x, const int y, TextureAtlas& textureAtlas) const
+{
+ if (face == "front") textureAtlas.SetSprite(_facesTextureCoordinates->front, x, y, false);
+ if (face == "back") textureAtlas.SetSprite(_facesTextureCoordinates->back, x, y, true);
+ if (face == "left") textureAtlas.SetSprite(_facesTextureCoordinates->left, x, y, true);
+ if (face == "right") textureAtlas.SetSprite(_facesTextureCoordinates->right, x, y, false);
+ if (face == "top") textureAtlas.SetSprite(_facesTextureCoordinates->top, x, y, false);
+ if (face == "bottom") textureAtlas.SetSprite(_facesTextureCoordinates->bottom, x, y, true);
+}
+
+BlockModel BlockBuilder::Build(const JsonData& blockData, TextureAtlas& textureAtlas) const
+{
+ for (const auto& textureData : blockData["textures"])
+ {
+ // ReSharper disable once CppZeroConstantCanBeReplacedWithNullptr
+ const int x = textureData["location"].value("column", 0);
+ // ReSharper disable once CppZeroConstantCanBeReplacedWithNullptr
+ const int y = textureData["location"].value("row", 0);
+
+ for (const auto& face : textureData["faces"])
+ {
+ DetermineAndSetFaceTexture(face, x, y, textureAtlas);
+ }
+ }
+
+ const BlockFaces faces
+ {
+ BlockFaceModel(_facesTextureCoordinates->front),
+ BlockFaceModel(_facesTextureCoordinates->back),
+ BlockFaceModel(_facesTextureCoordinates->left),
+ BlockFaceModel(_facesTextureCoordinates->right),
+ BlockFaceModel(_facesTextureCoordinates->top),
+ BlockFaceModel(_facesTextureCoordinates->bottom)
+ };
+
+ return BlockModel(faces);
+}
+
diff --git a/src/Application/Layer/Sandbox/World/Blocks/BlockBuilder.h b/src/Application/Layer/Sandbox/World/Blocks/BlockBuilder.h
new file mode 100644
index 00000000..2c02a567
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Blocks/BlockBuilder.h
@@ -0,0 +1,91 @@
+#pragma once
+#include "Core/Metadata.h"
+#include "Application/Layer/Sandbox/Model/BlockModel.h"
+#include "Application/Layer/Sandbox/Model/Surface/TextureAtlas.h"
+
+/// @class BlockBuilder
+/// @brief A factory that builds and outputs blocks based on their metadata.
+class BlockBuilder
+{
+ struct FacesUvTextureCoordinates
+ {
+ std::array front
+ {
+ Point{0.0f, 0.0f},
+ Point{1.0f, 0.0f},
+ Point{1.0f, 1.0f},
+ Point{0.0f, 1.0f},
+ };
+
+ std::array back
+ {
+ Point{0.0f, 0.0f},
+ Point{1.0f, 0.0f},
+ Point{1.0f, 1.0f},
+ Point{0.0f, 1.0f},
+ };
+
+ std::array left
+ {
+ Point{0.0f, 0.0f},
+ Point{1.0f, 0.0f},
+ Point{1.0f, 1.0f},
+ Point{0.0f, 1.0f},
+ };
+
+ std::array right
+ {
+ Point{0.0f, 0.0f},
+ Point{1.0f, 0.0f},
+ Point{1.0f, 1.0f},
+ Point{0.0f, 1.0f},
+ };
+
+ std::array top
+ {
+ Point{0.0f, 0.0f},
+ Point{1.0f, 0.0f},
+ Point{1.0f, 1.0f},
+ Point{0.0f, 1.0f},
+ };
+
+ std::array bottom
+ {
+ Point{0.0f, 0.0f},
+ Point{1.0f, 0.0f},
+ Point{1.0f, 1.0f},
+ Point{0.0f, 1.0f},
+ };
+ };
+
+ struct FaceMeshes
+ {
+ std::unique_ptr front;
+ std::unique_ptr back;
+ std::unique_ptr left;
+ std::unique_ptr right;
+ std::unique_ptr top;
+ std::unique_ptr bottom;
+ };
+
+ struct FaceTextures
+ {
+ std::shared_ptr front;
+ std::shared_ptr back;
+ std::shared_ptr left;
+ std::shared_ptr right;
+ std::shared_ptr top;
+ std::shared_ptr bottom;
+ };
+
+ std::shared_ptr _facesTextureCoordinates = std::make_shared();
+
+ void DetermineAndSetFaceTexture(const std::string& face, int x, int y, TextureAtlas& textureAtlas) const;
+
+public:
+
+ /// @brief Builds block based on the data.
+ /// @param blockData - Metadata of the block to be built.
+ /// @param textureAtlas - Texture atlas related to the block data.
+ BlockModel Build(const JsonData& blockData, TextureAtlas& textureAtlas) const;
+};
diff --git a/src/Application/Sandbox/World/Blocks/BlockMap.h b/src/Application/Layer/Sandbox/World/Blocks/BlockMap.h
similarity index 50%
rename from src/Application/Sandbox/World/Blocks/BlockMap.h
rename to src/Application/Layer/Sandbox/World/Blocks/BlockMap.h
index b511ec8c..7a5a1b92 100644
--- a/src/Application/Sandbox/World/Blocks/BlockMap.h
+++ b/src/Application/Layer/Sandbox/World/Blocks/BlockMap.h
@@ -1,23 +1,20 @@
#pragma once
#include "BlockProvider.h"
-#include "Application/Sandbox/Model/BlockModel.h"
+#include "Application/Layer/Sandbox/Model/BlockModel.h"
+#include "Application/Layer/Sandbox/Model/Surface/TextureAtlas.h"
/// @class BlockMap
/// @brief Represents a map of the blocks that could be used to place in the chunks.
class BlockMap
{
- Shader _blockShader = Shader("src/Data/Shaders/Block.vert", "src/Data/Shaders/Block.frag");
- std::vector _faceIndices
- {
- TriangleIndexes{0, 1, 2},
- TriangleIndexes{2, 3, 0}
- };
+ std::shared_ptr _blockTextures{};
std::unordered_map> _blockTypes;
+ Shader _blockShader{"src/Data/Shaders/Block.vert", "src/Data/Shaders/Block.frag"};
public:
/// @brief Copy constructor.
- BlockMap(const BlockMap&) = default;
+ BlockMap(const BlockMap&) = delete;
/// @brief Move constructor.
BlockMap(BlockMap&&) noexcept = default;
@@ -33,7 +30,12 @@ class BlockMap
explicit BlockMap(const std::string& filenameWithBlocksData)
{
auto blockProvider = BlockProvider(filenameWithBlocksData);
- _blockTypes = blockProvider.GetBlocks(_faceIndices, _blockShader);
+
+ const auto& textureName = blockProvider.GetTextureAtlasFilename();
+ const auto& textureSlotSize = blockProvider.GetTextureAtlasSlotSize();
+
+ _blockTextures = std::make_shared(textureName, textureSlotSize);
+ _blockTypes = blockProvider.GetBlocks(*_blockTextures);
}
/// @brief Returns the block model based on it's name.
@@ -43,5 +45,23 @@ class BlockMap
return _blockTypes.at(blockName);
}
+ /// @brief An operator that allows to get the block by its key in a convenient way.
+ std::shared_ptr& operator[](const std::string& blockName)
+ {
+ return _blockTypes.at(blockName);
+ }
+
+ /// @brief Returns the texture atlas that is used in this map.
+ std::shared_ptr& GetBlocksTexture()
+ {
+ return _blockTextures;
+ }
+
+ /// @brief Returns the blocks shader.
+ Shader& GetBlocksShader()
+ {
+ return _blockShader;
+ }
+
~BlockMap() = default;
};
diff --git a/src/Application/Sandbox/World/Blocks/BlockProvider.cpp b/src/Application/Layer/Sandbox/World/Blocks/BlockProvider.cpp
similarity index 57%
rename from src/Application/Sandbox/World/Blocks/BlockProvider.cpp
rename to src/Application/Layer/Sandbox/World/Blocks/BlockProvider.cpp
index 4391b406..f03c2a94 100644
--- a/src/Application/Sandbox/World/Blocks/BlockProvider.cpp
+++ b/src/Application/Layer/Sandbox/World/Blocks/BlockProvider.cpp
@@ -8,23 +8,31 @@ BlockProvider::BlockProvider(const std::string& filenameWithBlocksData)
}
std::unordered_map> BlockProvider::GetBlocks(
- std::vector& blockIndices,
- Shader& blockShader,
+ TextureAtlas& blocksTextureAtlas,
const std::string& blocksSetName)
{
const auto blocksSet = _blocksMetadata.GetJsonObject(blocksSetName);
-
- const std::string textureAtlasName = blocksSet.value("atlas", "");
- const size_t slotSize = blocksSet.value("slotSize", 0);
-
- auto builder = BlockBuilder(textureAtlasName, slotSize, blockIndices, blockShader);
auto blocks = std::unordered_map>();
for (const auto& blockData : blocksSet["blocks"])
{
const std::string name = blockData.value("block", "unknown");
- blocks[name] = std::make_shared(builder.Build(blockData));
+ const BlockBuilder builder;
+
+ blocks[name] = std::make_shared(builder.Build(blockData, blocksTextureAtlas));
}
return blocks;
}
+
+std::string BlockProvider::GetTextureAtlasFilename(const std::string& blocksSetName)
+{
+ const auto blocksSet = _blocksMetadata.GetJsonObject(blocksSetName);
+ return blocksSet.value("atlas", "");
+}
+
+size_t BlockProvider::GetTextureAtlasSlotSize(const std::string& blocksSetName)
+{
+ const auto blocksSet = _blocksMetadata.GetJsonObject(blocksSetName);
+ return blocksSet.value("slotSize", 0);
+}
diff --git a/src/Application/Layer/Sandbox/World/Blocks/BlockProvider.h b/src/Application/Layer/Sandbox/World/Blocks/BlockProvider.h
new file mode 100644
index 00000000..f7b8e4e0
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Blocks/BlockProvider.h
@@ -0,0 +1,31 @@
+#pragma once
+#include "Core/Metadata.h"
+#include "Application/Layer/Sandbox/Model/BlockModel.h"
+#include "Application/Layer/Sandbox/Model/Surface/TextureAtlas.h"
+
+/// @class BlockProvider
+/// @brief Provides all the blocks mentioned in the file.
+class BlockProvider
+{
+ Metadata _blocksMetadata;
+
+public:
+
+ /// @brief The constructor.
+ /// @param filenameWithBlocksData - Path to the JSON file containing the blocks metadata.
+ explicit BlockProvider(const std::string& filenameWithBlocksData);
+
+ /// @brief Provides the map of the built blocks.
+ /// @param blocksTextureAtlas - Texture atlas of the blocks to be built.
+ /// @param blocksSetName - Name of the blocks set that is used for this particular block map.
+ std::unordered_map> GetBlocks(TextureAtlas& blocksTextureAtlas, const std::string& blocksSetName = "default");
+
+ /// @brief Returns texture atlas filename of the blocks set.
+ /// @param blocksSetName - Name of the blocks set.
+ std::string GetTextureAtlasFilename(const std::string& blocksSetName = "default");
+
+ /// @brief Returns the sprite size defined in the set data.
+ /// @param blocksSetName - Name of the blocks set.
+ size_t GetTextureAtlasSlotSize(const std::string& blocksSetName = "default");
+};
+
diff --git a/src/Application/Layer/Sandbox/World/Chunks/ChunkBuilder.cpp b/src/Application/Layer/Sandbox/World/Chunks/ChunkBuilder.cpp
new file mode 100644
index 00000000..ce27bd67
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/ChunkBuilder.cpp
@@ -0,0 +1,14 @@
+#include "ChunkBuilder.h"
+
+#include "Application/Layer/Sandbox/World/Biomes/Biome.h"
+
+// ReSharper disable once CppMemberFunctionMayBeStatic
+std::unique_ptr ChunkBuilder::Build(const Position origin, const size_t& size, WorldGenerator& generator) const
+{
+ const auto chunkFrame = ChunkFrame{origin, size};
+ ChunkBlocks chunkBlocks;
+
+ generator.PaintChunk(chunkFrame, chunkBlocks);
+
+ return std::make_unique(chunkBlocks, generator.GetBlockMap().GetBlocksTexture(), size, generator.GetBlockMap().GetBlocksShader());
+}
diff --git a/src/Application/Layer/Sandbox/World/Chunks/ChunkBuilder.h b/src/Application/Layer/Sandbox/World/Chunks/ChunkBuilder.h
new file mode 100644
index 00000000..eb54c8bb
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/ChunkBuilder.h
@@ -0,0 +1,17 @@
+#pragma once
+#include "Application/Layer/Sandbox/World/WorldGenerator.h"
+#include "Structure/Chunk.h"
+
+/// @class ChunkBuilder
+/// @brief Builds chunks.
+class ChunkBuilder
+{
+public:
+
+ /// @brief Builds the chunk.
+ /// @param origin - origin of the chunk.
+ /// @param size - size of the chunks edge.
+ /// @param generator - the world generator that chunk uses to generate it's content.
+ std::unique_ptr Build(Position origin, const size_t& size, WorldGenerator& generator) const;
+};
+
diff --git a/src/Application/Layer/Sandbox/World/Chunks/ChunkPlacer.cpp b/src/Application/Layer/Sandbox/World/Chunks/ChunkPlacer.cpp
new file mode 100644
index 00000000..097e9a5e
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/ChunkPlacer.cpp
@@ -0,0 +1,123 @@
+#include "ChunkPlacer.h"
+
+std::vector ChunkPlacer::Subtract(const std::vector& aSet, const std::vector& bSet)
+{
+ std::vector result;
+
+ for (const auto& value : aSet)
+ {
+ if (std::find(bSet.begin(), bSet.end(), value) == bSet.end())
+ {
+ result.emplace_back(value);
+ }
+ }
+
+ return result;
+}
+
+Position ChunkPlacer::GetNormalizedPosition(const Point3D& position, const size_t& chunkSize) const
+{
+ auto normalizedPosition = position;
+
+ normalizedPosition /= chunkSize;
+
+ normalizedPosition.x = floor(normalizedPosition.x);
+ normalizedPosition.y = floor(normalizedPosition.y);
+ normalizedPosition.z = floor(normalizedPosition.z);
+
+ return {normalizedPosition};
+}
+
+std::string ChunkPlacer::PositionToString(const Position& position) const
+{
+ return std::to_string(position.x) + ", " +
+ std::to_string(position.y) + ", " +
+ std::to_string(position.z);
+}
+
+void ChunkPlacer::RemoveStaleChunks(const std::vector& currentChunksOrigins)
+{
+ std::vector staleChunksOrigins;
+
+ for (const auto& chunkData : _loadedChunks)
+ {
+ const auto origin = chunkData.first;
+ if (std::find(currentChunksOrigins.begin(), currentChunksOrigins.end(), origin) == currentChunksOrigins.end())
+ {
+ staleChunksOrigins.emplace_back(origin);
+ }
+ }
+
+ for (const auto& origin : staleChunksOrigins)
+ {
+ _log.Trace("Removed chunk: " + PositionToString(origin));
+ _loadedChunks.erase(origin);
+ }
+
+ _log.Debug("Finished removing stale chunks!");
+}
+
+void ChunkPlacer::AddNewChunks(const std::vector& currentChunksOrigins)
+{
+ for (const auto& origin : currentChunksOrigins)
+ {
+ if (_loadedChunks.find(origin) == _loadedChunks.end())
+ {
+ _log.Trace("Added chunk: " + PositionToString(origin));
+ _loadedChunks[origin] = _chunkBuilder.Build(origin, _order->GetChunkSize(), *_generator);
+ }
+ }
+
+ _log.Debug("Finished adding new chunks!");
+}
+
+void ChunkPlacer::UpdateChunksAround(const Position& normalizedOrigin)
+{
+ const auto currentChunksAroundOrigins = _order->GetChunksAround(normalizedOrigin);
+
+ RemoveStaleChunks(currentChunksAroundOrigins);
+ AddNewChunks(currentChunksAroundOrigins);
+}
+
+ChunkPlacer::ChunkPlacer(const OrderType orderType, const size_t chunkSize, const size_t renderDistance, const Position& initPosition)
+{
+ _previousNormalizedPosition = GetNormalizedPosition(initPosition, chunkSize);
+
+ switch (orderType)
+ {
+ case OrderType::cube:
+ _order = std::make_unique(renderDistance, chunkSize);
+ break;
+
+ case OrderType::diamond:
+ _order = std::make_unique(renderDistance, chunkSize);
+ break;
+
+ case OrderType::tiltedCube:
+ _order = std::make_unique(renderDistance, chunkSize);
+ break;
+ }
+}
+
+void ChunkPlacer::Update(const Position& position)
+{
+ const auto currentNormalizedPosition = GetNormalizedPosition(position, _order->GetChunkSize());
+
+ if (currentNormalizedPosition != _previousNormalizedPosition)
+ {
+ _previousNormalizedPosition = currentNormalizedPosition;
+ UpdateChunksAround(currentNormalizedPosition);
+
+ _log.Trace("Normalized position: " + PositionToString(currentNormalizedPosition));
+ }
+}
+
+void ChunkPlacer::Bind(std::shared_ptr generator)
+{
+ _generator = std::move(generator);
+}
+
+std::unordered_map>& ChunkPlacer::GetChunks()
+{
+ return _loadedChunks;
+}
diff --git a/src/Application/Layer/Sandbox/World/Chunks/ChunkPlacer.h b/src/Application/Layer/Sandbox/World/Chunks/ChunkPlacer.h
new file mode 100644
index 00000000..a61dfc8e
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/ChunkPlacer.h
@@ -0,0 +1,53 @@
+#pragma once
+#include "ChunkBuilder.h"
+#include "Application/Layer/Sandbox/Camera.h"
+#include "Application/Layer/Sandbox/World/WorldGenerator.h"
+#include "OrderType/OrderTypes.h"
+#include "Structure/Chunk.h"
+
+/// @class ChunkPlacer
+/// @brief Handles placing the chunks around the camera.
+/// @details This class handles @see Chunk objects and manages them for optimal experience.
+class ChunkPlacer
+{
+ Log& _log = Log::Get();
+ ChunkBuilder _chunkBuilder;
+
+ std::shared_ptr _generator;
+ std::unique_ptr _order;
+
+ Position _previousNormalizedPosition = {};
+ std::unordered_map> _loadedChunks = {};
+
+ static std::vector Subtract(const std::vector& aSet, const std::vector& bSet);
+ Position GetNormalizedPosition(const Point3D& position, const size_t& chunkSize) const;
+ std::string PositionToString(const Position& position) const;
+
+ void RemoveStaleChunks(const std::vector& currentChunksOrigins);
+ void AddNewChunks(const std::vector& currentChunksOrigins);
+
+ void UpdateChunksAround(const Position& normalizedOrigin);
+
+public:
+
+ /// @brief The constructor.
+ /// @param orderType - the way the chunks will be generated.
+ /// @param chunkSize - the size of the generated chunks.
+ /// @param renderDistance - specifies the maximum distance from the camera to render.
+ /// @param initPosition - position in space from where initialize the chunk placer.
+ ChunkPlacer(OrderType orderType, size_t chunkSize, size_t renderDistance, const Position& initPosition);
+
+ /// @brief Updates the chunk placer to adapt to the current frame.
+ /// @param position - Position around which chunks are going to be placed.
+ void Update(const Position& position);
+
+ /// @brief Binds world generator to the chunk placer.
+ /// @details The world generator is used to define how the world is generated, when
+ /// this class handles only displaying it in an optimal way.
+ /// @param generator - reference to the world generator.
+ void Bind(std::shared_ptr generator);
+
+ /// @brief Returns the map of placed chunks.
+ std::unordered_map>& GetChunks();
+};
+
diff --git a/src/Application/Layer/Sandbox/World/Chunks/ChunkRenderer.cpp b/src/Application/Layer/Sandbox/World/Chunks/ChunkRenderer.cpp
new file mode 100644
index 00000000..3e89cfcd
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/ChunkRenderer.cpp
@@ -0,0 +1,20 @@
+#include "ChunkRenderer.h"
+
+ChunkRenderer::ChunkRenderer()
+{
+ glCullFace(GL_FRONT);
+ glFrontFace(GL_CCW);
+}
+
+// ReSharper disable once CppMemberFunctionMayBeStatic
+void ChunkRenderer::Render(const std::unordered_map>& chunks, const Camera& camera) const
+{
+ glEnable(GL_CULL_FACE);
+
+ for (const auto& chunk : chunks)
+ {
+ chunk.second->Draw(camera);
+ }
+
+ glDisable(GL_CULL_FACE);
+}
diff --git a/src/Application/Layer/Sandbox/World/Chunks/ChunkRenderer.h b/src/Application/Layer/Sandbox/World/Chunks/ChunkRenderer.h
new file mode 100644
index 00000000..43e75fb4
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/ChunkRenderer.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "ChunkPlacer.h"
+
+/// @class ChunkRenderer
+/// @brief Supports rendering chunks.
+/// @details This class is responsible for rendering chunks around the camera by using the algorithms
+/// specified in the @see Order.
+class ChunkRenderer
+{
+ Log& _log = Log::Get();
+
+public:
+
+ /// @brief The constructor.
+ ChunkRenderer();
+
+ /// @brief Renders loaded chunks.
+ /// @param camera - A reference to the camera around which the objects are rendered.
+ /// @param chunks - Chunks to render with their positions on the map.
+ void Render(const std::unordered_map>& chunks, const Camera& camera) const;
+};
+
+
diff --git a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/CubeView.cpp b/src/Application/Layer/Sandbox/World/Chunks/OrderType/CubeOrder.cpp
similarity index 78%
rename from src/Application/Sandbox/World/Chunks/Rendring/RenderViews/CubeView.cpp
rename to src/Application/Layer/Sandbox/World/Chunks/OrderType/CubeOrder.cpp
index 59e7ee03..a85da5ed 100644
--- a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/CubeView.cpp
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/CubeOrder.cpp
@@ -1,12 +1,12 @@
-#include "CubeView.h"
+#include "CubeOrder.h"
-size_t CubeView::GetChunksAmount()
+size_t CubeOrder::GetChunksAmount()
{
const auto& chunkSize = GetChunkSize();
return chunkSize * chunkSize * chunkSize;
}
-std::vector CubeView::GetChunksAround(const glm::ivec3 normalizedOrigin)
+std::vector CubeOrder::GetChunksAround(const glm::ivec3 normalizedOrigin)
{
std::vector chunksPositions;
diff --git a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/CubeView.h b/src/Application/Layer/Sandbox/World/Chunks/OrderType/CubeOrder.h
similarity index 52%
rename from src/Application/Sandbox/World/Chunks/Rendring/RenderViews/CubeView.h
rename to src/Application/Layer/Sandbox/World/Chunks/OrderType/CubeOrder.h
index 090d2b20..c735435e 100644
--- a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/CubeView.h
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/CubeOrder.h
@@ -1,13 +1,13 @@
#pragma once
-#include "RenderView.h"
+#include "Order.h"
-/// @class CubeView
-/// @brief Provides an algorithm that the renderer renders chunks in as a cube.
+/// @class CubeOrder
+/// @brief Provides an algorithm for the ChunkPlacer to place the chunks in a cube manner.
/// @details Basically this algorithm returns origins formed in a cube.
-class CubeView final : public RenderView
+class CubeOrder final : public Order
{
public:
- using RenderView::RenderView;
+ using Order::Order;
size_t GetChunksAmount() override;
std::vector GetChunksAround(glm::ivec3 normalizedOrigin) override;
diff --git a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/DiamondView.cpp b/src/Application/Layer/Sandbox/World/Chunks/OrderType/DiamondOrder.cpp
similarity index 76%
rename from src/Application/Sandbox/World/Chunks/Rendring/RenderViews/DiamondView.cpp
rename to src/Application/Layer/Sandbox/World/Chunks/OrderType/DiamondOrder.cpp
index 82b4adf1..4d52fb2e 100644
--- a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/DiamondView.cpp
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/DiamondOrder.cpp
@@ -1,6 +1,6 @@
-#include "DiamondView.h"
+#include "DiamondOrder.h"
-size_t DiamondView::CountChunksRecursive(const size_t level)
+size_t DiamondOrder::CountChunksRecursive(const size_t level)
{
const auto result = 4 * level;
@@ -8,12 +8,12 @@ size_t DiamondView::CountChunksRecursive(const size_t level)
return result + CountChunksRecursive(level - 1);
}
-size_t DiamondView::GetChunksAmount()
+size_t DiamondOrder::GetChunksAmount()
{
return CountChunksRecursive(GetRenderDistance());
}
-std::vector DiamondView::GetChunksAround(const glm::ivec3 normalizedOrigin)
+std::vector DiamondOrder::GetChunksAround(const glm::ivec3 normalizedOrigin)
{
std::vector chunksPositions;
diff --git a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/DiamondView.h b/src/Application/Layer/Sandbox/World/Chunks/OrderType/DiamondOrder.h
similarity index 58%
rename from src/Application/Sandbox/World/Chunks/Rendring/RenderViews/DiamondView.h
rename to src/Application/Layer/Sandbox/World/Chunks/OrderType/DiamondOrder.h
index eb5c21fe..d81834ee 100644
--- a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/DiamondView.h
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/DiamondOrder.h
@@ -1,15 +1,15 @@
#pragma once
-#include "RenderView.h"
+#include "Order.h"
-/// @class DiamondView
-/// @brief Provides an algorithm that the renderer renders chunks in as a diamond.
+/// @class DiamondOrder
+/// @brief Provides an algorithm for the ChunkPlacer to place the chunks in a diamond manner.
/// @note Here is the explanation.
-class DiamondView final : public RenderView
+class DiamondOrder final : public Order
{
static size_t CountChunksRecursive(size_t level);
public:
- using RenderView::RenderView;
+ using Order::Order;
size_t GetChunksAmount() override;
std::vector GetChunksAround(glm::ivec3 normalizedOrigin) override;
diff --git a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/RenderView.h b/src/Application/Layer/Sandbox/World/Chunks/OrderType/Order.h
similarity index 77%
rename from src/Application/Sandbox/World/Chunks/Rendring/RenderViews/RenderView.h
rename to src/Application/Layer/Sandbox/World/Chunks/OrderType/Order.h
index b00d62ec..a6eecd48 100644
--- a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/RenderView.h
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/Order.h
@@ -2,11 +2,11 @@
#include
#include
-/// @class RenderView
-/// @brief The base class for creating render views.
-/// @details A render view is a class providing the algorithm, by which
-/// the chunks are rendered.
-class RenderView // NOLINT(cppcoreguidelines-special-member-functions)
+/// @class Order
+/// @brief The base class for creating placing order types.
+/// @details An order type is a class providing an algorithm, by which
+/// the chunks are placer by the ChunkPlacer.
+class Order // NOLINT(cppcoreguidelines-special-member-functions)
{
size_t _renderDistance;
size_t _chunkSize;
@@ -16,7 +16,7 @@ class RenderView // NOLINT(cppcoreguidelines-special-member-functions)
/// @brief The constructor.
/// @param renderDistance - the maximum distance from the camera to render.
/// @param chunkSize - the size of the generated chunks.
- RenderView(const size_t& renderDistance, const size_t& chunkSize)
+ Order(const size_t& renderDistance, const size_t& chunkSize)
: _renderDistance(renderDistance), _chunkSize(chunkSize)
{}
@@ -53,5 +53,5 @@ class RenderView // NOLINT(cppcoreguidelines-special-member-functions)
/// @brief Get the amount of chunks that could be generated on the current render distance settings.
virtual std::vector GetChunksAround(glm::ivec3 normalizedOrigin) = 0;
- virtual ~RenderView() = default;
+ virtual ~Order() = default;
};
diff --git a/src/Application/Layer/Sandbox/World/Chunks/OrderType/OrderTypes.h b/src/Application/Layer/Sandbox/World/Chunks/OrderType/OrderTypes.h
new file mode 100644
index 00000000..513d7e74
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/OrderTypes.h
@@ -0,0 +1,12 @@
+// ReSharper disable CppUnusedIncludeDirective
+#pragma once
+#include "CubeOrder.h"
+#include "DiamondOrder.h"
+#include "TiltedCubeOrder.h"
+
+enum class OrderType
+{
+ cube = 0,
+ diamond,
+ tiltedCube
+};
\ No newline at end of file
diff --git a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/TiltedCube.cpp b/src/Application/Layer/Sandbox/World/Chunks/OrderType/TiltedCubeOrder.cpp
similarity index 77%
rename from src/Application/Sandbox/World/Chunks/Rendring/RenderViews/TiltedCube.cpp
rename to src/Application/Layer/Sandbox/World/Chunks/OrderType/TiltedCubeOrder.cpp
index b89ee218..57be7e4c 100644
--- a/src/Application/Sandbox/World/Chunks/Rendring/RenderViews/TiltedCube.cpp
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/TiltedCubeOrder.cpp
@@ -1,12 +1,12 @@
-#include "TiltedCube.h"
+#include "TiltedCubeOrder.h"
-size_t TiltedCube::GetChunksAmount()
+size_t TiltedCubeOrder::GetChunksAmount()
{
const auto& r = GetChunkSize();
return (r + 1) * ((r + 1) * (r + 1) + r * r);
}
-std::vector TiltedCube::GetChunksAround(const glm::ivec3 normalizedOrigin)
+std::vector TiltedCubeOrder::GetChunksAround(const glm::ivec3 normalizedOrigin)
{
std::vector chunksPositions;
diff --git a/src/Application/Layer/Sandbox/World/Chunks/OrderType/TiltedCubeOrder.h b/src/Application/Layer/Sandbox/World/Chunks/OrderType/TiltedCubeOrder.h
new file mode 100644
index 00000000..6d7de627
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/OrderType/TiltedCubeOrder.h
@@ -0,0 +1,15 @@
+#pragma once
+#include "Order.h"
+
+/// @class TiltedCubeOrder
+/// @brief Provides an algorithm for the ChunkPlacer to place the chunks in a tilted cube manner.
+/// @details A tilted cube is just a regular cube that it's edges are pointing cardinal directions.
+class TiltedCubeOrder final : public Order
+{
+public:
+ using Order::Order;
+
+ size_t GetChunksAmount() override;
+ std::vector GetChunksAround(glm::ivec3 normalizedOrigin) override;
+};
+
diff --git a/src/Application/Layer/Sandbox/World/Chunks/Structure/Chunk.cpp b/src/Application/Layer/Sandbox/World/Chunks/Structure/Chunk.cpp
new file mode 100644
index 00000000..395666ba
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/Structure/Chunk.cpp
@@ -0,0 +1,18 @@
+#include "Chunk.h"
+
+
+Chunk::Chunk(const size_t& size, std::shared_ptr blocksTexture, Shader& shader) :
+ _mesh(ChunkMesh(shader, size)), _blockTexture(std::move(blocksTexture))
+{
+}
+
+Chunk::Chunk(ChunkBlocks blocks, std::shared_ptr blocksTexture, const size_t& size, Shader& shader) : _mesh(ChunkMesh(shader, size)), _blockTexture(
+ std::move(blocksTexture)), _blocks(std::move(blocks))
+{
+ _mesh.Rebuild(_blocks);
+}
+
+void Chunk::Draw(const Camera& camera) const
+{
+ _mesh.Draw(*_blockTexture, camera);
+}
diff --git a/src/Application/Layer/Sandbox/World/Chunks/Structure/Chunk.h b/src/Application/Layer/Sandbox/World/Chunks/Structure/Chunk.h
new file mode 100644
index 00000000..3e78c4ee
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/Structure/Chunk.h
@@ -0,0 +1,37 @@
+#pragma once
+#include "Application/Layer/Sandbox/Camera.h"
+#include "ChunkBlocks.h"
+#include "ChunkMesh.h"
+#include "Application/Layer/Sandbox/Model/Mesh/DynamicMesh.h"
+
+/// @class Chunk
+/// @brief Represents a single chunk placed in the world
+/// @details This class handles managing the generated chunk at the certain position.
+class Chunk
+{
+ ChunkMesh _mesh;
+ std::shared_ptr _blockTexture;
+ ChunkBlocks _blocks;
+
+public:
+
+ /// @brief The constructor.
+ /// @param size - Size of the chunk edge.
+ /// @param blocksTexture - Texture atlas of the blocks inside the chunk.
+ /// @param shader - Reference to the blocks shader.
+ explicit Chunk(const size_t& size, std::shared_ptr blocksTexture, Shader& shader);
+
+ /// @brief The constructor.
+ /// @details The chunk on initialization knows it's position, the structure to render (blocks)
+ /// and the player position for proper displaying blocks while the player is moving.
+ /// @param blocks - The blocks inside the chunk.
+ /// @param blocksTexture - Texture atlas of the blocks inside the chunk.
+ /// @param size - Size of the chunks edge.
+ /// @param shader - Reference to the blocks shader.
+ explicit Chunk(ChunkBlocks blocks, std::shared_ptr blocksTexture, const size_t& size, Shader& shader);
+
+ /// @brief Draws the chunk in the world.
+ /// @param camera - reference to the camera so that the blocks could be seen.
+ void Draw(const Camera& camera) const;
+};
+
diff --git a/src/Application/Sandbox/World/Chunks/Structure/ChunkBlocks.h b/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkBlocks.h
similarity index 55%
rename from src/Application/Sandbox/World/Chunks/Structure/ChunkBlocks.h
rename to src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkBlocks.h
index 6689692b..10792b1b 100644
--- a/src/Application/Sandbox/World/Chunks/Structure/ChunkBlocks.h
+++ b/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkBlocks.h
@@ -1,5 +1,5 @@
#pragma once
-#include "Application/Sandbox/Model/BlockModel.h"
+#include "Application/Layer/Sandbox/Model/BlockModel.h"
/// @brief Contains the information about a certain block and the visibility of its faces.
struct BlockVisibility
@@ -22,43 +22,19 @@ template <>
struct std::hash
{
/// @brief Definition of how to handle the passed origin as a key in the map.
- size_t operator()(const Position &origin) const noexcept
+ size_t operator()(const Position& origin) const noexcept
{
return std::hash()
(
- std::to_string(origin.x) +
- std::to_string(origin.y) +
+ std::to_string(origin.x) + "." +
+ std::to_string(origin.y) + "." +
std::to_string(origin.z)
);
}
};
-/// @class ChunkBlocks
/// @brief A structure that represents the body of typical chunk. Blocks and their visibility.
-class ChunkBlocks
-{
-public:
-
- /// @brief The constructor.
- ChunkBlocks() = default;
-
- /// @brief Copy constructor.
- ChunkBlocks(const ChunkBlocks&) = default;
-
- /// @brief Move constructor.
- ChunkBlocks(ChunkBlocks&&) noexcept = default;
-
- /// @brief Copy assignment constructor.
- ChunkBlocks &operator=(const ChunkBlocks &) = default;
-
- /// @brief Move assignment constructor.
- ChunkBlocks &operator=(ChunkBlocks &&) noexcept = default;
-
- /// @brief Map with blocks that are placed inside the chunk.
- /// @details This map contains all blocks that are included in the chunk
- /// and maps the location of the block as a key, and it's model and
- /// faces visibility as a key.
- std::unordered_map block;
-
- ~ChunkBlocks() = default;
-};
+/// @details This map contains all blocks that are included in the chunk
+/// and maps the location of the block as a key, and it's model and
+/// faces visibility as a key.
+using ChunkBlocks = std::unordered_map;
diff --git a/src/Application/Sandbox/World/Chunks/Structure/ChunkFrame.h b/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkFrame.h
similarity index 100%
rename from src/Application/Sandbox/World/Chunks/Structure/ChunkFrame.h
rename to src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkFrame.h
diff --git a/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkMesh.cpp b/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkMesh.cpp
new file mode 100644
index 00000000..1fa8b0b2
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkMesh.cpp
@@ -0,0 +1,52 @@
+#include "ChunkMesh.h"
+
+void ChunkMesh::AddFaceToMesh(
+ const Position& origin,
+ const std::array& faceVertices,
+ const std::array& faceTextureCoordinates,
+ std::vector& mesh)
+{
+ constexpr auto quadVerticesCount = 4;
+ for (auto i = 0; i < quadVerticesCount; ++i)
+ {
+ mesh.emplace_back(Vertex{faceVertices[i] + Point3D(origin), faceTextureCoordinates[i]});
+ }
+}
+
+ChunkMesh::ChunkMesh(Shader& blockShader, const size_t& sizeOfChunk) : _blockShader(blockShader)
+{
+ const std::vector indicesPattern =
+ {
+ TriangleIndexes{0, 1, 2},
+ TriangleIndexes{2, 3, 0}
+ };
+ const auto maxInstancesAmount = sizeOfChunk * sizeOfChunk * sizeOfChunk;
+
+ _mesh = std::make_unique(std::vector(), indicesPattern, _blockShader, maxInstancesAmount);
+}
+
+void ChunkMesh::Rebuild(const ChunkBlocks& blocks) const
+{
+ std::vector vertices;
+
+ for (const auto& block : blocks)
+ {
+ auto& origin = block.first;
+ auto& faceModels = block.second.model->GetFaces();
+ const auto& facesVisibility = block.second.visibility;
+
+ if (facesVisibility.front) AddFaceToMesh(origin, _faceVertices.front, faceModels.front.GetUvCoordinates(), vertices);
+ if (facesVisibility.back) AddFaceToMesh(origin, _faceVertices.back, faceModels.back.GetUvCoordinates(), vertices);
+ if (facesVisibility.left) AddFaceToMesh(origin, _faceVertices.left, faceModels.left.GetUvCoordinates(), vertices);
+ if (facesVisibility.right) AddFaceToMesh(origin, _faceVertices.right, faceModels.right.GetUvCoordinates(), vertices);
+ if (facesVisibility.top) AddFaceToMesh(origin, _faceVertices.top, faceModels.top.GetUvCoordinates(), vertices);
+ if (facesVisibility.bottom) AddFaceToMesh(origin, _faceVertices.bottom, faceModels.bottom.GetUvCoordinates(), vertices);
+ }
+
+ _mesh->Update(vertices);
+}
+
+void ChunkMesh::Draw(const Texture& blocksTexture, const Camera& camera) const
+{
+ _mesh->Draw(blocksTexture, camera);
+}
diff --git a/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkMesh.h b/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkMesh.h
new file mode 100644
index 00000000..437d2943
--- /dev/null
+++ b/src/Application/Layer/Sandbox/World/Chunks/Structure/ChunkMesh.h
@@ -0,0 +1,94 @@
+#pragma once
+#include "ChunkBlocks.h"
+#include "Application/Layer/Sandbox/Model/Mesh/DynamicMesh.h"
+
+/// @class ChunkMesh
+/// @brief Represents the chunk mesh and manages it in a runtime.
+class ChunkMesh
+{
+ std::unique_ptr _mesh = nullptr;
+ Shader& _blockShader;
+
+ struct FaceVertices
+ {
+ std::array front
+ {
+ {
+ Point3D{0.0f, 0.0f, 0.0f},
+ Point3D{1.0f, 0.0f, 0.0f},
+ Point3D{1.0f, 1.0f, 0.0f},
+ Point3D{0.0f, 1.0f, 0.0f}
+ }
+ };
+
+ std::array back
+ {
+ {
+ Point3D{0.0f, 0.0f, 1.0f},
+ Point3D{0.0f, 1.0f, 1.0f},
+ Point3D{1.0f, 1.0f, 1.0f},
+ Point3D{1.0f, 0.0f, 1.0f}
+ }
+ };
+
+ std::array left
+ {
+ {
+ Point3D{0.0f, 0.0f, 0.0f},
+ Point3D{0.0f, 1.0f, 0.0f},
+ Point3D{0.0f, 1.0f, 1.0f},
+ Point3D{0.0f, 0.0f, 1.0f}
+ }
+ };
+
+ std::array right
+ {
+ {
+ Point3D{1.0f, 0.0f, 0.0f},
+ Point3D{1.0f, 0.0f, 1.0f},
+ Point3D{1.0f, 1.0f, 1.0f},
+ Point3D{1.0f, 1.0f, 0.0f}
+ }
+ };
+
+ std::array top
+ {
+ {
+ Point3D{0.0f, 1.0f, 0.0f},
+ Point3D{1.0f, 1.0f, 0.0f},
+ Point3D{1.0f, 1.0f, 1.0f},
+ Point3D{0.0f, 1.0f, 1.0f}
+ }
+ };
+
+ std::array bottom
+ {
+ {
+ Point3D{0.0f, 0.0f, 0.0f},
+ Point3D{0.0f, 0.0f, 1.0f},
+ Point3D{1.0f, 0.0f, 1.0f},
+ Point3D{1.0f, 0.0f, 0.0f},
+ }
+ };
+ };
+ const FaceVertices _faceVertices;
+
+ static void AddFaceToMesh(const Position& origin, const std::array& faceVertices, const std::array& faceTextureCoordinates, std::vector& mesh);
+
+public:
+
+ /// @brief The constructor.
+ /// @param blockShader - Shader of the blocks inside the chunk.
+ /// @param sizeOfChunk - Size of the chunk edge.
+ explicit ChunkMesh(Shader& blockShader, const size_t& sizeOfChunk);
+
+ /// @brief Rebuilds the mesh basing on the passed blocks.
+ /// @param blocks - Blocks inside the chunk.
+ void Rebuild(const ChunkBlocks& blocks) const;
+
+ /// @brief Renders blocks inside the chunk.
+ /// @param blocksTexture - The texture that blocks uses.
+ /// @param camera - Reference to the camera, so the blocks could be seen.
+ void Draw(const Texture& blocksTexture, const Camera& camera) const;
+};
+
diff --git a/src/Application/Sandbox/World/WorldGenerator.cpp b/src/Application/Layer/Sandbox/World/WorldGenerator.cpp
similarity index 89%
rename from src/Application/Sandbox/World/WorldGenerator.cpp
rename to src/Application/Layer/Sandbox/World/WorldGenerator.cpp
index e7cf7623..c04e8d46 100644
--- a/src/Application/Sandbox/World/WorldGenerator.cpp
+++ b/src/Application/Layer/Sandbox/World/WorldGenerator.cpp
@@ -16,3 +16,8 @@ void WorldGenerator::PaintChunk(const ChunkFrame& frame, ChunkBlocks& blocks) co
_placer->PaintChunk(frame, blocks);
WorldGeneratorUtils::OptimizeChunk(frame, blocks, *_placer);
}
+
+BlockMap& WorldGenerator::GetBlockMap()
+{
+ return _blockMap;
+}
diff --git a/src/Application/Sandbox/World/WorldGenerator.h b/src/Application/Layer/Sandbox/World/WorldGenerator.h
similarity index 90%
rename from src/Application/Sandbox/World/WorldGenerator.h
rename to src/Application/Layer/Sandbox/World/WorldGenerator.h
index e392716e..c4e96c93 100644
--- a/src/Application/Sandbox/World/WorldGenerator.h
+++ b/src/Application/Layer/Sandbox/World/WorldGenerator.h
@@ -25,4 +25,7 @@ class WorldGenerator
/// @param frame - the frame of the chunk.
/// @param blocks - the blocks inside the chunk.
void PaintChunk(const ChunkFrame& frame, ChunkBlocks& blocks) const;
+
+ /// @brief Returns the map of blocks used by this generator.
+ BlockMap& GetBlockMap();
};
diff --git a/src/Application/Sandbox/World/WorldGeneratorUtils.cpp b/src/Application/Layer/Sandbox/World/WorldGeneratorUtils.cpp
similarity index 81%
rename from src/Application/Sandbox/World/WorldGeneratorUtils.cpp
rename to src/Application/Layer/Sandbox/World/WorldGeneratorUtils.cpp
index 662cbda8..f8da6b3b 100644
--- a/src/Application/Sandbox/World/WorldGeneratorUtils.cpp
+++ b/src/Application/Layer/Sandbox/World/WorldGeneratorUtils.cpp
@@ -16,9 +16,9 @@ void WorldGeneratorUtils::OptimizeBlock(const Position& origin, BlockVisibility&
factor = -factor;
factor *= frameSize;
- const int& x = static_cast(factor.x) + static_cast(origin.x) + 1;
- const int& y = static_cast(factor.y) + static_cast(origin.y) + 1;
- const int& z = static_cast(factor.z) + static_cast(origin.z) + 1;
+ const int& x = static_cast(factor.x) + origin.x + 1;
+ const int& y = static_cast(factor.y) + origin.y + 1;
+ const int& z = static_cast(factor.z) + origin.z + 1;
block.visibility = {false, false, false, false, false, false};
@@ -36,7 +36,7 @@ void WorldGeneratorUtils::OptimizeChunk(const ChunkFrame& frame, ChunkBlocks& bl
{
const auto noise = biomePlacer.GetChunkNoise(frame, 1);
- for (auto& block : blocks.block)
+ for (auto& block : blocks)
{
OptimizeBlock(block.first, block.second, noise);
}
diff --git a/src/Application/Sandbox/World/WorldGeneratorUtils.h b/src/Application/Layer/Sandbox/World/WorldGeneratorUtils.h
similarity index 100%
rename from src/Application/Sandbox/World/WorldGeneratorUtils.h
rename to src/Application/Layer/Sandbox/World/WorldGeneratorUtils.h
diff --git a/src/Application/LayerStack/LayerStack.h b/src/Application/LayerStack/LayerStack.h
new file mode 100644
index 00000000..a573cc12
--- /dev/null
+++ b/src/Application/LayerStack/LayerStack.h
@@ -0,0 +1,52 @@
+#pragma once
+#include
+#include
+
+#include "Application/Layer/Layer.h"
+
+
+/// @class LayerStack
+/// @brief Represents the stack that can process layers of content that
+/// is displayed on the screen.
+/// @details This structure handles the priority of what should be interactive on the screen.
+class LayerStack
+{
+ std::vector> _layers{};
+
+public:
+
+ /// @brief Pushes the layer onto the stack.
+ void Push(std::unique_ptr layer)
+ {
+ _layers.emplace_back(std::move(layer));
+ }
+
+ /// @brief Pops the layer from the stack.
+ void Pop()
+ {
+ _layers.pop_back();
+ }
+
+ /// @brief Calls the OnUpdate() methods of the layers.
+ void Update() const
+ {
+ for (const auto& layer : _layers)
+ {
+ layer->OnUpdate();
+ }
+ }
+
+ /// @brief Calls the OnEvent() methods of the layers respecting the lock
+ /// @param hid - Reference to the Human Interface Device.
+ void ProcessEvents(HumanInterfaceDevice& hid) const
+ {
+ for (auto i = _layers.size(); i > 0; --i)
+ {
+ auto& layer = _layers[i - 1];
+
+ layer->OnEvent(hid);
+ if (layer->IsLocked()) break;
+ }
+ }
+};
+
diff --git a/src/Application/LayerStack/Stack/SandboxStack.h b/src/Application/LayerStack/Stack/SandboxStack.h
new file mode 100644
index 00000000..46749e8b
--- /dev/null
+++ b/src/Application/LayerStack/Stack/SandboxStack.h
@@ -0,0 +1,19 @@
+#pragma once
+#include "Application/Layer/PauseMenu/PauseMenuLayer.h"
+#include "Application/Layer/Sandbox/SandboxLayer.h"
+#include "Application/LayerStack/LayerStack.h"
+
+/// @class SandboxStack
+/// @brief Represents the stack responsible for the full simulation of the sandbox.
+class SandboxStack final : public LayerStack
+{
+public:
+
+ /// @brief The constructor.
+ /// @param window - Reference to the window.
+ explicit SandboxStack(Window& window)
+ {
+ Push(std::make_unique(window));
+ Push(std::make_unique());
+ }
+};
diff --git a/src/Application/Sandbox/Camera.cpp b/src/Application/Sandbox/Camera.cpp
deleted file mode 100644
index 40eb9a33..00000000
--- a/src/Application/Sandbox/Camera.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-#include "Camera.h"
-
-Camera::Camera(Window& window, const glm::vec3 position, HumanInterfaceDevice& hid) : _window(window), _position(position), _hid(hid)
-{
- glfwSetInputMode(_window.GetHandle(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
-}
-
-void Camera::Update()
-{
- // ReSharper disable once CppInitializedValueIsAlwaysRewritten
- auto view = glm::mat4(1.0f);
- view = lookAt(_position, _position + _orientation, _up);
-
- const float aspectRatio = static_cast(_window.GetWidth()) / static_cast(_window.GetHeight());
-
- // ReSharper disable once CppInitializedValueIsAlwaysRewritten
- auto projection = glm::mat4(1.0f);
- projection = glm::perspective(glm::radians(_fieldOfView), aspectRatio, _nearPane, _farPane);
-
- _orthographicProjection = projection * view;
-}
-
-void Camera::HandleHorizontalMovement(const KeyboardKey& left, const KeyboardKey& right, const KeyboardKey& forward,
- const KeyboardKey& backward)
-{
- if (_hid.IsPressed(left))
- {
- _position += _speed * -normalize(cross(_orientation, _up));
- }
- if (_hid.IsPressed(right))
- {
- _position += _speed * normalize(cross(_orientation, _up));
- }
- if (_hid.IsPressed(forward))
- {
- _position += _speed * _orientation;
- }
- if (_hid.IsPressed(backward))
- {
- _position += _speed * -_orientation;
- }
-}
-
-void Camera::HandleVerticalMovement(const KeyboardKey& up, const KeyboardKey& down)
-{
- if (_hid.IsPressed(up))
- {
- _position += _speed * _up;
- }
- if (_hid.IsPressed(down))
- {
- _position += _speed * -_up;
- }
-}
-
-void Camera::HandleSpeed(const KeyboardKey& boost, const float boostSpeed)
-{
- _speed = _hid.IsPressed(boost) ? boostSpeed : _defaultSpeed;
-}
-
-void Camera::HandleCursorMovement()
-{
- double mouseX;
- double mouseY;
- glfwGetCursorPos(_window.GetHandle(), &mouseX, &mouseY);
-
- const double middleAxisX = static_cast(_window.GetWidth()) / 2.0;
- const double middleAxisY = static_cast(_window.GetHeight()) / 2.0;
-
- const float xAxisRotation = _sensitivity * (static_cast(mouseY - middleAxisY) / static_cast(_window.GetHeight()));
- const float yAxisRotation = _sensitivity * (static_cast(mouseX - middleAxisX) / static_cast(_window.GetWidth()));
-
- const auto orientation = rotate(_orientation, glm::radians(-xAxisRotation), normalize(cross(_orientation, _up)));
- const auto angleWithXAxis = abs(angle(orientation, _up) - glm::radians(90.0f));
-
- // This prevents the barrel roll situation when looking up
- if (angleWithXAxis < glm::radians(85.0f))
- {
- _orientation = orientation;
- }
-
- _orientation = rotate(_orientation, glm::radians(-yAxisRotation), _up);
- glfwSetCursorPos(_window.GetHandle(), middleAxisX, middleAxisY);
-}
-
-void Camera::Bind(Shader const& shader) const
-{
- shader.Load();
- glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "camera"), 1, GL_FALSE, value_ptr(_orthographicProjection));
-}
-
-void Camera::HandleInput()
-{
-
- if (_hid.IsPressedOnce(KeyboardKey::escape))
- {
- _isPaused = !_isPaused;
- if (_isPaused)
- {
- glfwSetInputMode(_window.GetHandle(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- }
- else
- {
- glfwSetInputMode(_window.GetHandle(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- }
- }
-
- if (_isPaused)
- {
- return;
- }
-
- HandleHorizontalMovement(KeyboardKey::a, KeyboardKey::d, KeyboardKey::w, KeyboardKey::s);
- HandleVerticalMovement(KeyboardKey::space, KeyboardKey::leftCtrl);
- HandleSpeed(KeyboardKey::leftShift, 0.4f);
- HandleCursorMovement();
-}
-
-glm::vec3 Camera::GetPosition() const
-{
- return _position;
-}
-
-inline size_t Camera::GetWidth() const
-{
- return _window.GetWidth();
-}
-
-inline size_t Camera::GetHeight() const
-{
- return _window.GetHeight();
-}
-
-inline float Camera::GetDefaultSpeed() const
-{
- return _defaultSpeed;
-}
-
-inline void Camera::SetDefaultSpeed(const float defaultSpeed)
-{
- _defaultSpeed = defaultSpeed;
-}
-
-inline float Camera::GetSpeed() const
-{
- return _speed;
-}
-
-inline void Camera::SetSpeed(const float speed)
-{
- _speed = speed;
-}
-
-inline float Camera::GetSensitivity() const
-{
- return _sensitivity;
-}
-
-inline void Camera::SetSensitivity(const float sensitivity)
-{
- _sensitivity = sensitivity;
-}
-
-inline float Camera::GetFieldOfView() const
-{
- return _fieldOfView;
-}
-
-inline void Camera::SetFieldOfView(const float fieldOfView)
-{
- _fieldOfView = fieldOfView;
-}
-
-inline float Camera::GetNearPane() const
-{
- return _nearPane;
-}
-
-inline void Camera::SetNearPane(const float nearPane)
-{
- _nearPane = nearPane;
-}
-
-inline float Camera::GetFarPane() const
-{
- return _farPane;
-}
-
-inline void Camera::SetFarPane(const float farPane)
-{
- _farPane = farPane;
-}
\ No newline at end of file
diff --git a/src/Application/Sandbox/Events/HumanInterfaceDevice.cpp b/src/Application/Sandbox/Events/HumanInterfaceDevice.cpp
deleted file mode 100644
index a3e74e3e..00000000
--- a/src/Application/Sandbox/Events/HumanInterfaceDevice.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "HumanInterfaceDevice.h"
-
-std::string HumanInterfaceDevice::KeyDescription(const KeyboardKey& key) const
-{
- switch(key)
- {
- case KeyboardKey::a: return "A";
- case KeyboardKey::d: return "D";
- case KeyboardKey::s: return "S";
- case KeyboardKey::w: return "W";
-
- case KeyboardKey::escape: return "ESC";
- case KeyboardKey::space: return "SPACE";
- case KeyboardKey::leftShift: return "LEFT SHIFT";
- case KeyboardKey::rightShift: return "RIGHT SHIFT";
- case KeyboardKey::leftCtrl: return "LEFT CTRL";
- case KeyboardKey::rightCtrl: return "RIGHT CTRL";
- }
-
- _log.Warn("Key code " + std::to_string(static_cast(key)) + " description not found!");
- return std::to_string(static_cast(key));
-}
-
-std::string HumanInterfaceDevice::ButtonDescription(const MouseButton& button) const
-{
- switch(button)
- {
- case MouseButton::left: return "LEFT BUTTON";
- case MouseButton::right: return "RIGHT BUTTON";
- }
-
- _log.Warn("Button code " + std::to_string(static_cast(button)) + " description not found!");
- return std::to_string(static_cast(button));
-}
-
-int HumanInterfaceDevice::GetState(const KeyboardKey& key) const
-{
- return glfwGetKey(_window, static_cast(key));
-}
-
-int HumanInterfaceDevice::GetState(const MouseButton& button) const
-{
- return glfwGetMouseButton(_window, static_cast(button));
-}
-
-HumanInterfaceDevice::HumanInterfaceDevice(GLFWwindow* window) : _window(window)
-{
-}
-
-bool HumanInterfaceDevice::IsPressed(const KeyboardKey& key) const
-{
- if (GetState(key) == GLFW_PRESS)
- {
- _log.Trace("Key pressed: " + KeyDescription(key));
- return true;
- }
-
- return false;
-}
-
-bool HumanInterfaceDevice::IsPressedOnce(const KeyboardKey& key)
-{
- if (GetState(key) == GLFW_PRESS && _onceHandledKeyboardKeys.find(key) == _onceHandledKeyboardKeys.end())
- {
- _onceHandledKeyboardKeys.insert(key);
- return IsPressed(key);
- }
-
- if (IsReleased(key))
- {
- _onceHandledKeyboardKeys.erase(key);
- }
-
- return false;
-}
-
-bool HumanInterfaceDevice::IsReleased(const KeyboardKey& key) const
-{
- return GetState(key) == GLFW_RELEASE;
-}
-
-bool HumanInterfaceDevice::IsPressed(const MouseButton& button) const
-{
- if (GetState(button) == GLFW_PRESS)
- {
- _log.Trace("Button pressed: " + ButtonDescription(button));
- return true;
- }
-
- return false;
-}
-
-bool HumanInterfaceDevice::IsPressedOnce(const MouseButton& button)
-{
- if (GetState(button) == GLFW_PRESS && _onceHandledMouseButtons.find(button) == _onceHandledMouseButtons.end())
- {
- _onceHandledMouseButtons.insert(button);
- return IsPressed(button);
- }
-
- if (IsReleased(button))
- {
- _onceHandledMouseButtons.erase(button);
- }
-
- return false;
-}
-
-bool HumanInterfaceDevice::IsReleased(const MouseButton& button) const
-{
- return GetState(button) == GLFW_RELEASE;
-}
diff --git a/src/Application/Sandbox/Model/BlockFaceModel.cpp b/src/Application/Sandbox/Model/BlockFaceModel.cpp
deleted file mode 100644
index ab5c707c..00000000
--- a/src/Application/Sandbox/Model/BlockFaceModel.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "BlockFaceModel.h"
-
-BlockFaceModel::BlockFaceModel(std::unique_ptr& mesh, std::shared_ptr texture)
-{
- _mesh = std::move(mesh);
- _texture = std::move(texture);
-}
-
-void BlockFaceModel::Draw(const glm::vec3& origin, const Camera& camera) const
-{
- _mesh->Draw(origin, *_texture, camera);
-}
diff --git a/src/Application/Sandbox/Model/BlockFaceModel.h b/src/Application/Sandbox/Model/BlockFaceModel.h
deleted file mode 100644
index 49a6ebb9..00000000
--- a/src/Application/Sandbox/Model/BlockFaceModel.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-#include
-
-#include "Mesh/Mesh.h"
-
-/// @class BlockFaceModel
-/// @brief Represents face of a @see BlockModel.
-class BlockFaceModel
-{
- std::unique_ptr _mesh;
- std::shared_ptr _texture;
-
-public:
-
- /// @brief The constructor.
- /// @param mesh - The mesh of the model.
- /// @param texture - The texture that the model is covered with.
- BlockFaceModel(std::unique_ptr& mesh, std::shared_ptr texture);
-
- /// @brief Draws the face of a block.
- /// @param origin - A position in the world to place the model.
- /// @param camera - It is used to bind a shader to see the drawn model.
- void Draw(const Position& origin, const Camera& camera) const;
-};
diff --git a/src/Application/Sandbox/Model/BlockModel.h b/src/Application/Sandbox/Model/BlockModel.h
deleted file mode 100644
index 2c9e447e..00000000
--- a/src/Application/Sandbox/Model/BlockModel.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#pragma once
-#include "BlockFaceModel.h"
-#include "Application/Sandbox/Camera.h"
-
-/// @brief Container for the face models of a block.
-struct BlockFaces
-{
- /// @brief Model of the block front face.
- BlockFaceModel front;
-
- /// @brief Model of the block back face.
- BlockFaceModel back;
-
- /// @brief Model of the block left face.
- BlockFaceModel left;
-
- /// @brief Model of the block right face.
- BlockFaceModel right;
-
- /// @brief Model of the block top face.
- BlockFaceModel top;
-
- /// @brief Model of the block bottom face.
- BlockFaceModel bottom;
-};
-
-
-/// @brief Represents visibility of the faces.
-struct FacesVisibility
-{
- /// @brief Answers the question "Is the front face of this block visible?".
- bool front;
-
- /// @brief Answers the question "Is the back face of this block visible?".
- bool back;
-
- /// @brief Answers the question "Is the left face of this block visible?".
- bool left;
-
- /// @brief Answers the question "Is the right face of this block visible?".
- bool right;
-
- /// @brief Answers the question "Is the top face of this block visible?".
- bool top;
-
- /// @brief Answers the question "Is the bottom face of this block visible?".
- bool bottom;
-};
-
-/// @class BlockModel
-/// @brief Represents a graphical model of a block.
-/// @note This class is not an actual model.
-/// More like container for the @see BlockFaceModel objects. But it suits well it's definition and
-/// has functionality that makes sense.
-class BlockModel
-{
- BlockFaces _blockFaces;
-
-public:
-
- /// @brief The constructor.
- /// @param faces - The faces of the block.
- explicit BlockModel(BlockFaces faces)
- : _blockFaces(std::move(faces))
- {}
-
- /// @brief Draws the front face.
- /// @param origin - A position in the world to place the mesh.
- /// @param camera - It is used to bind a shader to see the drawn model.
- void DrawFrontFace(const Position& origin, const Camera& camera) const
- {
- _blockFaces.front.Draw(origin, camera);
- }
-
- /// @brief Draws the back face.
- /// @param origin - A position in the world to place the mesh.
- /// @param camera - It is used to bind a shader to see the drawn model.
- void DrawBackFace(const Position& origin, const Camera& camera) const
- {
- _blockFaces.back.Draw(origin, camera);
- }
-
- /// @brief Draws the left face.
- /// @param origin - A position in the world to place the mesh.
- /// @param camera - It is used to bind a shader to see the drawn model.
- void DrawLeftFace(const Position& origin, const Camera& camera) const
- {
- _blockFaces.left.Draw(origin, camera);
- }
-
- /// @brief Draws the right face.
- /// @param origin - A position in the world to place the mesh.
- /// @param camera - It is used to bind a shader to see the drawn model.
- void DrawRightFace(const Position& origin, const Camera& camera) const
- {
- _blockFaces.right.Draw(origin, camera);
- }
-
- /// @brief Draws the top face.
- /// @param origin - A position in the world to place the mesh.
- /// @param camera - It is used to bind a shader to see the drawn model.
- void DrawTopFace(const Position& origin, const Camera& camera) const
- {
- _blockFaces.top.Draw(origin, camera);
- }
-
- /// @brief Draws the bottom face.
- /// @param origin - A position in the world to place the mesh.
- /// @param camera - It is used to bind a shader to see the drawn model.
- void DrawBottomFace(const Position& origin, const Camera& camera) const
- {
- _blockFaces.bottom.Draw(origin, camera);
- }
-};
\ No newline at end of file
diff --git a/src/Application/Sandbox/Sandbox.cpp b/src/Application/Sandbox/Sandbox.cpp
deleted file mode 100644
index d5f28cff..00000000
--- a/src/Application/Sandbox/Sandbox.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "Sandbox.h"
-
-#include "Camera.h"
-#include "Events/HumanInterfaceDevice.h"
-#include "World/WorldGenerator.h"
-#include "Utils/FPSCounter.h"
-#include "World/Chunks/Rendring/ChunkPlacer.h"
-
-
-Sandbox::Sandbox(Window& window) : _window(window)
-{
-}
-
-void Sandbox::Run() const
-{
- _log.Info("Launching simulation...");
-
- HumanInterfaceDevice hid(_window.GetHandle());
- Camera camera(_window, glm::vec3(0.0f, 0.0f, 0.0f), hid);
-
- auto worldGenerator = std::make_shared(69);
-
- ChunkPlacer chunkPlacer(RenderViewType::cube, 8, 1, camera);
- chunkPlacer.Bind(worldGenerator);
-
- FPSCounter counter;
-
- glEnable(GL_DEPTH_TEST);
-
- while(!glfwWindowShouldClose(_window.GetHandle()))
- {
- glfwPollEvents();
-
- if (_window.GetWidth() <= 0 || _window.GetHeight() <= 0)
- {
- continue;
- }
-
- glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- camera.Update();
- camera.HandleInput();
- chunkPlacer.Update();
- counter.Update();
-
- glfwSwapBuffers(_window.GetHandle());
- }
-
- glDisable(GL_DEPTH_TEST);
-
- gltTerminate();
-}
diff --git a/src/Application/Sandbox/Sandbox.h b/src/Application/Sandbox/Sandbox.h
deleted file mode 100644
index fca1be1d..00000000
--- a/src/Application/Sandbox/Sandbox.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-#include "Core/Log.h"
-#include "Application/Window.h"
-
-/// @class Sandbox
-/// @brief Class where the world is projected.
-/// @details This class handles displaying the world or so to say the actual simulation.
-class Sandbox
-{
- Log& _log = Log::Get();
- Window& _window;
-
-public:
-
- /// @brief The constructor.
- /// @param window - Reference to the window settings.
- explicit Sandbox(Window& window);
-
- /// @brief Initializes the simulation.
- void Run() const;
-};
-
diff --git a/src/Application/Sandbox/World/Blocks/BlockBuilder.cpp b/src/Application/Sandbox/World/Blocks/BlockBuilder.cpp
deleted file mode 100644
index 2aa20d4a..00000000
--- a/src/Application/Sandbox/World/Blocks/BlockBuilder.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "BlockBuilder.h"
-
-void BlockBuilder::SetFaceTexture(
- std::vector& face,
- const int x,
- const int y,
- const bool flipTexture) const
-{
- _textureAtlas->SetSprite(face, x, y, flipTexture);
-}
-
-void BlockBuilder::DetermineAndSetFaceTexture(const std::string& face, const int x, const int y) const
-{
- if (face == "front") SetFaceTexture(_faceVertices->front, x, y, false);
- if (face == "back") SetFaceTexture(_faceVertices->back, x, y, true);
- if (face == "left") SetFaceTexture(_faceVertices->left, x, y, true);
- if (face == "right") SetFaceTexture(_faceVertices->right, x, y, false);
- if (face == "top") SetFaceTexture(_faceVertices->top, x, y, false);
- if (face == "bottom") SetFaceTexture(_faceVertices->bottom, x, y, true);
-}
-
-BlockBuilder::BlockBuilder(const std::string& textureAtlasFilename, const size_t spriteSize, std::vector& blockIndices, Shader& blockShader)
- : _faceIndices(blockIndices),
- _textureAtlas(std::make_shared(textureAtlasFilename, spriteSize)),
- _blockShader(blockShader)
-{
-}
-
-BlockModel BlockBuilder::Build(const JsonData& blockData)
-{
- for (const auto& textureData : blockData["textures"])
- {
- const int x = textureData["location"].value("column", 0);
- const int y = textureData["location"].value("row", 0);
-
- for (const auto& face : textureData["faces"])
- {
- DetermineAndSetFaceTexture(face, x, y);
- }
- }
-
- FaceMeshes faceMeshes
- {
- std::make_unique(_faceVertices->front, _faceIndices, _blockShader),
- std::make_unique(_faceVertices->back, _faceIndices, _blockShader),
- std::make_unique(_faceVertices->left, _faceIndices, _blockShader),
- std::make_unique(_faceVertices->right, _faceIndices, _blockShader),
- std::make_unique(_faceVertices->top, _faceIndices, _blockShader),
- std::make_unique(_faceVertices->bottom, _faceIndices, _blockShader)
- };
-
- BlockFaces faces
- {
- BlockFaceModel(faceMeshes.front, _textureAtlas),
- BlockFaceModel(faceMeshes.back, _textureAtlas),
- BlockFaceModel(faceMeshes.left, _textureAtlas),
- BlockFaceModel(faceMeshes.right, _textureAtlas),
- BlockFaceModel(faceMeshes.top, _textureAtlas),
- BlockFaceModel(faceMeshes.bottom, _textureAtlas)
- };
-
- return BlockModel(std::move(faces));
-}
-
diff --git a/src/Application/Sandbox/World/Blocks/BlockBuilder.h b/src/Application/Sandbox/World/Blocks/BlockBuilder.h
deleted file mode 100644
index 663f3660..00000000
--- a/src/Application/Sandbox/World/Blocks/BlockBuilder.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#pragma once
-#include "Core/Metadata.h"
-#include "Application/Sandbox/Model/BlockModel.h"
-#include "Application/Sandbox/Model/Mesh/Geometry/Shader.h"
-#include "Application/Sandbox/Model/Surface/TextureAtlas.h"
-
-/// @class BlockBuilder
-/// @brief A factory that builds and outputs blocks based on their metadata.
-class BlockBuilder
-{
- struct FaceVertices
- {
- std::vector front
- {
- Vertex{Position{0.0f, 0.0f, 0.0f}, Point{0.0f, 0.0f}},
- Vertex{Position{1.0f, 0.0f, 0.0f}, Point{1.0f, 0.0f}},
- Vertex{Position{1.0f, 1.0f, 0.0f}, Point{1.0f, 1.0f}},
- Vertex{Position{0.0f, 1.0f, 0.0f}, Point{0.0f, 1.0f}},
- };
-
- std::vector back
- {
- Vertex{Position{0.0f, 0.0f, 1.0f}, Point{0.0f, 0.0f}},
- Vertex{Position{0.0f, 1.0f, 1.0f}, Point{1.0f, 0.0f}},
- Vertex{Position{1.0f, 1.0f, 1.0f}, Point{1.0f, 1.0f}},
- Vertex{Position{1.0f, 0.0f, 1.0f}, Point{0.0f, 1.0f}},
- };
-
- std::vector left
- {
- Vertex{Position{0.0f, 0.0f, 0.0f}, Point{0.0f, 0.0f}},
- Vertex{Position{0.0f, 1.0f, 0.0f}, Point{1.0f, 0.0f}},
- Vertex{Position{0.0f, 1.0f, 1.0f}, Point{1.0f, 1.0f}},
- Vertex{Position{0.0f, 0.0f, 1.0f}, Point{0.0f, 1.0f}},
- };
-
- std::vector right
- {
- Vertex{Position{1.0f, 0.0f, 0.0f}, Point{0.0f, 0.0f}},
- Vertex{Position{1.0f, 0.0f, 1.0f}, Point{1.0f, 0.0f}},
- Vertex{Position{1.0f, 1.0f, 1.0f}, Point{1.0f, 1.0f}},
- Vertex{Position{1.0f, 1.0f, 0.0f}, Point{0.0f, 1.0f}},
- };
-
- std::vector top
- {
- Vertex{Position{0.0f, 1.0f, 0.0f}, Point{0.0f, 0.0f}},
- Vertex{Position{1.0f, 1.0f, 0.0f}, Point{1.0f, 0.0f}},
- Vertex{Position{1.0f, 1.0f, 1.0f}, Point{1.0f, 1.0f}},
- Vertex{Position{0.0f, 1.0f, 1.0f}, Point{0.0f, 1.0f}},
- };
-
- std::vector bottom
- {
- Vertex{Position{0.0f, 0.0f, 0.0f}, Point{0.0f, 0.0f}},
- Vertex{Position{0.0f, 0.0f, 1.0f}, Point{1.0f, 0.0f}},
- Vertex{Position{1.0f, 0.0f, 1.0f}, Point{1.0f, 1.0f}},
- Vertex{Position{1.0f, 0.0f, 0.0f}, Point{0.0f, 1.0f}},
- };
- };
-
- struct FaceMeshes
- {
- std::unique_ptr front;
- std::unique_ptr back;
- std::unique_ptr left;
- std::unique_ptr right;
- std::unique_ptr top;
- std::unique_ptr bottom;
- };
-
- struct FaceTextures
- {
- std::shared_ptr front;
- std::shared_ptr back;
- std::shared_ptr left;
- std::shared_ptr right;
- std::shared_ptr top;
- std::shared_ptr