Graphics: Add Material and made use of passes (WIP)
This commit is contained in:
parent
f61deabe92
commit
b5045a2c59
|
|
@ -0,0 +1,53 @@
|
||||||
|
option HAS_DIFFUSE_TEXTURE: bool;
|
||||||
|
option HAS_ALPHA_TEXTURE: bool;
|
||||||
|
option ALPHA_TEST: bool;
|
||||||
|
|
||||||
|
const HasUV = HAS_DIFFUSE_TEXTURE || HAS_ALPHA_TEXTURE;
|
||||||
|
|
||||||
|
[layout(std140)]
|
||||||
|
struct InstanceData
|
||||||
|
{
|
||||||
|
worldMatrix: mat4<f32>,
|
||||||
|
invWorldMatrix: mat4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
[layout(std140)]
|
||||||
|
struct ViewerData
|
||||||
|
{
|
||||||
|
projectionMatrix: mat4<f32>,
|
||||||
|
invProjectionMatrix: mat4<f32>,
|
||||||
|
viewMatrix: mat4<f32>,
|
||||||
|
invViewMatrix: mat4<f32>,
|
||||||
|
viewProjMatrix: mat4<f32>,
|
||||||
|
invViewProjMatrix: mat4<f32>,
|
||||||
|
renderTargetSize: vec2<f32>,
|
||||||
|
invRenderTargetSize: vec2<f32>,
|
||||||
|
eyePosition: vec3<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
external
|
||||||
|
{
|
||||||
|
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
||||||
|
[set(1), binding(0)] instanceData: uniform<InstanceData>
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertex stage
|
||||||
|
struct VertIn
|
||||||
|
{
|
||||||
|
[location(0)] pos: vec3<f32>,
|
||||||
|
[location(1), cond(HasUV)] uv: vec2<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertOut
|
||||||
|
{
|
||||||
|
[builtin(position)] position: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(vert)]
|
||||||
|
fn main(input: VertIn) -> VertOut
|
||||||
|
{
|
||||||
|
let output: VertOut;
|
||||||
|
output.position = viewerData.viewProjMatrix * instanceData.worldMatrix * vec4<f32>(input.pos, 1.0);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
@ -44,8 +44,8 @@ namespace Nz
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BakedFrameGraph BuildFrameGraph();
|
BakedFrameGraph BuildFrameGraph();
|
||||||
void RegisterMaterial(MaterialPass* material);
|
void RegisterMaterialPass(MaterialPass* material);
|
||||||
void UnregisterMaterial(MaterialPass* material);
|
void UnregisterMaterialPass(MaterialPass* material);
|
||||||
|
|
||||||
struct MaterialData
|
struct MaterialData
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class CommandBufferBuilder;
|
class CommandBufferBuilder;
|
||||||
class MaterialPass;
|
class Material;
|
||||||
class WorldInstance;
|
class WorldInstance;
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API InstancedRenderable
|
class NAZARA_GRAPHICS_API InstancedRenderable
|
||||||
|
|
@ -26,15 +26,15 @@ namespace Nz
|
||||||
InstancedRenderable(InstancedRenderable&&) noexcept = default;
|
InstancedRenderable(InstancedRenderable&&) noexcept = default;
|
||||||
~InstancedRenderable();
|
~InstancedRenderable();
|
||||||
|
|
||||||
virtual void Draw(CommandBufferBuilder& commandBuffer) const = 0;
|
virtual void Draw(const std::string& pass, CommandBufferBuilder& commandBuffer) const = 0;
|
||||||
|
|
||||||
virtual const std::shared_ptr<MaterialPass>& GetMaterial(std::size_t i) const = 0;
|
virtual const std::shared_ptr<Material>& GetMaterial(std::size_t i) const = 0;
|
||||||
virtual std::size_t GetMaterialCount() const = 0;
|
virtual std::size_t GetMaterialCount() const = 0;
|
||||||
|
|
||||||
InstancedRenderable& operator=(const InstancedRenderable&) = delete;
|
InstancedRenderable& operator=(const InstancedRenderable&) = delete;
|
||||||
InstancedRenderable& operator=(InstancedRenderable&&) noexcept = default;
|
InstancedRenderable& operator=(InstancedRenderable&&) noexcept = default;
|
||||||
|
|
||||||
NazaraSignal(OnMaterialInvalidated, InstancedRenderable* /*instancedRenderable*/, std::size_t /*materialIndex*/, const std::shared_ptr<MaterialPass>& /*newMaterial*/);
|
NazaraSignal(OnMaterialInvalidated, InstancedRenderable* /*instancedRenderable*/, std::size_t /*materialIndex*/, const std::shared_ptr<Material>& /*newMaterial*/);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// 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_MATERIAL_HPP
|
||||||
|
#define NAZARA_MATERIAL_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class NAZARA_GRAPHICS_API Material : public Resource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Material();
|
||||||
|
~Material() = default;
|
||||||
|
|
||||||
|
void AddPass(std::string name, std::shared_ptr<MaterialPass> pass);
|
||||||
|
|
||||||
|
inline MaterialPass* GetPass(const std::string& name) const;
|
||||||
|
|
||||||
|
bool HasPass(const std::string& name) const;
|
||||||
|
|
||||||
|
void RemovePass(const std::string& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<MaterialPass>> m_passes;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Material.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_MATERIAL_HPP
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
inline MaterialPass* Material::GetPass(const std::string& name) const
|
||||||
|
{
|
||||||
|
auto it = m_passes.find(name);
|
||||||
|
if (it == m_passes.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/DebugOff.hpp>
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class GraphicalMesh;
|
class GraphicalMesh;
|
||||||
class MaterialPass;
|
class Material;
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API Model : public InstancedRenderable
|
class NAZARA_GRAPHICS_API Model : public InstancedRenderable
|
||||||
{
|
{
|
||||||
|
|
@ -28,17 +28,17 @@ namespace Nz
|
||||||
Model(Model&&) noexcept = default;
|
Model(Model&&) noexcept = default;
|
||||||
~Model() = default;
|
~Model() = default;
|
||||||
|
|
||||||
void Draw(CommandBufferBuilder& commandBuffer) const override;
|
void Draw(const std::string& pass, CommandBufferBuilder& commandBuffer) const override;
|
||||||
|
|
||||||
const std::shared_ptr<AbstractBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
|
const std::shared_ptr<AbstractBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
|
||||||
std::size_t GetIndexCount(std::size_t subMeshIndex) const;
|
std::size_t GetIndexCount(std::size_t subMeshIndex) const;
|
||||||
const std::shared_ptr<MaterialPass>& GetMaterial(std::size_t subMeshIndex) const override;
|
const std::shared_ptr<Material>& GetMaterial(std::size_t subMeshIndex) const override;
|
||||||
std::size_t GetMaterialCount() const override;
|
std::size_t GetMaterialCount() const override;
|
||||||
const std::shared_ptr<RenderPipeline>& GetRenderPipeline(std::size_t subMeshIndex) const;
|
const std::vector<RenderPipelineInfo::VertexBufferData>& GetVertexBufferData(std::size_t subMeshIndex) const;
|
||||||
const std::shared_ptr<AbstractBuffer>& GetVertexBuffer(std::size_t subMeshIndex) const;
|
const std::shared_ptr<AbstractBuffer>& GetVertexBuffer(std::size_t subMeshIndex) const;
|
||||||
inline std::size_t GetSubMeshCount() const;
|
inline std::size_t GetSubMeshCount() const;
|
||||||
|
|
||||||
inline void SetMaterial(std::size_t subMeshIndex, std::shared_ptr<MaterialPass> material);
|
inline void SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material);
|
||||||
|
|
||||||
Model& operator=(const Model&) = delete;
|
Model& operator=(const Model&) = delete;
|
||||||
Model& operator=(Model&&) noexcept = default;
|
Model& operator=(Model&&) noexcept = default;
|
||||||
|
|
@ -46,7 +46,7 @@ namespace Nz
|
||||||
private:
|
private:
|
||||||
struct SubMeshData
|
struct SubMeshData
|
||||||
{
|
{
|
||||||
std::shared_ptr<MaterialPass> material;
|
std::shared_ptr<Material> material;
|
||||||
std::vector<RenderPipelineInfo::VertexBufferData> vertexBufferData;
|
std::vector<RenderPipelineInfo::VertexBufferData> vertexBufferData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace Nz
|
||||||
return m_subMeshes.size();
|
return m_subMeshes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Model::SetMaterial(std::size_t subMeshIndex, std::shared_ptr<MaterialPass> material)
|
inline void Model::SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material)
|
||||||
{
|
{
|
||||||
assert(subMeshIndex < m_subMeshes.size());
|
assert(subMeshIndex < m_subMeshes.size());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Nz
|
||||||
FaceFilling faceFilling = FaceFilling::Fill;
|
FaceFilling faceFilling = FaceFilling::Fill;
|
||||||
FaceSide cullingSide = FaceSide::Back;
|
FaceSide cullingSide = FaceSide::Back;
|
||||||
FrontFace frontFace = FrontFace::CounterClockwise;
|
FrontFace frontFace = FrontFace::CounterClockwise;
|
||||||
RendererComparison depthCompare = RendererComparison::Less;
|
RendererComparison depthCompare = RendererComparison::LessOrEqual;
|
||||||
PrimitiveMode primitiveMode = PrimitiveMode::TriangleList;
|
PrimitiveMode primitiveMode = PrimitiveMode::TriangleList;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||||
#include <Nazara/Graphics/FrameGraph.hpp>
|
#include <Nazara/Graphics/FrameGraph.hpp>
|
||||||
#include <Nazara/Graphics/Graphics.hpp>
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||||
|
|
@ -41,14 +42,26 @@ namespace Nz
|
||||||
if (auto it = renderableMap.find(instancedRenderable); it == renderableMap.end())
|
if (auto it = renderableMap.find(instancedRenderable); it == renderableMap.end())
|
||||||
{
|
{
|
||||||
auto& renderableData = renderableMap.emplace(instancedRenderable, RenderableData{}).first->second;
|
auto& renderableData = renderableMap.emplace(instancedRenderable, RenderableData{}).first->second;
|
||||||
renderableData.onMaterialInvalidated.Connect(instancedRenderable->OnMaterialInvalidated, [this](InstancedRenderable* instancedRenderable, std::size_t materialIndex, const std::shared_ptr<MaterialPass>& newMaterial)
|
renderableData.onMaterialInvalidated.Connect(instancedRenderable->OnMaterialInvalidated, [this](InstancedRenderable* instancedRenderable, std::size_t materialIndex, const std::shared_ptr<Material>& newMaterial)
|
||||||
{
|
{
|
||||||
if (newMaterial)
|
if (newMaterial)
|
||||||
RegisterMaterial(newMaterial.get());
|
{
|
||||||
|
if (MaterialPass* pass = newMaterial->GetPass("DepthPass"))
|
||||||
|
RegisterMaterialPass(pass);
|
||||||
|
|
||||||
|
if (MaterialPass* pass = newMaterial->GetPass("ForwardPass"))
|
||||||
|
RegisterMaterialPass(pass);
|
||||||
|
}
|
||||||
|
|
||||||
const auto& prevMaterial = instancedRenderable->GetMaterial(materialIndex);
|
const auto& prevMaterial = instancedRenderable->GetMaterial(materialIndex);
|
||||||
if (prevMaterial)
|
if (prevMaterial)
|
||||||
UnregisterMaterial(prevMaterial.get());
|
{
|
||||||
|
if (MaterialPass* pass = prevMaterial->GetPass("DepthPass"))
|
||||||
|
UnregisterMaterialPass(pass);
|
||||||
|
|
||||||
|
if (MaterialPass* pass = prevMaterial->GetPass("ForwardPass"))
|
||||||
|
UnregisterMaterialPass(pass);
|
||||||
|
}
|
||||||
|
|
||||||
m_rebuildForwardPass = true;
|
m_rebuildForwardPass = true;
|
||||||
});
|
});
|
||||||
|
|
@ -56,8 +69,14 @@ namespace Nz
|
||||||
std::size_t matCount = instancedRenderable->GetMaterialCount();
|
std::size_t matCount = instancedRenderable->GetMaterialCount();
|
||||||
for (std::size_t i = 0; i < matCount; ++i)
|
for (std::size_t i = 0; i < matCount; ++i)
|
||||||
{
|
{
|
||||||
if (MaterialPass* mat = instancedRenderable->GetMaterial(i).get())
|
if (Material* mat = instancedRenderable->GetMaterial(i).get())
|
||||||
RegisterMaterial(mat);
|
{
|
||||||
|
if (MaterialPass* pass = mat->GetPass("DepthPass"))
|
||||||
|
RegisterMaterialPass(pass);
|
||||||
|
|
||||||
|
if (MaterialPass* pass = mat->GetPass("ForwardPass"))
|
||||||
|
RegisterMaterialPass(pass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rebuildForwardPass = true;
|
m_rebuildForwardPass = true;
|
||||||
|
|
@ -77,7 +96,6 @@ namespace Nz
|
||||||
{
|
{
|
||||||
renderFrame.PushForRelease(std::move(m_bakedFrameGraph));
|
renderFrame.PushForRelease(std::move(m_bakedFrameGraph));
|
||||||
m_bakedFrameGraph = BuildFrameGraph();
|
m_bakedFrameGraph = BuildFrameGraph();
|
||||||
m_rebuildForwardPass = false; //< No need to rebuild forward pass twice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update UBOs and materials
|
// Update UBOs and materials
|
||||||
|
|
@ -111,8 +129,7 @@ namespace Nz
|
||||||
builder.EndDebugRegion();
|
builder.EndDebugRegion();
|
||||||
}, QueueType::Transfer);
|
}, QueueType::Transfer);
|
||||||
|
|
||||||
const Vector2ui& frameSize = renderFrame.GetSize();
|
if (m_bakedFrameGraph.Resize(renderFrame))
|
||||||
if (m_bakedFrameGraph.Resize(frameSize.x, frameSize.y))
|
|
||||||
{
|
{
|
||||||
const std::shared_ptr<TextureSampler>& sampler = graphics->GetSamplerCache().Get({});
|
const std::shared_ptr<TextureSampler>& sampler = graphics->GetSamplerCache().Get({});
|
||||||
for (auto&& [_, viewerData] : m_viewers)
|
for (auto&& [_, viewerData] : m_viewers)
|
||||||
|
|
@ -134,7 +151,10 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bakedFrameGraph.Execute(renderFrame);
|
m_bakedFrameGraph.Execute(renderFrame);
|
||||||
|
m_rebuildForwardPass = false;
|
||||||
|
m_rebuildFrameGraph = false;
|
||||||
|
|
||||||
|
const Vector2ui& frameSize = renderFrame.GetSize();
|
||||||
for (auto&& [viewer, viewerData] : m_viewers)
|
for (auto&& [viewer, viewerData] : m_viewers)
|
||||||
{
|
{
|
||||||
const RenderTarget& renderTarget = viewer->GetRenderTarget();
|
const RenderTarget& renderTarget = viewer->GetRenderTarget();
|
||||||
|
|
@ -192,8 +212,8 @@ namespace Nz
|
||||||
std::size_t matCount = instancedRenderable->GetMaterialCount();
|
std::size_t matCount = instancedRenderable->GetMaterialCount();
|
||||||
for (std::size_t i = 0; i < matCount; ++i)
|
for (std::size_t i = 0; i < matCount; ++i)
|
||||||
{
|
{
|
||||||
if (MaterialPass* mat = instancedRenderable->GetMaterial(i).get())
|
if (MaterialPass* pass = instancedRenderable->GetMaterial(i)->GetPass("ForwardPass"))
|
||||||
UnregisterMaterial(mat);
|
UnregisterMaterialPass(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rebuildForwardPass = true;
|
m_rebuildForwardPass = true;
|
||||||
|
|
@ -224,31 +244,25 @@ namespace Nz
|
||||||
|
|
||||||
for (auto&& [viewer, viewerData] : m_viewers)
|
for (auto&& [viewer, viewerData] : m_viewers)
|
||||||
{
|
{
|
||||||
FramePass& framePass = frameGraph.AddPass("Forward pass");
|
FramePass& depthPrepass = frameGraph.AddPass("Depth pre-pass");
|
||||||
|
depthPrepass.SetDepthStencilOutput(viewerData.depthStencilAttachment);
|
||||||
framePass.AddOutput(viewerData.colorAttachment);
|
depthPrepass.SetDepthStencilClear(1.f, 0);
|
||||||
framePass.SetDepthStencilOutput(viewerData.depthStencilAttachment);
|
|
||||||
|
depthPrepass.SetExecutionCallback([this]()
|
||||||
framePass.SetClearColor(0, Color::Black);
|
|
||||||
framePass.SetDepthStencilClear(1.f, 0);
|
|
||||||
|
|
||||||
framePass.SetExecutionCallback([this]()
|
|
||||||
{
|
{
|
||||||
if (m_rebuildForwardPass)
|
if (m_rebuildForwardPass)
|
||||||
{
|
|
||||||
m_rebuildForwardPass = false;
|
|
||||||
return FramePassExecution::UpdateAndExecute;
|
return FramePassExecution::UpdateAndExecute;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return FramePassExecution::Execute;
|
return FramePassExecution::Execute;
|
||||||
});
|
});
|
||||||
|
|
||||||
framePass.SetCommandCallback([this, viewer = viewer](CommandBufferBuilder& builder, const Recti& /*renderRect*/)
|
depthPrepass.SetCommandCallback([this, viewer = viewer](CommandBufferBuilder& builder, const Recti& /*renderRect*/)
|
||||||
{
|
{
|
||||||
Recti viewport = viewer->GetViewport();
|
Recti viewport = viewer->GetViewport();
|
||||||
|
|
||||||
builder.SetScissor(viewport);
|
builder.SetScissor(viewport);
|
||||||
builder.SetViewport(viewport);
|
builder.SetViewport(viewport);
|
||||||
|
|
||||||
builder.BindShaderBinding(Graphics::ViewerBindingSet, viewer->GetViewerInstance().GetShaderBinding());
|
builder.BindShaderBinding(Graphics::ViewerBindingSet, viewer->GetViewerInstance().GetShaderBinding());
|
||||||
|
|
||||||
for (const auto& [worldInstance, renderables] : m_renderables)
|
for (const auto& [worldInstance, renderables] : m_renderables)
|
||||||
|
|
@ -256,7 +270,41 @@ namespace Nz
|
||||||
builder.BindShaderBinding(Graphics::WorldBindingSet, worldInstance->GetShaderBinding());
|
builder.BindShaderBinding(Graphics::WorldBindingSet, worldInstance->GetShaderBinding());
|
||||||
|
|
||||||
for (const auto& [renderable, renderableData] : renderables)
|
for (const auto& [renderable, renderableData] : renderables)
|
||||||
renderable->Draw(builder);
|
renderable->Draw("DepthPass", builder);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FramePass& forwardPass = frameGraph.AddPass("Forward pass");
|
||||||
|
forwardPass.AddOutput(viewerData.colorAttachment);
|
||||||
|
forwardPass.SetDepthStencilInput(viewerData.depthStencilAttachment);
|
||||||
|
forwardPass.SetDepthStencilOutput(viewerData.depthStencilAttachment);
|
||||||
|
|
||||||
|
forwardPass.SetClearColor(0, Color::Black);
|
||||||
|
forwardPass.SetDepthStencilClear(1.f, 0);
|
||||||
|
|
||||||
|
forwardPass.SetExecutionCallback([this]()
|
||||||
|
{
|
||||||
|
if (m_rebuildForwardPass)
|
||||||
|
return FramePassExecution::UpdateAndExecute;
|
||||||
|
else
|
||||||
|
return FramePassExecution::Execute;
|
||||||
|
});
|
||||||
|
|
||||||
|
forwardPass.SetCommandCallback([this, viewer = viewer](CommandBufferBuilder& builder, const Recti& /*renderRect*/)
|
||||||
|
{
|
||||||
|
Recti viewport = viewer->GetViewport();
|
||||||
|
|
||||||
|
builder.SetScissor(viewport);
|
||||||
|
builder.SetViewport(viewport);
|
||||||
|
|
||||||
|
builder.BindShaderBinding(Graphics::ViewerBindingSet, viewer->GetViewerInstance().GetShaderBinding());
|
||||||
|
|
||||||
|
for (const auto& [worldInstance, renderables] : m_renderables)
|
||||||
|
{
|
||||||
|
builder.BindShaderBinding(Graphics::WorldBindingSet, worldInstance->GetShaderBinding());
|
||||||
|
|
||||||
|
for (const auto& [renderable, renderableData] : renderables)
|
||||||
|
renderable->Draw("ForwardPass", builder);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -268,7 +316,7 @@ namespace Nz
|
||||||
return frameGraph.Bake();
|
return frameGraph.Bake();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardFramePipeline::RegisterMaterial(MaterialPass* material)
|
void ForwardFramePipeline::RegisterMaterialPass(MaterialPass* material)
|
||||||
{
|
{
|
||||||
auto it = m_materials.find(material);
|
auto it = m_materials.find(material);
|
||||||
if (it == m_materials.end())
|
if (it == m_materials.end())
|
||||||
|
|
@ -285,7 +333,7 @@ namespace Nz
|
||||||
it->second.usedCount++;
|
it->second.usedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardFramePipeline::UnregisterMaterial(MaterialPass* material)
|
void ForwardFramePipeline::UnregisterMaterialPass(MaterialPass* material)
|
||||||
{
|
{
|
||||||
auto it = m_materials.find(material);
|
auto it = m_materials.find(material);
|
||||||
assert(it != m_materials.end());
|
assert(it != m_materials.end());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
Material::Material()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::AddPass(std::string name, std::shared_ptr<MaterialPass> pass)
|
||||||
|
{
|
||||||
|
if (HasPass(name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_passes.emplace(std::move(name), std::move(pass));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Material::HasPass(const std::string& name) const
|
||||||
|
{
|
||||||
|
return m_passes.find(name) != m_passes.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::RemovePass(const std::string& name)
|
||||||
|
{
|
||||||
|
m_passes.erase(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include <Nazara/Graphics/Model.hpp>
|
#include <Nazara/Graphics/Model.hpp>
|
||||||
#include <Nazara/Graphics/GraphicalMesh.hpp>
|
#include <Nazara/Graphics/GraphicalMesh.hpp>
|
||||||
#include <Nazara/Graphics/Graphics.hpp>
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||||
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
@ -29,16 +29,21 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::Draw(CommandBufferBuilder& commandBuffer) const
|
void Model::Draw(const std::string& pass, CommandBufferBuilder& commandBuffer) const
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < m_subMeshes.size(); ++i)
|
for (std::size_t i = 0; i < m_subMeshes.size(); ++i)
|
||||||
{
|
{
|
||||||
const auto& submeshData = m_subMeshes[i];
|
const auto& submeshData = m_subMeshes[i];
|
||||||
|
|
||||||
|
MaterialPass* materialPass = submeshData.material->GetPass(pass);
|
||||||
|
if (!materialPass)
|
||||||
|
continue;
|
||||||
|
|
||||||
const auto& indexBuffer = m_graphicalMesh->GetIndexBuffer(i);
|
const auto& indexBuffer = m_graphicalMesh->GetIndexBuffer(i);
|
||||||
const auto& vertexBuffer = m_graphicalMesh->GetVertexBuffer(i);
|
const auto& vertexBuffer = m_graphicalMesh->GetVertexBuffer(i);
|
||||||
const auto& renderPipeline = submeshData.material->GetPipeline()->GetRenderPipeline(submeshData.vertexBufferData);
|
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(submeshData.vertexBufferData);
|
||||||
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, submeshData.material->GetShaderBinding());
|
commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, materialPass->GetShaderBinding());
|
||||||
commandBuffer.BindIndexBuffer(indexBuffer.get());
|
commandBuffer.BindIndexBuffer(indexBuffer.get());
|
||||||
commandBuffer.BindVertexBuffer(0, vertexBuffer.get());
|
commandBuffer.BindVertexBuffer(0, vertexBuffer.get());
|
||||||
commandBuffer.BindPipeline(*renderPipeline);
|
commandBuffer.BindPipeline(*renderPipeline);
|
||||||
|
|
@ -57,7 +62,7 @@ namespace Nz
|
||||||
return m_graphicalMesh->GetIndexCount(subMeshIndex);
|
return m_graphicalMesh->GetIndexCount(subMeshIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<MaterialPass>& Model::GetMaterial(std::size_t subMeshIndex) const
|
const std::shared_ptr<Material>& Model::GetMaterial(std::size_t subMeshIndex) const
|
||||||
{
|
{
|
||||||
assert(subMeshIndex < m_subMeshes.size());
|
assert(subMeshIndex < m_subMeshes.size());
|
||||||
const auto& subMeshData = m_subMeshes[subMeshIndex];
|
const auto& subMeshData = m_subMeshes[subMeshIndex];
|
||||||
|
|
@ -69,11 +74,11 @@ namespace Nz
|
||||||
return m_subMeshes.size();
|
return m_subMeshes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<RenderPipeline>& Model::GetRenderPipeline(std::size_t subMeshIndex) const
|
const std::vector<RenderPipelineInfo::VertexBufferData>& Model::GetVertexBufferData(std::size_t subMeshIndex) const
|
||||||
{
|
{
|
||||||
assert(subMeshIndex < m_subMeshes.size());
|
assert(subMeshIndex < m_subMeshes.size());
|
||||||
const auto& subMeshData = m_subMeshes[subMeshIndex];
|
const auto& subMeshData = m_subMeshes[subMeshIndex];
|
||||||
return subMeshData.material->GetPipeline()->GetRenderPipeline(subMeshData.vertexBufferData);
|
return subMeshData.vertexBufferData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<AbstractBuffer>& Model::GetVertexBuffer(std::size_t subMeshIndex) const
|
const std::shared_ptr<AbstractBuffer>& Model::GetVertexBuffer(std::size_t subMeshIndex) const
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue