diff --git a/SDK/include/NDK/Components/CameraComponent.hpp b/SDK/include/NDK/Components/CameraComponent.hpp index cd575b40d..4b610d5a0 100644 --- a/SDK/include/NDK/Components/CameraComponent.hpp +++ b/SDK/include/NDK/Components/CameraComponent.hpp @@ -40,6 +40,7 @@ namespace Ndk inline const NzFrustumf& GetFrustum() const; inline unsigned int GetLayer() const; inline const NzMatrix4f& GetProjectionMatrix() const; + inline nzProjectionType GetProjectionType() const; inline const NzRenderTarget* GetTarget() const; inline const NzRectf& GetTargetRegion() const; inline const NzMatrix4f& GetViewMatrix() const; @@ -49,6 +50,7 @@ namespace Ndk inline void SetFOV(float fov); inline void SetLayer(unsigned int layer); + inline void SetProjectionType(nzProjectionType projection); inline void SetTarget(const NzRenderTarget* renderTarget); inline void SetTargetRegion(const NzRectf& region); inline void SetViewport(const NzRecti& viewport); @@ -80,6 +82,7 @@ namespace Ndk NazaraSlot(NzRenderTarget, OnRenderTargetRelease, m_targetReleaseSlot); NazaraSlot(NzRenderTarget, OnRenderTargetSizeChange, m_targetResizeSlot); + nzProjectionType m_projectionType; mutable NzFrustumf m_frustum; mutable NzMatrix4f m_projectionMatrix; mutable NzMatrix4f m_viewMatrix; diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index f510d180a..083ef4219 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -8,6 +8,7 @@ namespace Ndk { inline CameraComponent::CameraComponent() : + m_projectionType(nzProjectionType_Perspective), m_targetRegion(0.f, 0.f, 1.f, 1.f), m_target(nullptr), m_frustumUpdated(false), @@ -25,6 +26,7 @@ namespace Ndk inline CameraComponent::CameraComponent(const CameraComponent& camera) : Component(camera), NzAbstractViewer(camera), + m_projectionType(camera.m_projectionType), m_targetRegion(camera.m_targetRegion), m_target(nullptr), m_frustumUpdated(false), @@ -95,6 +97,11 @@ namespace Ndk return m_projectionMatrix; } + inline nzProjectionType CameraComponent::GetProjectionType() const + { + return m_projectionType; + } + inline const NzRenderTarget* CameraComponent::GetTarget() const { return m_target; @@ -132,8 +139,15 @@ namespace Ndk inline void CameraComponent::SetFOV(float fov) { NazaraAssert(!NzNumberEquals(fov, 0.f), "FOV must be different from zero"); - m_fov = fov; + + InvalidateProjectionMatrix(); + } + + inline void CameraComponent::SetProjectionType(nzProjectionType projectionType) + { + m_projectionType = projectionType; + InvalidateProjectionMatrix(); } @@ -149,6 +163,7 @@ namespace Ndk inline void CameraComponent::SetTargetRegion(const NzRectf& region) { m_targetRegion = region; + InvalidateViewport(); } @@ -166,14 +181,15 @@ namespace Ndk inline void CameraComponent::SetZFar(float zFar) { m_zFar = zFar; + InvalidateProjectionMatrix(); } inline void CameraComponent::SetZNear(float zNear) { NazaraAssert(!NzNumberEquals(zNear, 0.f), "zNear cannot be zero"); - m_zNear = zNear; + InvalidateProjectionMatrix(); } diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 41f03ca3c..70223bbab 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -15,6 +15,8 @@ namespace Ndk { class NDK_API GraphicsComponent : public Component { + friend class RenderSystem; + public: GraphicsComponent() = default; inline GraphicsComponent(const GraphicsComponent& graphicsComponent); @@ -30,6 +32,7 @@ namespace Ndk private: void InvalidateRenderableData(const NzInstancedRenderable* renderable, nzUInt32 flags, unsigned int index); + inline void InvalidateRenderables(); inline void InvalidateTransformMatrix(); void OnAttached() override; diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index af435aa2b..0691414d1 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -46,11 +46,16 @@ namespace Ndk UpdateTransformMatrix(); } - inline void GraphicsComponent::InvalidateTransformMatrix() + inline void GraphicsComponent::InvalidateRenderables() { for (Renderable& r : m_renderables) r.dataUpdated = false; + } + inline void GraphicsComponent::InvalidateTransformMatrix() + { m_transformMatrixUpdated = false; + + InvalidateRenderables(); } } diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index d02e3b00b..66167c92c 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -26,12 +26,21 @@ namespace Ndk ~RenderSystem() = default; inline const NzBackgroundRef& GetDefaultBackground() const; + inline const NzMatrix4f& GetCoordinateSystemMatrix() const; + inline NzVector3f GetGlobalForward() const; + inline NzVector3f GetGlobalRight() const; + inline NzVector3f GetGlobalUp() const; inline void SetDefaultBackground(NzBackgroundRef background); + inline void SetGlobalForward(const NzVector3f& direction); + inline void SetGlobalRight(const NzVector3f& direction); + inline void SetGlobalUp(const NzVector3f& direction); static SystemIndex systemIndex; private: + inline void InvalidateCoordinateSystem(); + void OnEntityRemoved(Entity* entity) override; void OnEntityValidation(Entity* entity, bool justAdded) override; void OnUpdate(float elapsedTime) override; @@ -41,6 +50,8 @@ namespace Ndk EntityList m_lights; NzBackgroundRef m_background; NzForwardRenderTechnique m_renderTechnique; + NzMatrix4f m_coordinateSystemMatrix; + bool m_coordinateSystemInvalidated; }; } diff --git a/SDK/include/NDK/Systems/RenderSystem.inl b/SDK/include/NDK/Systems/RenderSystem.inl index ac4db251f..a2eed384e 100644 --- a/SDK/include/NDK/Systems/RenderSystem.inl +++ b/SDK/include/NDK/Systems/RenderSystem.inl @@ -14,8 +14,60 @@ namespace Ndk return m_background; } + inline const NzMatrix4f& RenderSystem::GetCoordinateSystemMatrix() const + { + return m_coordinateSystemMatrix; + } + + inline NzVector3f RenderSystem::GetGlobalForward() const + { + return NzVector3f(-m_coordinateSystemMatrix.m13, -m_coordinateSystemMatrix.m23, -m_coordinateSystemMatrix.m33); + } + + inline NzVector3f RenderSystem::GetGlobalRight() const + { + return NzVector3f(m_coordinateSystemMatrix.m11, m_coordinateSystemMatrix.m21, m_coordinateSystemMatrix.m31); + } + + inline NzVector3f RenderSystem::GetGlobalUp() const + { + return NzVector3f(m_coordinateSystemMatrix.m12, m_coordinateSystemMatrix.m22, m_coordinateSystemMatrix.m32); + } + inline void RenderSystem::SetDefaultBackground(NzBackgroundRef background) { m_background = std::move(background); } + + inline void RenderSystem::SetGlobalForward(const NzVector3f& direction) + { + m_coordinateSystemMatrix.m13 = -direction.x; + m_coordinateSystemMatrix.m23 = -direction.y; + m_coordinateSystemMatrix.m33 = -direction.z; + + InvalidateCoordinateSystem(); + } + + inline void RenderSystem::SetGlobalRight(const NzVector3f& direction) + { + m_coordinateSystemMatrix.m11 = direction.x; + m_coordinateSystemMatrix.m21 = direction.y; + m_coordinateSystemMatrix.m31 = direction.z; + + InvalidateCoordinateSystem(); + } + + inline void RenderSystem::SetGlobalUp(const NzVector3f& direction) + { + m_coordinateSystemMatrix.m12 = direction.x; + m_coordinateSystemMatrix.m22 = direction.y; + m_coordinateSystemMatrix.m32 = direction.z; + + InvalidateCoordinateSystem(); + } + + inline void RenderSystem::InvalidateCoordinateSystem() + { + m_coordinateSystemInvalidated = true; + } } diff --git a/SDK/src/NDK/Components/CameraComponent.cpp b/SDK/src/NDK/Components/CameraComponent.cpp index a976262c4..d408552c5 100644 --- a/SDK/src/NDK/Components/CameraComponent.cpp +++ b/SDK/src/NDK/Components/CameraComponent.cpp @@ -116,9 +116,21 @@ namespace Ndk void CameraComponent::UpdateProjectionMatrix() const { - EnsureViewportUpdate(); // Can affect aspect ratio + switch (m_projectionType) + { + case nzProjectionType_Orthogonal: + EnsureViewportUpdate(); + + m_projectionMatrix.MakeOrtho(0.f, static_cast(m_viewport.width), 0.f, static_cast(m_viewport.height), m_zNear, m_zFar); + break; + + case nzProjectionType_Perspective: + EnsureViewportUpdate(); // Can affect aspect ratio + + m_projectionMatrix.MakePerspective(m_fov, m_aspectRatio, m_zNear, m_zFar); + break; + } - m_projectionMatrix.MakePerspective(m_fov, m_aspectRatio, m_zNear, m_zFar); m_projectionMatrixUpdated = true; } @@ -153,7 +165,8 @@ namespace Ndk { m_aspectRatio = aspectRatio; - InvalidateProjectionMatrix(); + if (m_projectionType == nzProjectionType_Perspective) + InvalidateProjectionMatrix(); } // Convert it back to int diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index 13d44577b..ee5658e18 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -3,15 +3,16 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include +#include #include namespace Ndk { void GraphicsComponent::InvalidateRenderableData(const NzInstancedRenderable* renderable, nzUInt32 flags, unsigned int index) { - NazaraUnused(renderable); - NazaraAssert(index < m_renderables.size(), "Invalid renderable index"); + NazaraUnused(renderable); Renderable& r = m_renderables[index]; r.dataUpdated = false; @@ -66,7 +67,9 @@ namespace Ndk { NazaraAssert(m_entity && m_entity->HasComponent(), "GraphicsComponent requires NodeComponent"); - m_transformMatrix = m_entity->GetComponent().GetTransformMatrix(); + Ndk::RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem(); + + m_transformMatrix = renderSystem.GetCoordinateSystemMatrix() * m_entity->GetComponent().GetTransformMatrix(); m_transformMatrixUpdated = true; } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index b9129d798..35aae1403 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -11,7 +11,9 @@ namespace Ndk { - RenderSystem::RenderSystem() + RenderSystem::RenderSystem() : + m_coordinateSystemMatrix(NzMatrix4f::Identity()), + m_coordinateSystemInvalidated(true) { SetDefaultBackground(NzColorBackground::New()); SetUpdateRate(0.f); @@ -54,6 +56,18 @@ namespace Ndk { NazaraUnused(elapsedTime); + // Invalidate every renderable if the coordinate system changed + if (m_coordinateSystemInvalidated) + { + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + graphicsComponent.InvalidateTransformMatrix(); + } + + m_coordinateSystemInvalidated = false; + } + for (const Ndk::EntityHandle& camera : m_cameras) { CameraComponent& camComponent = camera->GetComponent(); @@ -76,7 +90,8 @@ namespace Ndk LightComponent& lightComponent = light->GetComponent(); NodeComponent& drawableNode = light->GetComponent(); - lightComponent.AddToRenderQueue(renderQueue, drawableNode.GetTransformMatrix()); + ///TODO: Cache somehow? + lightComponent.AddToRenderQueue(renderQueue, m_coordinateSystemMatrix * drawableNode.GetTransformMatrix()); } NzSceneData sceneData; diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 1e301ecb9..a0f9749a4 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -17,6 +17,14 @@ enum nzBackgroundType nzBackgroundType_Max = nzBackgroundType_User }; +enum nzProjectionType +{ + nzProjectionType_Orthogonal, + nzProjectionType_Perspective, + + nzProjectionType_Max = nzProjectionType_Perspective +}; + enum nzLightType { nzLightType_Directional,