From 5ece76a797d28a5c5eb77f9a276191778451aae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Petter=20Sk=C3=A5lerud?= <np_skalerud@hotmail.com> Date: Fri, 22 Mar 2019 19:03:36 +0100 Subject: [PATCH] Renamed some components' position member to 'positionOffset'. Added (tried) support for orthographic camera projection. Still not working entirely. More work on getting lighting into the engine. Updated submodule DMath to latest version (22.03.2019) and updated some functions to utilize new functionality. Split RenderSystem::BuildRenderGraph into 2 functions to match renderer-interface better. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nils Petter Skålerud <np_skalerud@hotmail.com> --- external/DMath | 2 +- src/Engine/Components/Camera.cpp | 12 +++-- src/Engine/Components/Camera.hpp | 4 +- src/Engine/Components/MeshRenderer.cpp | 3 +- src/Engine/Components/PointLight.cpp | 6 +++ src/Engine/Components/PointLight.hpp | 1 + src/Engine/Components/SpriteRenderer.cpp | 25 ++++----- src/Engine/Components/SpriteRenderer.hpp | 2 +- src/Engine/Engine.cpp | 35 ++++++------ src/Engine/Renderer/OpenGL.cpp | 8 +++ src/Engine/Renderer/Renderer.cpp | 38 ++++++++++--- src/Engine/Systems/RenderSystem.cpp | 69 +++++++++++++++++++----- src/Engine/Systems/RenderSystem.hpp | 32 +++++++++-- 13 files changed, 168 insertions(+), 69 deletions(-) diff --git a/external/DMath b/external/DMath index b44a8d7..0d9c06d 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 5fe66c3..04d7824 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 b462fbb..0226c36 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 e0d9a29..f1136dc 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 809e3cd..da60b31 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 9507c4e..5bbe42c 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 139895d..f46ff15 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 130f984..7099436 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 f1c4321..ac5b7a5 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 be81be0..5cd0661 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 9aaa7d4..ce93f8a 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 037ad38..d48089d 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 dd9a300..e80c7fc 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 -- GitLab