diff --git a/external/DMath b/external/DMath index b44a8d7273fcc7e9775733a014c5d944fd48167c..0d9c06d9e19a54a8747147a370d5e73dfe616220 160000 --- a/external/DMath +++ b/external/DMath @@ -1 +1 @@ -Subproject commit b44a8d7273fcc7e9775733a014c5d944fd48167c +Subproject commit 0d9c06d9e19a54a8747147a370d5e73dfe616220 diff --git a/src/Engine/Components/Camera.cpp b/src/Engine/Components/Camera.cpp index 5fe66c3ddf30721d9f04c078427070cc65371e50..04d7824fd50aa6d74a0b4e48f3f60e13d47e7db7 100644 --- a/src/Engine/Components/Camera.cpp +++ b/src/Engine/Components/Camera.cpp @@ -10,13 +10,13 @@ namespace Engine { Camera::Camera(SceneObject& owningObject) : ParentType(owningObject), - position(), + positionOffset(), fov(defaultFovY), forward(Math::Vector3D::Back()), up(Math::Vector3D::Up()), zNear(defaultZNear), zFar(defaultZFar), - activeProjectionMode(ProjectionMode::Perspective), + projectionMode(ProjectionMode::Perspective), orthographicWidth(defaultOrtographicWidth) { } @@ -27,7 +27,7 @@ namespace Engine void Camera::LookAt(const Math::Vector3D& newTarget) { - forward = (newTarget - position).GetNormalized(); + forward = (newTarget - positionOffset).GetNormalized(); } Renderer::CameraInfo Camera::GetCameraInfo() const @@ -39,10 +39,12 @@ namespace Engine cameraInfo.zNear = zNear; cameraInfo.zFar = zFar; - if (activeProjectionMode == ProjectionMode::Perspective) + if (projectionMode == ProjectionMode::Perspective) cameraInfo.projectMode = Renderer::CameraInfo::ProjectMode::Perspective; + else if (projectionMode == ProjectionMode::Orthgraphic) + cameraInfo.projectMode = Renderer::CameraInfo::ProjectMode::Orthographic; - cameraInfo.transform = Math::LinTran3D::LookAtRH(position, position + forward, up); + cameraInfo.transform = Math::LinTran3D::LookAt_RH(positionOffset, positionOffset + forward, up); return cameraInfo; } diff --git a/src/Engine/Components/Camera.hpp b/src/Engine/Components/Camera.hpp index b462fbb05cb00d6c001510e27ebcc98eb204c9e5..0226c36cac8c60ce34a4953ad1b1bd0ad53c6686 100644 --- a/src/Engine/Components/Camera.hpp +++ b/src/Engine/Components/Camera.hpp @@ -30,7 +30,7 @@ namespace Engine explicit Camera(SceneObject& owningObject); ~Camera(); - Math::Vector3D position; + Math::Vector3D positionOffset; Math::Vector3D forward; Math::Vector3D up; @@ -38,7 +38,7 @@ namespace Engine float orthographicWidth; float zNear; float zFar; - ProjectionMode activeProjectionMode; + ProjectionMode projectionMode; void LookAt(const Math::Vector3D& newTarget); diff --git a/src/Engine/Components/MeshRenderer.cpp b/src/Engine/Components/MeshRenderer.cpp index e0d9a299f7e2fd7450b335df02f3e3460617c856..f1136dc0c7ef2c918d9e05cb693c3f1b1eeacce7 100644 --- a/src/Engine/Components/MeshRenderer.cpp +++ b/src/Engine/Components/MeshRenderer.cpp @@ -56,7 +56,8 @@ namespace Engine Math::Matrix4x4 MeshRenderer::GetModel(Space space) const { - return Math::LinTran3D::AsMat4(GetModel_Reduced(space)); + const auto& model = GetModel_Reduced(space); + return Math::LinTran3D::AsMat4(model); } } } diff --git a/src/Engine/Components/PointLight.cpp b/src/Engine/Components/PointLight.cpp index 809e3cd7e010d9dd6278a87aa551552ffc1de81c..da60b31cee0e16233114b3750e3192c103c83527 100644 --- a/src/Engine/Components/PointLight.cpp +++ b/src/Engine/Components/PointLight.cpp @@ -29,5 +29,11 @@ namespace Engine else return Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel); } + + Math::Matrix4x4 PointLight::GetModel(Space space) const + { + using namespace Math::LinTran3D; + return AsMat4(GetModel_Reduced(space)); + } } } \ No newline at end of file diff --git a/src/Engine/Components/PointLight.hpp b/src/Engine/Components/PointLight.hpp index 9507c4efb148712d6eefb279597f6c96117d1bcf..5bbe42cb94dba2c489a667fcb7484c2054f5f8f8 100644 --- a/src/Engine/Components/PointLight.hpp +++ b/src/Engine/Components/PointLight.hpp @@ -23,6 +23,7 @@ namespace Engine Math::Vector3D positionOffset; [[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const; + [[nodiscard]] Math::Matrix4x4 GetModel(Space space) const; }; } } \ No newline at end of file diff --git a/src/Engine/Components/SpriteRenderer.cpp b/src/Engine/Components/SpriteRenderer.cpp index 139895d184295471b7b28d2284eaf7c31e77587f..f46ff15a45cecdebebee85b660f7ccf5277d4d24 100644 --- a/src/Engine/Components/SpriteRenderer.cpp +++ b/src/Engine/Components/SpriteRenderer.cpp @@ -15,7 +15,7 @@ namespace Engine SpriteRenderer::SpriteRenderer(SceneObject& owningObject) : ParentType(owningObject), sprite(Asset::Sprite::None), - position{ 0, 0 }, + positionOffset{ 0, 0 }, rotation(0), scale{ 1, 1 } { @@ -39,33 +39,26 @@ namespace Engine Math::Matrix<3, 2> SpriteRenderer::GetModel2D_Reduced(Space space) const { - const auto& scaleModel = Math::LinTran2D::Scale_Reduced(scale); - const auto& rotateModel = Math::LinTran2D::Rotate_Reduced(rotation); - auto localModel = Math::LinTran2D::Multiply(scaleModel, rotateModel); - Math::LinTran2D::AddTranslation(localModel, position); + using namespace Math::LinTran2D; + + const auto& scaleModel = Scale_Reduced(scale); + const auto& rotateModel = Rotate_Reduced(rotation); + auto localModel = Multiply(scaleModel, rotateModel); + AddTranslation(localModel, positionOffset); if (space == Space::Local) return localModel; else { auto parentModel = GetSceneObject().transform.GetModel2D_Reduced(space); - return Math::LinTran2D::Multiply(parentModel, localModel); + return Multiply(parentModel, localModel); } } Math::Matrix4x4 SpriteRenderer::GetModel(Space space) const { const auto& model = GetModel2D_Reduced(space); - auto newMatrix = Math::Matrix4x4::Identity(); - for (size_t x = 0; x < model.GetWidth() - 1; x++) - { - for (size_t y = 0; y < model.GetHeight(); y++) - newMatrix[x][y] = model[x][y]; - } - - for (size_t y = 0; y < model.GetHeight(); y++) - newMatrix[3][y] = model[2][y]; - return newMatrix; + return Math::LinTran2D::AsMat4(model); } } } diff --git a/src/Engine/Components/SpriteRenderer.hpp b/src/Engine/Components/SpriteRenderer.hpp index 130f984ca322b202b8d7296f4e1555bac5933c8f..70994367f7f2f6dfea79ec033718cb5bae774190 100644 --- a/src/Engine/Components/SpriteRenderer.hpp +++ b/src/Engine/Components/SpriteRenderer.hpp @@ -27,7 +27,7 @@ namespace Engine Math::Matrix<3, 2> GetModel2D_Reduced(Space space) const; Math::Matrix4x4 GetModel(Space space) const; - Math::Vector2D position; + Math::Vector2D positionOffset; float rotation; Math::Vector2D scale; diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp index f1c43217a399e1d45f04754a5f416ce025dc8b2c..ac5b7a5317e5c9fa81afb2073b6b312c81cdbd00 100644 --- a/src/Engine/Engine.cpp +++ b/src/Engine/Engine.cpp @@ -6,6 +6,7 @@ #include "Renderer/Renderer.hpp" #include "Components/SpriteRenderer.hpp" #include "Components/MeshRenderer.hpp" +#include "Components/PointLight.hpp" #include "Time/Time.hpp" #include "Input/InputRaw.hpp" #include "Scene.hpp" @@ -34,8 +35,6 @@ public: } protected: - - void SceneStart() override { ParentType::SceneStart(); @@ -69,7 +68,6 @@ void Engine::Core::Run() Renderer::GetViewport(0).SetSceneRef(&scene1); - auto& sceneObject1 = scene1.NewSceneObject(); auto& sprite1 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); sprite1.SetMesh(Asset::Mesh::Helmet); @@ -80,11 +78,11 @@ void Engine::Core::Run() auto& objCamera = scene1.NewSceneObject(); auto& camera = objCamera.AddComponent<Components::Camera>().first.get(); - - camera.position.z = 5.f; + camera.positionOffset.z = 5.f; auto& obj3 = scene1.NewSceneObject(); - //ScriptTest& scriptTest = obj3.AddComponent<ScriptTest>(); + obj3.transform.localPosition = { 5.f, 5.f, 10.f }; + Components::PointLight& light1 = obj3.AddComponent<Components::PointLight>().first.get(); Renderer::RenderGraph graph; @@ -98,22 +96,19 @@ void Engine::Core::Run() const float speed = 2.5f; auto cross = Math::Vector3D::Cross(camera.forward, camera.up); if (Input::Raw::GetValue(Input::Raw::Button::A)) - camera.position -= cross * speed * scene1.GetTimeData().GetDeltaTime(); + camera.positionOffset -= cross * speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::D)) - camera.position += cross * speed * scene1.GetTimeData().GetDeltaTime(); + camera.positionOffset += cross * speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::W)) - camera.position += camera.forward * speed * scene1.GetTimeData().GetDeltaTime(); + camera.positionOffset += camera.forward * speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::S)) - camera.position -= camera.forward * speed * scene1.GetTimeData().GetDeltaTime(); + camera.positionOffset -= camera.forward * speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::Space)) - camera.position += Math::Vector3D::Up() * speed * scene1.GetTimeData().GetDeltaTime(); + camera.positionOffset += Math::Vector3D::Up() * speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::LeftCtrl)) - camera.position += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime(); + camera.positionOffset += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime(); camera.LookAt({ 0, 0, 0 }); - if (Input::Raw::GetValue(Input::Raw::Button::K)) - mesh2.positionOffset.y += 1.f * scene1.GetTimeData().GetDeltaTime(); - if (Input::Raw::GetEventType(Input::Raw::Button::C) == Input::EventType::Pressed) { scene1.Clear(); @@ -123,18 +118,20 @@ void Engine::Core::Run() scene1.ScriptTick(); - RenderSystem::BuildRenderGraph(scene1, graph, graphTransform); + RenderSystem::BuildRenderGraph(scene1, graph); + Renderer::Core::PrepareRenderingEarly(graph); + RenderSystem::BuildRenderGraphTransform(scene1, graphTransform); + Renderer::Core::PrepareRenderingLate(graphTransform); + Renderer::Core::SetCameraInfo(camera.GetCameraInfo()); - Renderer::Core::PrepareRenderingEarly(graph); - - Renderer::Core::PrepareRenderingLate(graphTransform); Renderer::Core::Draw(); + Time::Core::TickEnd(scene1.GetTimeData()); } diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp index be81be082b886b0e926a6efe7198ad0c1cea5a32..5cd066160f9b28561f7b12b5fa83a92abfbb02fa 100644 --- a/src/Engine/Renderer/OpenGL.cpp +++ b/src/Engine/Renderer/OpenGL.cpp @@ -33,6 +33,7 @@ namespace Engine struct Data; struct CameraDataUBO; + struct LightDataUBO; void UpdateVBODatabase(Data& data, const std::vector<MeshID>& loadQueue); std::optional<VBO> VBOFromPath(const std::string& path); @@ -54,6 +55,12 @@ struct Engine::Renderer::OpenGL::CameraDataUBO Math::Matrix<4, 4, float> viewProjection; }; +struct Engine::Renderer::OpenGL::LightDataUBO +{ + uint32_t pointLightCount; + std::array<Math::Vector4D, 10> pointLights; +}; + struct Engine::Renderer::OpenGL::VertexBufferObject { enum class Attribute @@ -302,6 +309,7 @@ void Engine::Renderer::OpenGL::PrepareRenderingEarly(const std::vector<SpriteID> void Engine::Renderer::OpenGL::PrepareRenderingLate() { + // Update lights positions } void Engine::Renderer::OpenGL::Draw() diff --git a/src/Engine/Renderer/Renderer.cpp b/src/Engine/Renderer/Renderer.cpp index 9aaa7d4d6956e23db9c6b47bf5948cda9015d1b8..ce93f8ad7bfe8b279ec478e56cf1da838924755d 100644 --- a/src/Engine/Renderer/Renderer.cpp +++ b/src/Engine/Renderer/Renderer.cpp @@ -61,7 +61,13 @@ size_t Engine::Renderer::GetViewportCount() { return Core::data->viewports.size( Engine::Renderer::Viewport& Engine::Renderer::GetViewport(size_t index) { return *Core::data->viewports[index]; } -Engine::Renderer::API Engine::Renderer::GetActiveAPI() { return Core::data->activeAPI; } +Engine::Renderer::API Engine::Renderer::GetActiveAPI() +{ + if (Core::data) + return Core::data->activeAPI; + else + return API::None; +} std::any& Engine::Renderer::Core::GetAPIData() { return data->apiData; } @@ -187,6 +193,9 @@ bool Engine::Renderer::IsCompatible(const RenderGraph &renderGraph, const Render if (renderGraph.meshes.size() != transforms.meshes.size()) return false; + if (renderGraph.pointLights.size() != transforms.pointLights.size()) + return false; + return true; } @@ -240,22 +249,39 @@ void Engine::Renderer::Core::UpdateAssetReferences(Data& data, const RenderGraph Math::Matrix4x4 Engine::Renderer::CameraInfo::GetModel(float aspectRatio) const { + using namespace Math::LinTran3D; if (projectMode == ProjectMode::Perspective) { switch (GetActiveAPI()) { case API::OpenGL: - return Math::LinTran3D::Perspective<float>(Math::API3D::OpenGL, fovY, aspectRatio, zNear, zFar) * transform; + return Perspective<float>(Math::API3D::OpenGL, fovY, aspectRatio, zNear, zFar) * transform; case API::Vulkan: - return Math::LinTran3D::Perspective<float>(Math::API3D::Vulkan, fovY, aspectRatio, zNear, zFar) * transform; + return Perspective<float>(Math::API3D::Vulkan, fovY, aspectRatio, zNear, zFar) * transform; default: assert(false); return {}; } } - else // Orthogonal + else if (projectMode == ProjectMode::Orthographic) { - assert(false); - return {}; + const float& right = orthoWidth / 2; + const float& left = -right; + const float& top = orthoWidth / aspectRatio / 2; + const float& bottom = -top; + switch (GetActiveAPI()) + { + case API::OpenGL: + return Orthographic<float>(Math::API3D::OpenGL, left, right, bottom, top, zNear, zFar); + case API::Vulkan: + return Orthographic<float>(Math::API3D::Vulkan, left, right, bottom, top, zNear, zFar); + default: + assert(false); + return {}; + } } + + // Function should NOT reach here. + assert(false); + return {}; } \ No newline at end of file diff --git a/src/Engine/Systems/RenderSystem.cpp b/src/Engine/Systems/RenderSystem.cpp index 037ad38832de4778e0160c89ad88fcd6d0dfaf27..d48089d869165c40b4273a201966f4d85cbc652d 100644 --- a/src/Engine/Systems/RenderSystem.cpp +++ b/src/Engine/Systems/RenderSystem.cpp @@ -2,43 +2,86 @@ #include "../Renderer/Renderer.hpp" +#include "../Components/SpriteRenderer.hpp" +#include "../Components/MeshRenderer.hpp" +#include "../Components/PointLight.hpp" + +#include "DMath/LinearTransform3D.hpp" + namespace Engine { - void RenderSystem::BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph, Renderer::RenderGraphTransform& transforms) + void RenderSystem::BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph) { auto spriteComponentsPtr = scene.GetAllComponents<Components::SpriteRenderer>(); if (spriteComponentsPtr == nullptr) - { graph.sprites.clear(); - transforms.sprites.clear(); - } else { const auto& spriteComponents = *spriteComponentsPtr; graph.sprites.resize(spriteComponents.size()); - transforms.sprites.resize(spriteComponents.size()); for (size_t i = 0; i < spriteComponents.size(); i++) - { graph.sprites[i] = static_cast<Renderer::SpriteID>(spriteComponents[i].GetSprite()); - transforms.sprites[i] = spriteComponents[i].GetModel(Space::World); - } } auto meshComponentsPtr = scene.GetAllComponents<Components::MeshRenderer>(); if (meshComponentsPtr == nullptr) - { graph.meshes.clear(); - transforms.meshes.clear(); - } else { const auto& meshComponents = *meshComponentsPtr; graph.meshes.resize(meshComponents.size()); - transforms.meshes.resize(meshComponents.size()); for (size_t i = 0; i < meshComponents.size(); i++) - { graph.meshes[i] = static_cast<Renderer::MeshID>(meshComponents[i].GetMesh()); + } + + auto pointLightComponentsPtr = scene.GetAllComponents<Components::PointLight>(); + if (pointLightComponentsPtr == nullptr) + graph.pointLights.clear(); + else + { + const auto& pointLightComponents = *pointLightComponentsPtr; + graph.pointLights.resize(pointLightComponents.size()); + for (size_t i = 0; i < pointLightComponents.size(); i++) + graph.pointLights[i] = Renderer::PointLight{ pointLightComponents[i].intensity }; + } + } + + void RenderSystem::BuildRenderGraphTransform(const Scene& scene, Renderer::RenderGraphTransform& transforms) + { + auto spriteComponentsPtr = scene.GetAllComponents<Components::SpriteRenderer>(); + if (spriteComponentsPtr == nullptr) + transforms.sprites.clear(); + else + { + const auto& spriteComponents = *spriteComponentsPtr; + transforms.sprites.resize(spriteComponents.size()); + for (size_t i = 0; i < spriteComponents.size(); i++) + transforms.sprites[i] = spriteComponents[i].GetModel(Space::World); + } + + auto meshComponentsPtr = scene.GetAllComponents<Components::MeshRenderer>(); + if (meshComponentsPtr == nullptr) + transforms.meshes.clear(); + else + { + const auto& meshComponents = *meshComponentsPtr; + transforms.meshes.resize(meshComponents.size()); + for (size_t i = 0; i < meshComponents.size(); i++) transforms.meshes[i] = meshComponents[i].GetModel(Space::World); + } + + auto pointLightComponentsPtr = scene.GetAllComponents<Components::PointLight>(); + if (pointLightComponentsPtr == nullptr) + transforms.pointLights.clear(); + else + { + const auto& pointLightComponents = *pointLightComponentsPtr; + transforms.pointLights.resize(pointLightComponents.size()); + for (size_t i = 0; i < pointLightComponents.size(); i++) + { + const auto& model = pointLightComponents[i].GetModel_Reduced(Space::World); + const Math::Vector3D& position = Math::LinTran3D::GetTranslation(model); + transforms.pointLights[i] = position; } } } diff --git a/src/Engine/Systems/RenderSystem.hpp b/src/Engine/Systems/RenderSystem.hpp index dd9a3002b61ccff49704489a0d2fc877034ea701..e80c7fc3c639684c7f83aaea608ec8d04c33518b 100644 --- a/src/Engine/Systems/RenderSystem.hpp +++ b/src/Engine/Systems/RenderSystem.hpp @@ -2,20 +2,42 @@ #include "System.hpp" -#include "../Components/MeshRenderer.hpp" -#include "../Components/SpriteRenderer.hpp" #include "../Renderer/Typedefs.hpp" #include "../Scene.hpp" +// Forward declarations namespace Engine { - using RenderSystem = System<Components::MeshRenderer, Components::SpriteRenderer>; + class Scene; + + namespace Components + { + class MeshRenderer; + class SpriteRenderer; + class PointLight; + } +} + +namespace Engine +{ + using RenderSystem = System + < + Components::MeshRenderer, + Components::SpriteRenderer, + Components::PointLight + >; template<> - class System<Components::MeshRenderer, Components::SpriteRenderer> + class System + < + Components::MeshRenderer, + Components::SpriteRenderer, + Components::PointLight + > { public: - static void BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph, Renderer::RenderGraphTransform& transforms); + static void BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph); + static void BuildRenderGraphTransform(const Scene& scene, Renderer::RenderGraphTransform& transforms); }; } \ No newline at end of file