Add renderer phase A textured scene path
This commit is contained in:
33
engine/include/XCEngine/Components/MeshFilterComponent.h
Normal file
33
engine/include/XCEngine/Components/MeshFilterComponent.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Components/Component.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
#include <XCEngine/Resources/Mesh/Mesh.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
class MeshFilterComponent : public Component {
|
||||
public:
|
||||
std::string GetName() const override { return "MeshFilter"; }
|
||||
|
||||
Resources::Mesh* GetMesh() const { return m_mesh.Get(); }
|
||||
const Resources::ResourceHandle<Resources::Mesh>& GetMeshHandle() const { return m_mesh; }
|
||||
const std::string& GetMeshPath() const { return m_meshPath; }
|
||||
|
||||
void SetMesh(const Resources::ResourceHandle<Resources::Mesh>& mesh);
|
||||
void SetMesh(Resources::Mesh* mesh);
|
||||
void ClearMesh();
|
||||
|
||||
void Serialize(std::ostream& os) const override;
|
||||
void Deserialize(std::istream& is) override;
|
||||
|
||||
private:
|
||||
Resources::ResourceHandle<Resources::Mesh> m_mesh;
|
||||
std::string m_meshPath;
|
||||
};
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
52
engine/include/XCEngine/Components/MeshRendererComponent.h
Normal file
52
engine/include/XCEngine/Components/MeshRendererComponent.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Components/Component.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
#include <XCEngine/Resources/Material/Material.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
class MeshRendererComponent : public Component {
|
||||
public:
|
||||
std::string GetName() const override { return "MeshRenderer"; }
|
||||
|
||||
size_t GetMaterialCount() const { return m_materials.size(); }
|
||||
Resources::Material* GetMaterial(size_t index) const;
|
||||
const Resources::ResourceHandle<Resources::Material>& GetMaterialHandle(size_t index) const;
|
||||
const std::vector<std::string>& GetMaterialPaths() const { return m_materialPaths; }
|
||||
|
||||
void SetMaterial(size_t index, const Resources::ResourceHandle<Resources::Material>& material);
|
||||
void SetMaterial(size_t index, Resources::Material* material);
|
||||
void SetMaterials(const std::vector<Resources::ResourceHandle<Resources::Material>>& materials);
|
||||
void ClearMaterials();
|
||||
|
||||
bool GetCastShadows() const { return m_castShadows; }
|
||||
void SetCastShadows(bool value) { m_castShadows = value; }
|
||||
|
||||
bool GetReceiveShadows() const { return m_receiveShadows; }
|
||||
void SetReceiveShadows(bool value) { m_receiveShadows = value; }
|
||||
|
||||
uint32_t GetRenderLayer() const { return m_renderLayer; }
|
||||
void SetRenderLayer(uint32_t value) { m_renderLayer = value; }
|
||||
|
||||
void Serialize(std::ostream& os) const override;
|
||||
void Deserialize(std::istream& is) override;
|
||||
|
||||
private:
|
||||
void EnsureMaterialSlot(size_t index);
|
||||
static std::string MaterialPathFromHandle(const Resources::ResourceHandle<Resources::Material>& material);
|
||||
|
||||
std::vector<Resources::ResourceHandle<Resources::Material>> m_materials;
|
||||
std::vector<std::string> m_materialPaths;
|
||||
bool m_castShadows = true;
|
||||
bool m_receiveShadows = true;
|
||||
uint32_t m_renderLayer = 0;
|
||||
};
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/RenderPipeline.h>
|
||||
#include <XCEngine/Rendering/RenderResourceCache.h>
|
||||
|
||||
#include <XCEngine/RHI/RHIDescriptorPool.h>
|
||||
#include <XCEngine/RHI/RHIDescriptorSet.h>
|
||||
#include <XCEngine/RHI/RHIPipelineLayout.h>
|
||||
#include <XCEngine/RHI/RHIPipelineState.h>
|
||||
#include <XCEngine/RHI/RHIResourceView.h>
|
||||
#include <XCEngine/RHI/RHISampler.h>
|
||||
#include <XCEngine/RHI/RHITexture.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
class Material;
|
||||
class Texture;
|
||||
} // namespace Resources
|
||||
|
||||
namespace Rendering {
|
||||
class RenderSurface;
|
||||
|
||||
namespace Pipelines {
|
||||
|
||||
class BuiltinForwardPipeline : public RenderPipeline {
|
||||
public:
|
||||
BuiltinForwardPipeline() = default;
|
||||
~BuiltinForwardPipeline() override;
|
||||
|
||||
bool Initialize(const RenderContext& context) override;
|
||||
void Shutdown() override;
|
||||
bool Render(
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const RenderSceneData& sceneData) override;
|
||||
|
||||
private:
|
||||
struct PerObjectConstants {
|
||||
Math::Matrix4x4 projection = Math::Matrix4x4::Identity();
|
||||
Math::Matrix4x4 view = Math::Matrix4x4::Identity();
|
||||
Math::Matrix4x4 model = Math::Matrix4x4::Identity();
|
||||
};
|
||||
|
||||
bool EnsureInitialized(const RenderContext& context);
|
||||
bool CreatePipelineResources(const RenderContext& context);
|
||||
void DestroyPipelineResources();
|
||||
|
||||
const Resources::Material* ResolveMaterial(const VisibleRenderObject& visibleObject, uint32_t materialIndex) const;
|
||||
const Resources::Texture* ResolveTexture(const Resources::Material* material) const;
|
||||
RHI::RHIResourceView* ResolveTextureView(const VisibleRenderObject& visibleObject, uint32_t materialIndex);
|
||||
bool DrawVisibleObject(
|
||||
const RenderContext& context,
|
||||
const RenderSceneData& sceneData,
|
||||
const VisibleRenderObject& visibleObject);
|
||||
|
||||
RHI::RHIDevice* m_device = nullptr;
|
||||
RHI::RHIType m_backendType = RHI::RHIType::D3D12;
|
||||
bool m_initialized = false;
|
||||
|
||||
RenderResourceCache m_resourceCache;
|
||||
|
||||
RHI::RHIDescriptorPool* m_constantPool = nullptr;
|
||||
RHI::RHIDescriptorSet* m_constantSet = nullptr;
|
||||
RHI::RHIDescriptorPool* m_texturePool = nullptr;
|
||||
RHI::RHIDescriptorSet* m_textureSet = nullptr;
|
||||
RHI::RHIDescriptorPool* m_samplerPool = nullptr;
|
||||
RHI::RHIDescriptorSet* m_samplerSet = nullptr;
|
||||
RHI::RHIPipelineLayout* m_pipelineLayout = nullptr;
|
||||
RHI::RHIPipelineState* m_pipelineState = nullptr;
|
||||
RHI::RHISampler* m_sampler = nullptr;
|
||||
RHI::RHITexture* m_fallbackTexture = nullptr;
|
||||
RHI::RHIResourceView* m_fallbackTextureView = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Pipelines
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
23
engine/include/XCEngine/Rendering/RenderCameraData.h
Normal file
23
engine/include/XCEngine/Rendering/RenderCameraData.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Math/Color.h>
|
||||
#include <XCEngine/Core/Math/Matrix4.h>
|
||||
#include <XCEngine/Core/Math/Vector3.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
struct RenderCameraData {
|
||||
Math::Matrix4x4 view = Math::Matrix4x4::Identity();
|
||||
Math::Matrix4x4 projection = Math::Matrix4x4::Identity();
|
||||
Math::Matrix4x4 viewProjection = Math::Matrix4x4::Identity();
|
||||
Math::Vector3 worldPosition = Math::Vector3::Zero();
|
||||
Math::Color clearColor = Math::Color::Black();
|
||||
uint32_t viewportWidth = 0;
|
||||
uint32_t viewportHeight = 0;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
26
engine/include/XCEngine/Rendering/RenderContext.h
Normal file
26
engine/include/XCEngine/Rendering/RenderContext.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/RHI/RHIEnums.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
class RHICommandList;
|
||||
class RHICommandQueue;
|
||||
class RHIDevice;
|
||||
} // namespace RHI
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct RenderContext {
|
||||
RHI::RHIDevice* device = nullptr;
|
||||
RHI::RHICommandList* commandList = nullptr;
|
||||
RHI::RHICommandQueue* commandQueue = nullptr;
|
||||
RHI::RHIType backendType = RHI::RHIType::D3D12;
|
||||
|
||||
bool IsValid() const {
|
||||
return device != nullptr && commandList != nullptr && commandQueue != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
24
engine/include/XCEngine/Rendering/RenderPipeline.h
Normal file
24
engine/include/XCEngine/Rendering/RenderPipeline.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/RenderContext.h>
|
||||
#include <XCEngine/Rendering/RenderSceneExtractor.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
class RenderSurface;
|
||||
|
||||
class RenderPipeline {
|
||||
public:
|
||||
virtual ~RenderPipeline() = default;
|
||||
|
||||
virtual bool Initialize(const RenderContext& context) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool Render(
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const RenderSceneData& sceneData) = 0;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
18
engine/include/XCEngine/Rendering/RenderPipelineAsset.h
Normal file
18
engine/include/XCEngine/Rendering/RenderPipelineAsset.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
class RenderPipeline;
|
||||
|
||||
class RenderPipelineAsset {
|
||||
public:
|
||||
virtual ~RenderPipelineAsset() = default;
|
||||
|
||||
virtual std::unique_ptr<RenderPipeline> CreatePipeline() const = 0;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
51
engine/include/XCEngine/Rendering/RenderResourceCache.h
Normal file
51
engine/include/XCEngine/Rendering/RenderResourceCache.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/RHI/RHIBuffer.h>
|
||||
#include <XCEngine/RHI/RHIDevice.h>
|
||||
#include <XCEngine/RHI/RHIResourceView.h>
|
||||
#include <XCEngine/RHI/RHITexture.h>
|
||||
#include <XCEngine/Resources/Mesh/Mesh.h>
|
||||
#include <XCEngine/Resources/Texture/Texture.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
class RenderResourceCache {
|
||||
public:
|
||||
struct CachedMesh {
|
||||
RHI::RHIBuffer* vertexBuffer = nullptr;
|
||||
RHI::RHIResourceView* vertexBufferView = nullptr;
|
||||
RHI::RHIBuffer* indexBuffer = nullptr;
|
||||
RHI::RHIResourceView* indexBufferView = nullptr;
|
||||
uint32_t vertexCount = 0;
|
||||
uint32_t indexCount = 0;
|
||||
uint32_t vertexStride = 0;
|
||||
bool uses32BitIndices = false;
|
||||
};
|
||||
|
||||
struct CachedTexture {
|
||||
RHI::RHITexture* texture = nullptr;
|
||||
RHI::RHIResourceView* shaderResourceView = nullptr;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
};
|
||||
|
||||
~RenderResourceCache();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
const CachedMesh* GetOrCreateMesh(RHI::RHIDevice* device, const Resources::Mesh* mesh);
|
||||
const CachedTexture* GetOrCreateTexture(RHI::RHIDevice* device, const Resources::Texture* texture);
|
||||
|
||||
private:
|
||||
bool UploadMesh(RHI::RHIDevice* device, const Resources::Mesh* mesh, CachedMesh& cachedMesh);
|
||||
bool UploadTexture(RHI::RHIDevice* device, const Resources::Texture* texture, CachedTexture& cachedTexture);
|
||||
|
||||
std::unordered_map<const Resources::Mesh*, CachedMesh> m_meshCache;
|
||||
std::unordered_map<const Resources::Texture*, CachedTexture> m_textureCache;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
48
engine/include/XCEngine/Rendering/RenderSceneExtractor.h
Normal file
48
engine/include/XCEngine/Rendering/RenderSceneExtractor.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/RenderCameraData.h>
|
||||
#include <XCEngine/Rendering/VisibleRenderObject.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
class CameraComponent;
|
||||
class GameObject;
|
||||
class Scene;
|
||||
} // namespace Components
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct RenderSceneData {
|
||||
Components::CameraComponent* camera = nullptr;
|
||||
RenderCameraData cameraData;
|
||||
std::vector<VisibleRenderObject> visibleObjects;
|
||||
|
||||
bool HasCamera() const { return camera != nullptr; }
|
||||
};
|
||||
|
||||
class RenderSceneExtractor {
|
||||
public:
|
||||
RenderSceneData Extract(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
uint32_t viewportWidth,
|
||||
uint32_t viewportHeight) const;
|
||||
|
||||
private:
|
||||
Components::CameraComponent* SelectCamera(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera) const;
|
||||
RenderCameraData BuildCameraData(
|
||||
const Components::CameraComponent& camera,
|
||||
uint32_t viewportWidth,
|
||||
uint32_t viewportHeight) const;
|
||||
void ExtractVisibleObjects(
|
||||
Components::GameObject* gameObject,
|
||||
std::vector<VisibleRenderObject>& visibleObjects) const;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
59
engine/include/XCEngine/Rendering/RenderSurface.h
Normal file
59
engine/include/XCEngine/Rendering/RenderSurface.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Math/Color.h>
|
||||
#include <XCEngine/RHI/RHIEnums.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
class RHIResourceView;
|
||||
} // namespace RHI
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
class RenderSurface {
|
||||
public:
|
||||
RenderSurface() = default;
|
||||
RenderSurface(uint32_t width, uint32_t height);
|
||||
|
||||
uint32_t GetWidth() const { return m_width; }
|
||||
uint32_t GetHeight() const { return m_height; }
|
||||
void SetSize(uint32_t width, uint32_t height);
|
||||
|
||||
void SetColorAttachment(RHI::RHIResourceView* colorAttachment);
|
||||
void SetColorAttachments(const std::vector<RHI::RHIResourceView*>& colorAttachments);
|
||||
const std::vector<RHI::RHIResourceView*>& GetColorAttachments() const { return m_colorAttachments; }
|
||||
|
||||
void SetDepthAttachment(RHI::RHIResourceView* depthAttachment) { m_depthAttachment = depthAttachment; }
|
||||
RHI::RHIResourceView* GetDepthAttachment() const { return m_depthAttachment; }
|
||||
|
||||
void SetClearColorOverride(const Math::Color& clearColor);
|
||||
void ClearClearColorOverride();
|
||||
bool HasClearColorOverride() const { return m_hasClearColorOverride; }
|
||||
const Math::Color& GetClearColorOverride() const { return m_clearColorOverride; }
|
||||
|
||||
void SetAutoTransitionEnabled(bool enabled) { m_autoTransition = enabled; }
|
||||
bool IsAutoTransitionEnabled() const { return m_autoTransition; }
|
||||
|
||||
void SetColorStateBefore(RHI::ResourceStates state) { m_colorStateBefore = state; }
|
||||
RHI::ResourceStates GetColorStateBefore() const { return m_colorStateBefore; }
|
||||
|
||||
void SetColorStateAfter(RHI::ResourceStates state) { m_colorStateAfter = state; }
|
||||
RHI::ResourceStates GetColorStateAfter() const { return m_colorStateAfter; }
|
||||
|
||||
private:
|
||||
uint32_t m_width = 0;
|
||||
uint32_t m_height = 0;
|
||||
std::vector<RHI::RHIResourceView*> m_colorAttachments;
|
||||
RHI::RHIResourceView* m_depthAttachment = nullptr;
|
||||
bool m_hasClearColorOverride = false;
|
||||
Math::Color m_clearColorOverride = Math::Color::Black();
|
||||
bool m_autoTransition = true;
|
||||
RHI::ResourceStates m_colorStateBefore = RHI::ResourceStates::Present;
|
||||
RHI::ResourceStates m_colorStateAfter = RHI::ResourceStates::Present;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
36
engine/include/XCEngine/Rendering/SceneRenderer.h
Normal file
36
engine/include/XCEngine/Rendering/SceneRenderer.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/RenderPipeline.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
class CameraComponent;
|
||||
class Scene;
|
||||
} // namespace Components
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
class SceneRenderer {
|
||||
public:
|
||||
SceneRenderer();
|
||||
explicit SceneRenderer(std::unique_ptr<RenderPipeline> pipeline);
|
||||
~SceneRenderer();
|
||||
|
||||
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
|
||||
RenderPipeline* GetPipeline() const { return m_pipeline.get(); }
|
||||
|
||||
bool Render(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface);
|
||||
|
||||
private:
|
||||
RenderSceneExtractor m_sceneExtractor;
|
||||
std::unique_ptr<RenderPipeline> m_pipeline;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
24
engine/include/XCEngine/Rendering/VisibleRenderObject.h
Normal file
24
engine/include/XCEngine/Rendering/VisibleRenderObject.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Math/Matrix4.h>
|
||||
#include <XCEngine/Resources/Mesh/Mesh.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
class GameObject;
|
||||
class MeshFilterComponent;
|
||||
class MeshRendererComponent;
|
||||
} // namespace Components
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct VisibleRenderObject {
|
||||
Components::GameObject* gameObject = nullptr;
|
||||
Components::MeshFilterComponent* meshFilter = nullptr;
|
||||
Components::MeshRendererComponent* meshRenderer = nullptr;
|
||||
Resources::Mesh* mesh = nullptr;
|
||||
Math::Matrix4x4 localToWorld = Math::Matrix4x4::Identity();
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user