Graphics: Add Camera class
This commit is contained in:
parent
9a311da2c8
commit
793952eb67
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright (C) 2021 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Graphics module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_CAMERA_HPP
|
||||||
|
#define NAZARA_CAMERA_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||||
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
|
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||||
|
#include <Nazara/Math/Rect.hpp>
|
||||||
|
#include <Nazara/Math/Vector2.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class NAZARA_GRAPHICS_API Camera : public AbstractViewer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline Camera(const RenderTarget* renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
|
||||||
|
inline Camera(const Camera& camera);
|
||||||
|
inline Camera(Camera&& camera) noexcept;
|
||||||
|
~Camera() = default;
|
||||||
|
|
||||||
|
inline float GetAspectRatio() const;
|
||||||
|
inline DegreeAnglef GetFOV() const;
|
||||||
|
const RenderTarget& GetRenderTarget() override;
|
||||||
|
inline const Vector2f& GetSize() const;
|
||||||
|
inline const Rectf& GetTargetRegion() const;
|
||||||
|
ViewerInstance& GetViewerInstance() override;
|
||||||
|
const ViewerInstance& GetViewerInstance() const override;
|
||||||
|
const Recti& GetViewport() const override;
|
||||||
|
inline float GetZFar() const;
|
||||||
|
inline float GetZNear() const;
|
||||||
|
|
||||||
|
inline void UpdateFOV(DegreeAnglef fov);
|
||||||
|
inline void UpdateProjectionType(ProjectionType projectionType);
|
||||||
|
inline void UpdateSize(const Vector2f& size);
|
||||||
|
void UpdateTarget(const RenderTarget* framebuffer);
|
||||||
|
inline void UpdateTargetRegion(const Rectf& targetRegion);
|
||||||
|
inline void UpdateViewport(const Recti& viewport);
|
||||||
|
inline void UpdateZFar(float zFar);
|
||||||
|
inline void UpdateZNear(float zNear);
|
||||||
|
|
||||||
|
inline Camera& operator=(const Camera& camera);
|
||||||
|
inline Camera& operator=(Camera&& camera) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline void UpdateProjectionMatrix();
|
||||||
|
inline void UpdateViewport();
|
||||||
|
inline void UpdateViewport(Vector2ui renderTargetSize);
|
||||||
|
|
||||||
|
NazaraSlot(RenderTarget, OnRenderTargetRelease, m_onRenderTargetRelease);
|
||||||
|
NazaraSlot(RenderTarget, OnRenderTargetSizeChange, m_onRenderTargetSizeChange);
|
||||||
|
|
||||||
|
const RenderTarget* m_renderTarget;
|
||||||
|
DegreeAnglef m_fov;
|
||||||
|
ProjectionType m_projectionType;
|
||||||
|
Rectf m_targetRegion;
|
||||||
|
Recti m_viewport;
|
||||||
|
Vector2f m_size;
|
||||||
|
ViewerInstance m_viewerInstance;
|
||||||
|
float m_aspectRatio;
|
||||||
|
float m_zFar;
|
||||||
|
float m_zNear;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Camera.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,202 @@
|
||||||
|
// Copyright (C) 2021 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Components/CameraComponent.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
inline Camera::Camera(const RenderTarget* renderTarget, ProjectionType projectionType) :
|
||||||
|
m_renderTarget(nullptr),
|
||||||
|
m_fov(70.f),
|
||||||
|
m_projectionType(projectionType),
|
||||||
|
m_targetRegion(0.f, 0.f, 1.f, 1.f),
|
||||||
|
m_viewport(0, 0, 0, 0),
|
||||||
|
m_size(-1.f, -1.f),
|
||||||
|
m_zFar(1000.f),
|
||||||
|
m_zNear(1.f)
|
||||||
|
{
|
||||||
|
UpdateTarget(renderTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Camera::Camera(const Camera& camera) :
|
||||||
|
m_renderTarget(nullptr),
|
||||||
|
m_fov(camera.m_fov),
|
||||||
|
m_projectionType(camera.m_projectionType),
|
||||||
|
m_targetRegion(camera.m_targetRegion),
|
||||||
|
m_viewport(camera.m_viewport),
|
||||||
|
m_size(camera.m_size),
|
||||||
|
m_aspectRatio(camera.m_aspectRatio),
|
||||||
|
m_zFar(camera.m_zFar),
|
||||||
|
m_zNear(camera.m_zNear)
|
||||||
|
{
|
||||||
|
UpdateTarget(camera.m_renderTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Camera::Camera(Camera&& camera) noexcept :
|
||||||
|
m_renderTarget(nullptr),
|
||||||
|
m_fov(camera.m_fov),
|
||||||
|
m_projectionType(camera.m_projectionType),
|
||||||
|
m_targetRegion(camera.m_targetRegion),
|
||||||
|
m_viewport(camera.m_viewport),
|
||||||
|
m_size(camera.m_size),
|
||||||
|
m_aspectRatio(camera.m_aspectRatio),
|
||||||
|
m_zFar(camera.m_zFar),
|
||||||
|
m_zNear(camera.m_zNear)
|
||||||
|
{
|
||||||
|
UpdateTarget(camera.m_renderTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Camera::GetAspectRatio() const
|
||||||
|
{
|
||||||
|
return m_aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DegreeAnglef Camera::GetFOV() const
|
||||||
|
{
|
||||||
|
return m_fov;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2f& Camera::GetSize() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Rectf& Camera::GetTargetRegion() const
|
||||||
|
{
|
||||||
|
return m_targetRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Camera::GetZFar() const
|
||||||
|
{
|
||||||
|
return m_zFar;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Camera::GetZNear() const
|
||||||
|
{
|
||||||
|
return m_zNear;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateFOV(DegreeAnglef fov)
|
||||||
|
{
|
||||||
|
m_fov = fov;
|
||||||
|
UpdateProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateZFar(float zFar)
|
||||||
|
{
|
||||||
|
m_zFar = zFar;
|
||||||
|
UpdateProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateZNear(float zNear)
|
||||||
|
{
|
||||||
|
NazaraAssert(!NumberEquals(zNear, 0.f), "zNear cannot be zero");
|
||||||
|
|
||||||
|
m_zNear = zNear;
|
||||||
|
UpdateProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Camera& Camera::operator=(const Camera& camera)
|
||||||
|
{
|
||||||
|
m_fov = camera.m_fov;
|
||||||
|
m_projectionType = camera.m_projectionType;
|
||||||
|
m_targetRegion = camera.m_targetRegion;
|
||||||
|
m_viewport = camera.m_viewport;
|
||||||
|
m_size = camera.m_size;
|
||||||
|
m_aspectRatio = camera.m_aspectRatio;
|
||||||
|
m_zFar = camera.m_zFar;
|
||||||
|
m_zNear = camera.m_zNear;
|
||||||
|
|
||||||
|
UpdateTarget(camera.m_renderTarget);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Camera& Camera::operator=(Camera&& camera) noexcept
|
||||||
|
{
|
||||||
|
m_fov = camera.m_fov;
|
||||||
|
m_projectionType = camera.m_projectionType;
|
||||||
|
m_targetRegion = camera.m_targetRegion;
|
||||||
|
m_viewport = camera.m_viewport;
|
||||||
|
m_size = camera.m_size;
|
||||||
|
m_aspectRatio = camera.m_aspectRatio;
|
||||||
|
m_zFar = camera.m_zFar;
|
||||||
|
m_zNear = camera.m_zNear;
|
||||||
|
|
||||||
|
UpdateTarget(camera.m_renderTarget);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateProjectionType(ProjectionType projectionType)
|
||||||
|
{
|
||||||
|
m_projectionType = projectionType;
|
||||||
|
UpdateProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateTargetRegion(const Rectf& targetRegion)
|
||||||
|
{
|
||||||
|
m_targetRegion = targetRegion;
|
||||||
|
UpdateViewport();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateViewport(const Recti& viewport)
|
||||||
|
{
|
||||||
|
NazaraAssert(m_renderTarget, "no render target");
|
||||||
|
|
||||||
|
// We compute the region necessary to make this view port with the actual size of the target
|
||||||
|
Vector2f invSize = 1.f / Vector2f(m_renderTarget->GetSize());
|
||||||
|
|
||||||
|
UpdateTargetRegion(Rectf(invSize.x * viewport.x, invSize.y * viewport.y, invSize.x * viewport.width, invSize.y * viewport.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateSize(const Vector2f& size)
|
||||||
|
{
|
||||||
|
m_size = size;
|
||||||
|
UpdateProjectionMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateProjectionMatrix()
|
||||||
|
{
|
||||||
|
switch (m_projectionType)
|
||||||
|
{
|
||||||
|
case ProjectionType::Orthographic:
|
||||||
|
if (m_size.x < 0.f || m_size.y < 0.f)
|
||||||
|
m_viewerInstance.UpdateProjectionMatrix(Matrix4f::Ortho(0.f, float(m_viewport.x), 0.f, float(m_viewport.y), m_zNear, m_zFar));
|
||||||
|
else
|
||||||
|
m_viewerInstance.UpdateProjectionMatrix(Matrix4f::Ortho(0.f, m_size.x, 0.f, m_size.y, m_zNear, m_zFar));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProjectionType::Perspective:
|
||||||
|
m_viewerInstance.UpdateProjectionMatrix(Matrix4f::Perspective(m_fov, m_aspectRatio, m_zNear, m_zFar));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateViewport()
|
||||||
|
{
|
||||||
|
NazaraAssert(m_renderTarget, "no rendertarget!");
|
||||||
|
return UpdateViewport(m_renderTarget->GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Camera::UpdateViewport(Vector2ui renderTargetSize)
|
||||||
|
{
|
||||||
|
renderTargetSize.y = std::max(renderTargetSize.y, 1U); // Let's make sure we won't divide by zero
|
||||||
|
|
||||||
|
// Our target region is expressed as % of the viewport dimensions, let's compute it in pixels
|
||||||
|
Rectf fViewport(m_targetRegion);
|
||||||
|
fViewport.x *= renderTargetSize.x;
|
||||||
|
fViewport.y *= renderTargetSize.y;
|
||||||
|
fViewport.width *= renderTargetSize.x;
|
||||||
|
fViewport.height *= renderTargetSize.y;
|
||||||
|
|
||||||
|
m_aspectRatio = fViewport.width / fViewport.height;
|
||||||
|
|
||||||
|
// Convert it back to int
|
||||||
|
m_viewport.Set(fViewport);
|
||||||
|
|
||||||
|
UpdateProjectionMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,66 +8,20 @@
|
||||||
#define NAZARA_CAMERACOMPONENT_HPP
|
#define NAZARA_CAMERACOMPONENT_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
#include <Nazara/Graphics/Camera.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
|
||||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
|
||||||
#include <Nazara/Math/Rect.hpp>
|
|
||||||
#include <Nazara/Math/Vector2.hpp>
|
|
||||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class NAZARA_GRAPHICS_API CameraComponent : public AbstractViewer
|
class NAZARA_GRAPHICS_API CameraComponent : public Camera
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline CameraComponent(const RenderTarget* renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
|
using Camera::Camera;
|
||||||
inline CameraComponent(const CameraComponent& camera);
|
CameraComponent(const CameraComponent& camera) = default;
|
||||||
inline CameraComponent(CameraComponent&& camera) noexcept;
|
CameraComponent(CameraComponent&& camera) noexcept = default;
|
||||||
~CameraComponent() = default;
|
~CameraComponent() = default;
|
||||||
|
|
||||||
inline float GetAspectRatio() const;
|
CameraComponent& operator=(const CameraComponent& camera) = default;
|
||||||
inline DegreeAnglef GetFOV() const;
|
CameraComponent& operator=(CameraComponent&& camera) noexcept = default;
|
||||||
const RenderTarget& GetRenderTarget() override;
|
|
||||||
inline const Vector2f& GetSize() const;
|
|
||||||
inline const Rectf& GetTargetRegion() const;
|
|
||||||
ViewerInstance& GetViewerInstance() override;
|
|
||||||
const ViewerInstance& GetViewerInstance() const override;
|
|
||||||
const Recti& GetViewport() const override;
|
|
||||||
inline float GetZFar() const;
|
|
||||||
inline float GetZNear() const;
|
|
||||||
|
|
||||||
inline void UpdateFOV(DegreeAnglef fov);
|
|
||||||
inline void UpdateProjectionType(ProjectionType projectionType);
|
|
||||||
inline void UpdateSize(const Vector2f& size);
|
|
||||||
void UpdateTarget(const RenderTarget* framebuffer);
|
|
||||||
inline void UpdateTargetRegion(const Rectf& targetRegion);
|
|
||||||
inline void UpdateViewport(const Recti& viewport);
|
|
||||||
inline void UpdateZFar(float zFar);
|
|
||||||
inline void UpdateZNear(float zNear);
|
|
||||||
|
|
||||||
inline CameraComponent& operator=(const CameraComponent& camera);
|
|
||||||
inline CameraComponent& operator=(CameraComponent&& camera) noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline void UpdateProjectionMatrix();
|
|
||||||
inline void UpdateViewport();
|
|
||||||
inline void UpdateViewport(Vector2ui renderTargetSize);
|
|
||||||
|
|
||||||
NazaraSlot(RenderTarget, OnRenderTargetRelease, m_onRenderTargetRelease);
|
|
||||||
NazaraSlot(RenderTarget, OnRenderTargetSizeChange, m_onRenderTargetSizeChange);
|
|
||||||
|
|
||||||
const RenderTarget* m_renderTarget;
|
|
||||||
DegreeAnglef m_fov;
|
|
||||||
ProjectionType m_projectionType;
|
|
||||||
Rectf m_targetRegion;
|
|
||||||
Recti m_viewport;
|
|
||||||
Vector2f m_size;
|
|
||||||
ViewerInstance m_viewerInstance;
|
|
||||||
float m_aspectRatio;
|
|
||||||
float m_zFar;
|
|
||||||
float m_zNear;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,196 +7,4 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline CameraComponent::CameraComponent(const RenderTarget* renderTarget, ProjectionType projectionType) :
|
|
||||||
m_renderTarget(nullptr),
|
|
||||||
m_fov(70.f),
|
|
||||||
m_projectionType(projectionType),
|
|
||||||
m_targetRegion(0.f, 0.f, 1.f, 1.f),
|
|
||||||
m_viewport(0, 0, 0, 0),
|
|
||||||
m_size(-1.f, -1.f),
|
|
||||||
m_zFar(1000.f),
|
|
||||||
m_zNear(1.f)
|
|
||||||
{
|
|
||||||
UpdateTarget(renderTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CameraComponent::CameraComponent(const CameraComponent& camera) :
|
|
||||||
m_renderTarget(nullptr),
|
|
||||||
m_fov(camera.m_fov),
|
|
||||||
m_projectionType(camera.m_projectionType),
|
|
||||||
m_targetRegion(camera.m_targetRegion),
|
|
||||||
m_viewport(camera.m_viewport),
|
|
||||||
m_size(camera.m_size),
|
|
||||||
m_aspectRatio(camera.m_aspectRatio),
|
|
||||||
m_zFar(camera.m_zFar),
|
|
||||||
m_zNear(camera.m_zNear)
|
|
||||||
{
|
|
||||||
UpdateTarget(camera.m_renderTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CameraComponent::CameraComponent(CameraComponent&& camera) noexcept :
|
|
||||||
m_renderTarget(nullptr),
|
|
||||||
m_fov(camera.m_fov),
|
|
||||||
m_projectionType(camera.m_projectionType),
|
|
||||||
m_targetRegion(camera.m_targetRegion),
|
|
||||||
m_viewport(camera.m_viewport),
|
|
||||||
m_size(camera.m_size),
|
|
||||||
m_aspectRatio(camera.m_aspectRatio),
|
|
||||||
m_zFar(camera.m_zFar),
|
|
||||||
m_zNear(camera.m_zNear)
|
|
||||||
{
|
|
||||||
UpdateTarget(camera.m_renderTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float CameraComponent::GetAspectRatio() const
|
|
||||||
{
|
|
||||||
return m_aspectRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DegreeAnglef CameraComponent::GetFOV() const
|
|
||||||
{
|
|
||||||
return m_fov;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const Vector2f& CameraComponent::GetSize() const
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const Rectf& CameraComponent::GetTargetRegion() const
|
|
||||||
{
|
|
||||||
return m_targetRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float CameraComponent::GetZFar() const
|
|
||||||
{
|
|
||||||
return m_zFar;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float CameraComponent::GetZNear() const
|
|
||||||
{
|
|
||||||
return m_zNear;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateFOV(DegreeAnglef fov)
|
|
||||||
{
|
|
||||||
m_fov = fov;
|
|
||||||
UpdateProjectionMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateZFar(float zFar)
|
|
||||||
{
|
|
||||||
m_zFar = zFar;
|
|
||||||
UpdateProjectionMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateZNear(float zNear)
|
|
||||||
{
|
|
||||||
NazaraAssert(!NumberEquals(zNear, 0.f), "zNear cannot be zero");
|
|
||||||
|
|
||||||
m_zNear = zNear;
|
|
||||||
UpdateProjectionMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CameraComponent& CameraComponent::operator=(const CameraComponent& camera)
|
|
||||||
{
|
|
||||||
m_fov = camera.m_fov;
|
|
||||||
m_projectionType = camera.m_projectionType;
|
|
||||||
m_targetRegion = camera.m_targetRegion;
|
|
||||||
m_viewport = camera.m_viewport;
|
|
||||||
m_size = camera.m_size;
|
|
||||||
m_aspectRatio = camera.m_aspectRatio;
|
|
||||||
m_zFar = camera.m_zFar;
|
|
||||||
m_zNear = camera.m_zNear;
|
|
||||||
|
|
||||||
UpdateTarget(camera.m_renderTarget);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CameraComponent& CameraComponent::operator=(CameraComponent&& camera) noexcept
|
|
||||||
{
|
|
||||||
m_fov = camera.m_fov;
|
|
||||||
m_projectionType = camera.m_projectionType;
|
|
||||||
m_targetRegion = camera.m_targetRegion;
|
|
||||||
m_viewport = camera.m_viewport;
|
|
||||||
m_size = camera.m_size;
|
|
||||||
m_aspectRatio = camera.m_aspectRatio;
|
|
||||||
m_zFar = camera.m_zFar;
|
|
||||||
m_zNear = camera.m_zNear;
|
|
||||||
|
|
||||||
UpdateTarget(camera.m_renderTarget);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateProjectionType(ProjectionType projectionType)
|
|
||||||
{
|
|
||||||
m_projectionType = projectionType;
|
|
||||||
UpdateProjectionMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateTargetRegion(const Rectf& targetRegion)
|
|
||||||
{
|
|
||||||
m_targetRegion = targetRegion;
|
|
||||||
UpdateViewport();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateViewport(const Recti& viewport)
|
|
||||||
{
|
|
||||||
NazaraAssert(m_renderTarget, "no render target");
|
|
||||||
|
|
||||||
// We compute the region necessary to make this view port with the actual size of the target
|
|
||||||
Vector2f invSize = 1.f / Vector2f(m_renderTarget->GetSize());
|
|
||||||
|
|
||||||
UpdateTargetRegion(Rectf(invSize.x * viewport.x, invSize.y * viewport.y, invSize.x * viewport.width, invSize.y * viewport.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateSize(const Vector2f& size)
|
|
||||||
{
|
|
||||||
m_size = size;
|
|
||||||
UpdateProjectionMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateProjectionMatrix()
|
|
||||||
{
|
|
||||||
switch (m_projectionType)
|
|
||||||
{
|
|
||||||
case ProjectionType::Orthographic:
|
|
||||||
if (m_size.x < 0.f || m_size.y < 0.f)
|
|
||||||
m_viewerInstance.UpdateProjectionMatrix(Matrix4f::Ortho(0.f, float(m_viewport.x), 0.f, float(m_viewport.y), m_zNear, m_zFar));
|
|
||||||
else
|
|
||||||
m_viewerInstance.UpdateProjectionMatrix(Matrix4f::Ortho(0.f, m_size.x, 0.f, m_size.y, m_zNear, m_zFar));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ProjectionType::Perspective:
|
|
||||||
m_viewerInstance.UpdateProjectionMatrix(Matrix4f::Perspective(m_fov, m_aspectRatio, m_zNear, m_zFar));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateViewport()
|
|
||||||
{
|
|
||||||
NazaraAssert(m_renderTarget, "no rendertarget!");
|
|
||||||
return UpdateViewport(m_renderTarget->GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CameraComponent::UpdateViewport(Vector2ui renderTargetSize)
|
|
||||||
{
|
|
||||||
renderTargetSize.y = std::max(renderTargetSize.y, 1U); // Let's make sure we won't divide by zero
|
|
||||||
|
|
||||||
// Our target region is expressed as % of the viewport dimensions, let's compute it in pixels
|
|
||||||
Rectf fViewport(m_targetRegion);
|
|
||||||
fViewport.x *= renderTargetSize.x;
|
|
||||||
fViewport.y *= renderTargetSize.y;
|
|
||||||
fViewport.width *= renderTargetSize.x;
|
|
||||||
fViewport.height *= renderTargetSize.y;
|
|
||||||
|
|
||||||
m_aspectRatio = fViewport.width / fViewport.height;
|
|
||||||
|
|
||||||
// Convert it back to int
|
|
||||||
m_viewport.Set(fViewport);
|
|
||||||
|
|
||||||
UpdateProjectionMatrix();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright (C) 2021 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Camera.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
const RenderTarget& Camera::GetRenderTarget()
|
||||||
|
{
|
||||||
|
if (!m_renderTarget)
|
||||||
|
throw std::runtime_error("no rendertarget set");
|
||||||
|
|
||||||
|
return* m_renderTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewerInstance& Camera::GetViewerInstance()
|
||||||
|
{
|
||||||
|
return m_viewerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ViewerInstance& Camera::GetViewerInstance() const
|
||||||
|
{
|
||||||
|
return m_viewerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Recti& Camera::GetViewport() const
|
||||||
|
{
|
||||||
|
return m_viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::UpdateTarget(const RenderTarget* renderTarget)
|
||||||
|
{
|
||||||
|
m_onRenderTargetRelease.Disconnect();
|
||||||
|
m_onRenderTargetSizeChange.Disconnect();
|
||||||
|
|
||||||
|
m_renderTarget = renderTarget;
|
||||||
|
if (m_renderTarget)
|
||||||
|
{
|
||||||
|
m_onRenderTargetRelease.Connect(m_renderTarget->OnRenderTargetRelease, [this](const RenderTarget*)
|
||||||
|
{
|
||||||
|
UpdateTarget(nullptr);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_onRenderTargetSizeChange.Connect(m_renderTarget->OnRenderTargetSizeChange, [this](const RenderTarget*, const Vector2ui& newSize)
|
||||||
|
{
|
||||||
|
UpdateViewport(newSize);
|
||||||
|
});
|
||||||
|
|
||||||
|
UpdateViewport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,53 +3,8 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||||
|
|
||||||
#include <Nazara/Graphics/Components/CameraComponent.hpp>
|
#include <Nazara/Graphics/Components/CameraComponent.hpp>
|
||||||
#include <stdexcept>
|
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
const RenderTarget& CameraComponent::GetRenderTarget()
|
|
||||||
{
|
|
||||||
if (!m_renderTarget)
|
|
||||||
throw std::runtime_error("no rendertarget set");
|
|
||||||
|
|
||||||
return* m_renderTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewerInstance& CameraComponent::GetViewerInstance()
|
|
||||||
{
|
|
||||||
return m_viewerInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ViewerInstance& CameraComponent::GetViewerInstance() const
|
|
||||||
{
|
|
||||||
return m_viewerInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Recti& CameraComponent::GetViewport() const
|
|
||||||
{
|
|
||||||
return m_viewport;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraComponent::UpdateTarget(const RenderTarget* renderTarget)
|
|
||||||
{
|
|
||||||
m_onRenderTargetRelease.Disconnect();
|
|
||||||
m_onRenderTargetSizeChange.Disconnect();
|
|
||||||
|
|
||||||
m_renderTarget = renderTarget;
|
|
||||||
if (m_renderTarget)
|
|
||||||
{
|
|
||||||
m_onRenderTargetRelease.Connect(m_renderTarget->OnRenderTargetRelease, [this](const RenderTarget*)
|
|
||||||
{
|
|
||||||
UpdateTarget(nullptr);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_onRenderTargetSizeChange.Connect(m_renderTarget->OnRenderTargetSizeChange, [this](const RenderTarget*, const Vector2ui& newSize)
|
|
||||||
{
|
|
||||||
UpdateViewport(newSize);
|
|
||||||
});
|
|
||||||
|
|
||||||
UpdateViewport();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue