Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ set(SCENE_SOURCES
src/Scene/GameObject.cpp
src/Scene/MaterialComponent.cpp
src/Scene/MeshComponent.cpp
src/Scene/RenderView.cpp
src/Scene/SceneBase.cpp
src/Scene/Scene.cpp
src/Scene/TransformComponent.cpp
Expand Down
89 changes: 53 additions & 36 deletions include/public/Camera/Camera.hpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
#ifndef _CAMERA_HPP_
#define _CAMERA_HPP_

#include <Utility/Exception.hpp>
#include <Core/GameObject.hpp>
#include <Camera/RenderView.hpp>
#include <Camera/ViewFrustum.hpp>
#include <Core/GameObject.hpp>
#include <Math/Matrix.hpp>
#include <Math/Vector.hpp>
#include <Utility/Exception.hpp>

namespace Sleak {
/// Perspective or orthographic projection mode for a Camera.
/// @ingroup camera
enum class ProjectionType {Perspective, Orthographic};

/// GameObject that owns the engine's single active view/projection
/// matrices and view frustum. Position/orientation come from CameraController subclasses.
/// GameObject that describes a view: position, look target, and
/// projection. Position/orientation come from CameraController subclasses.
///
/// Create one, add it to the scene, and call
/// SceneBase::SetActiveCamera() so the renderer knows which view to
Expand All @@ -23,12 +24,11 @@ namespace Sleak {
/// ColliderComponent and RigidbodyComponent for a player character
/// that collides with the world.
///
/// The view and projection matrices are static, shared state. The
/// active camera rewrites them each Update() through
/// GetMainViewMatrix(), GetMainProjectionMatrix(),
/// GetMainCameraPosition(), and GetMainViewFrustum(), which is how the
/// renderer and CullingSystem read the current view. Only one camera
/// should be active at a time.
/// Each camera keeps its own view and projection matrices. Only the
/// scene's active camera drives rendering: after the update pass the
/// scene turns it into a RenderView through BuildRenderView() and
/// submits the frame with that. Other cameras in the scene can move
/// freely without affecting what is drawn or culled.
///
/// Orientation is expressed as a look target rather than a rotation.
/// SetLookTarget() aims at a world point and SetDirection() aims along
Expand Down Expand Up @@ -63,7 +63,7 @@ namespace Sleak {
float fov = 60, float near = 1.0f, float far = 1000.0f);

void Initialize() override;
/// Recalculates the view/projection matrices and frustum while active.
/// Recalculates this camera's view/projection matrices while active.
void Update(float DeltaTime) override;

void SetFieldOfView(float fov) {fieldOfView = fov;}
Expand Down Expand Up @@ -100,44 +100,61 @@ namespace Sleak {
/// Updates the viewport dimensions and recomputes the projection matrix.
void OnResize(uint32_t width, uint32_t height);

const Math::Matrix4& GetViewMatrix() const { return m_view; }
const Math::Matrix4& GetProjectionMatrix() const {
return m_projection;
}

/// Builds a RenderView from the camera's current position, target
/// and projection.
RenderView BuildRenderView() const;

/// @deprecated Use RenderView::GetCurrent().view.
static const Math::Matrix4& GetMainViewMatrix() {
return Camera::View;
return RenderView::GetCurrent().view;
}

/// @deprecated Use RenderView::GetCurrent().projection.
static const Math::Matrix4& GetMainProjectionMatrix() {
return Camera::Projection;
return RenderView::GetCurrent().projection;
}

/// @deprecated Use RenderView::GetCurrent().position.
static const Math::Vector3D& GetMainCameraPosition() {
return Camera::MainPosition;
return RenderView::GetCurrent().position;
}

/// @deprecated Use RenderView::GetCurrent().frustum.
static const ViewFrustum& GetMainViewFrustum() {
return Camera::s_frustum;
return RenderView::GetCurrent().frustum;
}

protected:
/// Rebuilds the static view matrix and view frustum from position/target/up, and begins culling for the frame.
void RecalculateViewMatrix();
/// Rebuilds the static projection matrix from FOV/aspect/near/far or the orthographic extents.
void RecalculateProjectionMatrix();

float fieldOfView;
float nearPlane;
float farPlane;
float width;
float height;

ProjectionType type = ProjectionType::Perspective;

Math::Vector3D Position;
Math::Vector3D LookTarget;
Math::Vector3D Up = Math::Vector3D::Up();

static Math::Matrix4 View;
static Math::Matrix4 Projection;
static Math::Vector3D MainPosition;
static ViewFrustum s_frustum;
/// Rebuilds this camera's view matrix from position/target/up.
void RecalculateViewMatrix();
/// Rebuilds this camera's projection matrix from FOV/aspect/near/far
/// or the orthographic extents.
void RecalculateProjectionMatrix();

/// LookAt matrix for the current position, target and up vector.
Math::Matrix4 ComputeViewMatrix() const;
/// Perspective or orthographic matrix for the current settings.
Math::Matrix4 ComputeProjectionMatrix() const;

float fieldOfView;
float nearPlane;
float farPlane;
float width;
float height;

ProjectionType type = ProjectionType::Perspective;

Math::Vector3D Position;
Math::Vector3D LookTarget;
Math::Vector3D Up = Math::Vector3D::Up();

Math::Matrix4 m_view = Math::Matrix4::Identity();
Math::Matrix4 m_projection = Math::Matrix4::Identity();
};
}

Expand Down
45 changes: 45 additions & 0 deletions include/public/Camera/RenderView.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef _RENDER_VIEW_HPP_
#define _RENDER_VIEW_HPP_

#include <Camera/ViewFrustum.hpp>
#include <Core/OSDef.hpp>
#include <Math/Matrix.hpp>
#include <Math/Vector.hpp>

namespace Sleak {

/// Snapshot of one camera for one frame: view, projection, eye position
/// and the frustum culling tests against.
///
/// SceneBase builds one from its active camera after the update pass
/// and hands it to the render submission step, so cameras that are not
/// the active one never touch what gets drawn. It is a plain value, so
/// rendering a second view means building a second RenderView.
///
/// Renderer code that has no scene to ask reads the view the frame is
/// being submitted with through GetCurrent().
///
/// @see Camera, SceneBase, CullingSystem
/// @ingroup camera
struct ENGINE_API RenderView {
Math::Matrix4 view = Math::Matrix4::Identity();
Math::Matrix4 projection = Math::Matrix4::Identity();
Math::Matrix4 viewProjection = Math::Matrix4::Identity();
Math::Vector3D position = Math::Vector3D(0, 0, 0);
ViewFrustum frustum{};

/// Builds a view from row-vector matrices, deriving viewProjection
/// and the frustum.
static RenderView Create(const Math::Matrix4& view,
const Math::Matrix4& projection,
const Math::Vector3D& position);

/// The view the current frame is being submitted with.
static const RenderView& GetCurrent();
/// Makes view the one GetCurrent() returns until the next call.
static void SetCurrent(const RenderView& view);
};

} // namespace Sleak

#endif
2 changes: 2 additions & 0 deletions include/public/Core/GameObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ namespace Sleak {
virtual void Update(float deltaTime);
virtual void FixedUpdate(float fixedDeltaTime);
virtual void LateUpdate(float deltaTime);
/// Calls SubmitRender on every component, then on active children.
virtual void SubmitRender(const RenderView& view);

/// Enables or disables the object, firing OnEnable/OnDisable on its components.
void SetActive(bool active);
Expand Down
17 changes: 13 additions & 4 deletions include/public/Core/SceneBase.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#ifndef _SCENE_BASE_HPP_
#define _SCENE_BASE_HPP_

#include <string>
#include <Memory/RefPtr.hpp>
#include <Camera/RenderView.hpp>
#include <Core/OSDef.hpp>
#include <Memory/RefPtr.hpp>
#include <Utility/Container/List.hpp>

#include <string>

namespace Sleak {

Expand Down Expand Up @@ -94,7 +94,8 @@ namespace Sleak {
virtual void Begin() = 0;

// Update loops
/// Advances all active, root-level objects by deltaTime, then steps lighting and physics.
/// Advances all active, root-level objects and physics, builds the
/// frame's RenderView from the active camera, then submits rendering.
virtual void Update(float deltaTime) = 0;
/// Advances all active, root-level objects on the fixed timestep.
virtual void FixedUpdate(float fixedDeltaTime);
Expand Down Expand Up @@ -141,7 +142,11 @@ namespace Sleak {
size_t GetObjectCount() const { return Objects.GetSize(); }

Camera* GetActiveCamera() const { return m_activeCamera; }
/// Picks the camera the scene renders and culls from.
void SetActiveCamera(Camera* cam) { m_activeCamera = cam; }
/// The view this frame was submitted with, built from the active
/// camera.
const RenderView& GetRenderView() const { return m_renderView; }

LightManager* GetLightManager() const {
return m_lightManager;
Expand All @@ -165,11 +170,15 @@ namespace Sleak {
List<GameObject*> m_pendingDestroy;

Camera* m_activeCamera = nullptr;
RenderView m_renderView;

LightManager* m_lightManager = nullptr;
Physics::PhysicsWorld* m_physicsWorld = nullptr;
Skybox* m_skybox = nullptr;

/// Queues draw work for every active object, lights, skybox and
/// debug lines, seen from view.
void SubmitRender(const RenderView& view);
/// Actually deletes objects queued by DestroyObject().
void ProcessPendingDestroy();
/// Destroys every object still owned by the scene, e.g. during Unload().
Expand Down
8 changes: 4 additions & 4 deletions include/public/Culling/CullingSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ namespace Sleak {
/// game-submitted occluder volumes. Backend-agnostic (no GPU work).
///
/// Frame protocol:
/// 1. BeginFrame(...) once per frame after camera update
/// (the engine calls this automatically from the main camera)
/// 1. BeginFrame(...) once per frame after the update pass
/// (SceneBase calls this with the active camera's RenderView)
/// 2. SubmitOccluderBox/Triangles any number of world-space occluders
/// 3. FinalizeOccluders() sort by distance, rasterize budget
/// 4. IsVisible(aabb) frustum + occlusion query
/// Steps 2-3 are optional; IsVisible degrades to frustum-only.
///
/// Everything here is static and lives for the process. The main camera
/// calls BeginFrame() for you during its update, so a game that only wants
/// Everything here is static and lives for the process. The scene calls
/// BeginFrame() for you from its active camera, so a game that only wants
/// frustum culling can call IsVisible() and stop reading here.
///
/// Occlusion culling is the part you opt into. Submit occluder volumes
Expand Down
8 changes: 7 additions & 1 deletion include/public/ECS/Component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Sleak {
class GameObject;
struct RenderView;
/// Base for behavior attached to a GameObject. Owner deletes it via
/// GameObject::RemoveComponent(), never directly.
///
Expand All @@ -24,7 +25,9 @@ namespace Sleak {
/// Lifecycle: the object calls Initialize() once (immediately if the
/// object is already initialized when the component is attached, and
/// otherwise during the object's own Initialize()), then OnEnable() if
/// the object is active, then Update() every frame.
/// the object is active, then Update() every frame. Components that
/// draw override SubmitRender(), which the scene calls once per frame
/// with the active camera's RenderView after all updates have run.
///
/// @code{.cpp}
/// class SpinComponent : public Sleak::Component {
Expand Down Expand Up @@ -67,6 +70,9 @@ namespace Sleak {
virtual void Update(float deltaTime) = 0;
virtual void FixedUpdate(float fixedDeltaTime) {}
virtual void LateUpdate(float deltaTime) {}
/// Queues this component's draw work for view; runs after every
/// Update of the frame.
virtual void SubmitRender(const RenderView& view) {}

/// Called when the component is detached or the owner is destroyed.
virtual void OnDestroy() {}
Expand Down
Loading
Loading