Graphics: Add support for draw call data (texture overlay)

This commit is contained in:
Jérôme Leclercq 2021-09-05 18:26:12 +02:00
parent 26e5a41dce
commit abdcd63058
16 changed files with 160 additions and 18 deletions

View File

@ -29,12 +29,14 @@ namespace Nz
using Dependencies = TypeList<Renderer>; using Dependencies = TypeList<Renderer>;
struct Config; struct Config;
struct DefaultTextures;
Graphics(Config config); Graphics(Config config);
~Graphics(); ~Graphics();
inline const std::shared_ptr<RenderPipeline>& GetBlitPipeline() const; inline const std::shared_ptr<RenderPipeline>& GetBlitPipeline() const;
inline const std::shared_ptr<RenderPipelineLayout>& GetBlitPipelineLayout() const; inline const std::shared_ptr<RenderPipelineLayout>& GetBlitPipelineLayout() const;
inline const DefaultTextures& GetDefaultTextures() const;
inline const std::shared_ptr<AbstractBuffer>& GetFullscreenVertexBuffer() const; inline const std::shared_ptr<AbstractBuffer>& GetFullscreenVertexBuffer() const;
inline const std::shared_ptr<VertexDeclaration>& GetFullscreenVertexDeclaration() const; inline const std::shared_ptr<VertexDeclaration>& GetFullscreenVertexDeclaration() const;
inline MaterialPassRegistry& GetMaterialPassRegistry(); inline MaterialPassRegistry& GetMaterialPassRegistry();
@ -51,15 +53,23 @@ namespace Nz
bool useDedicatedRenderDevice = true; bool useDedicatedRenderDevice = true;
}; };
static constexpr UInt32 MaterialBindingSet = 2; struct DefaultTextures
{
std::shared_ptr<Texture> whiteTexture2d;
};
static constexpr UInt32 DrawDataBindingSet = 2;
static constexpr UInt32 MaterialBindingSet = 3;
static constexpr UInt32 ViewerBindingSet = 0; static constexpr UInt32 ViewerBindingSet = 0;
static constexpr UInt32 WorldBindingSet = 1; static constexpr UInt32 WorldBindingSet = 1;
static void FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = DrawDataBindingSet);
static void FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = ViewerBindingSet); static void FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = ViewerBindingSet);
static void FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = WorldBindingSet); static void FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = WorldBindingSet);
private: private:
void BuildBlitPipeline(); void BuildBlitPipeline();
void BuildDefaultTextures();
void BuildFullscreenVertexBuffer(); void BuildFullscreenVertexBuffer();
void RegisterMaterialPasses(); void RegisterMaterialPasses();
void SelectDepthStencilFormats(); void SelectDepthStencilFormats();
@ -72,6 +82,7 @@ namespace Nz
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout; std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
std::shared_ptr<RenderPipelineLayout> m_referencePipelineLayout; std::shared_ptr<RenderPipelineLayout> m_referencePipelineLayout;
std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration; std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration;
DefaultTextures m_defaultTextures;
MaterialPassRegistry m_materialPassRegistry; MaterialPassRegistry m_materialPassRegistry;
PixelFormat m_preferredDepthStencilFormat; PixelFormat m_preferredDepthStencilFormat;

View File

@ -17,6 +17,11 @@ namespace Nz
return m_blitPipelineLayout; return m_blitPipelineLayout;
} }
inline auto Graphics::GetDefaultTextures() const -> const DefaultTextures&
{
return m_defaultTextures;
}
inline const std::shared_ptr<AbstractBuffer>& Graphics::GetFullscreenVertexBuffer() const inline const std::shared_ptr<AbstractBuffer>& Graphics::GetFullscreenVertexBuffer() const
{ {
return m_fullscreenVertexBuffer; return m_fullscreenVertexBuffer;

View File

@ -18,6 +18,7 @@ namespace Nz
m_data(std::move(data)) m_data(std::move(data))
{ {
RenderPipelineLayoutInfo info; RenderPipelineLayoutInfo info;
Graphics::FillDrawDataPipelineLayout(info);
Graphics::FillViewerPipelineLayout(info); Graphics::FillViewerPipelineLayout(info);
Graphics::FillWorldPipelineLayout(info); Graphics::FillWorldPipelineLayout(info);

View File

@ -23,7 +23,7 @@ namespace Nz
class RenderSpriteChain : public RenderElement class RenderSpriteChain : public RenderElement
{ {
public: public:
inline RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const ShaderBinding& instanceBinding); inline RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const ShaderBinding& instanceBinding);
~RenderSpriteChain() = default; ~RenderSpriteChain() = default;
inline UInt64 ComputeSortingScore(const RenderQueueRegistry& registry) const override; inline UInt64 ComputeSortingScore(const RenderQueueRegistry& registry) const override;
@ -33,6 +33,7 @@ namespace Nz
inline const RenderPipeline* GetRenderPipeline() const; inline const RenderPipeline* GetRenderPipeline() const;
inline std::size_t GetSpriteCount() const; inline std::size_t GetSpriteCount() const;
inline const void* GetSpriteData() const; inline const void* GetSpriteData() const;
inline const Texture* GetTextureOverlay() const;
inline const VertexDeclaration* GetVertexDeclaration() const; inline const VertexDeclaration* GetVertexDeclaration() const;
inline void Register(RenderQueueRegistry& registry) const override; inline void Register(RenderQueueRegistry& registry) const override;
@ -40,6 +41,7 @@ namespace Nz
private: private:
std::shared_ptr<RenderPipeline> m_renderPipeline; std::shared_ptr<RenderPipeline> m_renderPipeline;
std::shared_ptr<VertexDeclaration> m_vertexDeclaration; std::shared_ptr<VertexDeclaration> m_vertexDeclaration;
std::shared_ptr<Texture> m_textureOverlay;
std::size_t m_spriteCount; std::size_t m_spriteCount;
const void* m_spriteData; const void* m_spriteData;
const ShaderBinding& m_instanceBinding; const ShaderBinding& m_instanceBinding;

View File

@ -7,10 +7,11 @@
namespace Nz namespace Nz
{ {
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const ShaderBinding& instanceBinding) : inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const ShaderBinding& instanceBinding) :
RenderElement(BasicRenderElement::SpriteChain), RenderElement(BasicRenderElement::SpriteChain),
m_renderPipeline(std::move(renderPipeline)), m_renderPipeline(std::move(renderPipeline)),
m_vertexDeclaration(std::move(vertexDeclaration)), m_vertexDeclaration(std::move(vertexDeclaration)),
m_textureOverlay(std::move(textureOverlay)),
m_spriteCount(spriteCount), m_spriteCount(spriteCount),
m_spriteData(spriteData), m_spriteData(spriteData),
m_instanceBinding(instanceBinding), m_instanceBinding(instanceBinding),
@ -64,6 +65,11 @@ namespace Nz
return m_spriteData; return m_spriteData;
} }
inline const Texture* RenderSpriteChain::GetTextureOverlay() const
{
return m_textureOverlay.get();
}
inline const VertexDeclaration* RenderSpriteChain::GetVertexDeclaration() const inline const VertexDeclaration* RenderSpriteChain::GetVertexDeclaration() const
{ {
return m_vertexDeclaration.get(); return m_vertexDeclaration.get();

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp> #include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Renderer/UploadPool.hpp> #include <Nazara/Renderer/UploadPool.hpp>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
@ -53,6 +54,7 @@ namespace Nz
{ {
const AbstractBuffer* vertexBuffer; const AbstractBuffer* vertexBuffer;
const RenderPipeline* renderPipeline; const RenderPipeline* renderPipeline;
const ShaderBinding* drawDataBinding;
const ShaderBinding* instanceBinding; const ShaderBinding* instanceBinding;
const ShaderBinding* materialBinding; const ShaderBinding* materialBinding;
std::size_t firstIndex; std::size_t firstIndex;
@ -68,6 +70,7 @@ namespace Nz
std::unordered_map<const RenderSpriteChain*, DrawCallIndices> drawCallPerElement; std::unordered_map<const RenderSpriteChain*, DrawCallIndices> drawCallPerElement;
std::vector<DrawCall> drawCalls; std::vector<DrawCall> drawCalls;
std::vector<std::shared_ptr<AbstractBuffer>> vertexBuffers; std::vector<std::shared_ptr<AbstractBuffer>> vertexBuffers;
std::vector<ShaderBindingPtr> shaderBindings;
}; };
} }

View File

@ -9,17 +9,21 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp> #include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
namespace Nz namespace Nz
{ {
class NAZARA_GRAPHICS_API SubmeshRenderer : public ElementRenderer class NAZARA_GRAPHICS_API SubmeshRenderer : public ElementRenderer
{ {
public: public:
SubmeshRenderer() = default; SubmeshRenderer();
~SubmeshRenderer() = default; ~SubmeshRenderer() = default;
std::unique_ptr<ElementRendererData> InstanciateData(); std::unique_ptr<ElementRendererData> InstanciateData();
void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override; void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
private:
ShaderBindingPtr m_renderDataBinding;
}; };
} }

View File

@ -42,8 +42,8 @@ namespace Nz
struct TextureBinding struct TextureBinding
{ {
Texture* texture; const Texture* texture;
TextureSampler* sampler; const TextureSampler* sampler;
}; };
struct UniformBufferBinding struct UniformBufferBinding

View File

@ -66,11 +66,13 @@ namespace Nz
MaterialPipeline::Initialize(); MaterialPipeline::Initialize();
RenderPipelineLayoutInfo referenceLayoutInfo; RenderPipelineLayoutInfo referenceLayoutInfo;
FillDrawDataPipelineLayout(referenceLayoutInfo);
FillViewerPipelineLayout(referenceLayoutInfo); FillViewerPipelineLayout(referenceLayoutInfo);
FillWorldPipelineLayout(referenceLayoutInfo); FillWorldPipelineLayout(referenceLayoutInfo);
m_referencePipelineLayout = m_renderDevice->InstantiateRenderPipelineLayout(std::move(referenceLayoutInfo)); m_referencePipelineLayout = m_renderDevice->InstantiateRenderPipelineLayout(std::move(referenceLayoutInfo));
BuildDefaultTextures();
BuildFullscreenVertexBuffer(); BuildFullscreenVertexBuffer();
BuildBlitPipeline(); BuildBlitPipeline();
RegisterMaterialPasses(); RegisterMaterialPasses();
@ -86,10 +88,22 @@ namespace Nz
m_fullscreenVertexDeclaration.reset(); m_fullscreenVertexDeclaration.reset();
m_blitPipeline.reset(); m_blitPipeline.reset();
m_blitPipelineLayout.reset(); m_blitPipelineLayout.reset();
m_defaultTextures.whiteTexture2d.reset();
}
void Graphics::FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
{
// TextureOverlay
layoutInfo.bindings.push_back({
set, 0,
ShaderBindingType::Texture,
ShaderStageType_All
});
} }
void Graphics::FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set) void Graphics::FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
{ {
// ViewerData
layoutInfo.bindings.push_back({ layoutInfo.bindings.push_back({
set, 0, set, 0,
ShaderBindingType::UniformBuffer, ShaderBindingType::UniformBuffer,
@ -99,6 +113,7 @@ namespace Nz
void Graphics::FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set) void Graphics::FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
{ {
// InstanceData
layoutInfo.bindings.push_back({ layoutInfo.bindings.push_back({
set, 0, set, 0,
ShaderBindingType::UniformBuffer, ShaderBindingType::UniformBuffer,
@ -138,6 +153,22 @@ namespace Nz
m_blitPipeline = m_renderDevice->InstantiateRenderPipeline(std::move(pipelineInfo)); m_blitPipeline = m_renderDevice->InstantiateRenderPipeline(std::move(pipelineInfo));
} }
void Graphics::BuildDefaultTextures()
{
// White texture 2D
{
Nz::TextureInfo texInfo;
texInfo.width = texInfo.height = texInfo.depth = texInfo.mipmapLevel = 1;
texInfo.pixelFormat = PixelFormat::BGRA8;
texInfo.type = ImageType::E2D;
std::array<UInt8, 4> texData = { 0xFF, 0xFF, 0xFF, 0xFF };
m_defaultTextures.whiteTexture2d = m_renderDevice->InstantiateTexture(texInfo);
m_defaultTextures.whiteTexture2d->Update(texData.data());
}
}
void Graphics::BuildFullscreenVertexBuffer() void Graphics::BuildFullscreenVertexBuffer()
{ {
m_fullscreenVertexDeclaration = VertexDeclaration::Get(VertexLayout::XY_UV); m_fullscreenVertexDeclaration = VertexDeclaration::Get(VertexLayout::XY_UV);

View File

@ -8,7 +8,7 @@ option ColorLocation: i32 = -1;
option UvLocation: i32 = -1; option UvLocation: i32 = -1;
const HasVertexColor = (ColorLocation >= 0); const HasVertexColor = (ColorLocation >= 0);
const HasUV = (UvLocation >= 0) && (HasDiffuseTexture || HasAlphaTexture); const HasUV = (UvLocation >= 0);
[layout(std140)] [layout(std140)]
struct BasicSettings struct BasicSettings
@ -42,9 +42,10 @@ external
{ {
[set(0), binding(0)] viewerData: uniform<ViewerData>, [set(0), binding(0)] viewerData: uniform<ViewerData>,
[set(1), binding(0)] instanceData: uniform<InstanceData>, [set(1), binding(0)] instanceData: uniform<InstanceData>,
[set(2), binding(0)] settings: uniform<BasicSettings>, [set(2), binding(0)] TextureOverlay: sampler2D<f32>,
[set(2), binding(2)] MaterialAlphaMap: sampler2D<f32>, [set(3), binding(0)] settings: uniform<BasicSettings>,
[set(2), binding(1)] MaterialDiffuseMap: sampler2D<f32> [set(3), binding(2)] MaterialAlphaMap: sampler2D<f32>,
[set(3), binding(1)] MaterialDiffuseMap: sampler2D<f32>
} }
// Fragment stage // Fragment stage
@ -64,6 +65,10 @@ fn main(input: FragIn) -> FragOut
{ {
let diffuseColor = settings.DiffuseColor; let diffuseColor = settings.DiffuseColor;
const if (HasUV)
//TODO: diffuseColor *= TextureOverlay.Sample(input.uv);
diffuseColor = diffuseColor * TextureOverlay.Sample(input.uv);
const if (HasVertexColor) const if (HasVertexColor)
//TODO: diffuseColor *= input.color; //TODO: diffuseColor *= input.color;
diffuseColor = diffuseColor * input.color; diffuseColor = diffuseColor * input.color;

View File

@ -36,9 +36,10 @@ external
{ {
[set(0), binding(0)] viewerData: uniform<ViewerData>, [set(0), binding(0)] viewerData: uniform<ViewerData>,
[set(1), binding(0)] instanceData: uniform<InstanceData>, [set(1), binding(0)] instanceData: uniform<InstanceData>,
[set(2), binding(0)] settings: uniform<BasicSettings>, [set(2), binding(0)] TextureOverlay: sampler2D<f32>,
[set(2), binding(2)] MaterialAlphaMap: sampler2D<f32>, [set(3), binding(0)] settings: uniform<BasicSettings>,
[set(2), binding(1)] MaterialDiffuseMap: sampler2D<f32> [set(3), binding(2)] MaterialAlphaMap: sampler2D<f32>,
[set(3), binding(1)] MaterialDiffuseMap: sampler2D<f32>
} }
// Fragment stage // Fragment stage
@ -51,6 +52,11 @@ struct FragIn
fn main(input: FragIn) fn main(input: FragIn)
{ {
let alpha = settings.DiffuseColor.a; let alpha = settings.DiffuseColor.a;
const if (HasUV)
//TODO: diffuseColor *= TextureOverlay.Sample(input.uv);
alpha = alpha * TextureOverlay.Sample(input.uv).a;
const if (HasDiffuseTexture) const if (HasDiffuseTexture)
// TODO: alpha *= MaterialDiffuseMap.Sample(input.uv).a; // TODO: alpha *= MaterialDiffuseMap.Sample(input.uv).a;
alpha = alpha * MaterialDiffuseMap.Sample(input.uv).a; alpha = alpha * MaterialDiffuseMap.Sample(input.uv).a;

View File

@ -38,7 +38,9 @@ namespace Nz
}; };
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(vertexBufferData); const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(vertexBufferData);
elements.emplace_back(std::make_unique<RenderSpriteChain>(0, renderPipeline, vertexDeclaration, 1, m_vertices.data(), materialPass->GetShaderBinding(), worldInstance.GetShaderBinding())); const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTexture2d;
elements.emplace_back(std::make_unique<RenderSpriteChain>(0, renderPipeline, vertexDeclaration, whiteTexture, 1, m_vertices.data(), materialPass->GetShaderBinding(), worldInstance.GetShaderBinding()));
} }
const std::shared_ptr<Material>& Sprite::GetMaterial(std::size_t i) const const std::shared_ptr<Material>& Sprite::GetMaterial(std::size_t i) const

View File

@ -52,6 +52,8 @@ namespace Nz
void SpriteChainRenderer::Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount) void SpriteChainRenderer::Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{ {
Graphics* graphics = Graphics::Instance();
auto& data = static_cast<SpriteChainRendererData&>(rendererData); auto& data = static_cast<SpriteChainRendererData&>(rendererData);
std::size_t firstQuadIndex = 0; std::size_t firstQuadIndex = 0;
@ -61,14 +63,23 @@ namespace Nz
const VertexDeclaration* currentVertexDeclaration = nullptr; const VertexDeclaration* currentVertexDeclaration = nullptr;
AbstractBuffer* currentVertexBuffer = nullptr; AbstractBuffer* currentVertexBuffer = nullptr;
const RenderPipeline* currentPipeline = nullptr; const RenderPipeline* currentPipeline = nullptr;
const ShaderBinding* currentDrawDataBinding = nullptr;
const ShaderBinding* currentInstanceBinding = nullptr; const ShaderBinding* currentInstanceBinding = nullptr;
const ShaderBinding* currentMaterialBinding = nullptr; const ShaderBinding* currentMaterialBinding = nullptr;
const Texture* currentTextureOverlay = nullptr;
auto FlushDrawCall = [&]() auto FlushDrawCall = [&]()
{ {
currentDrawCall = nullptr; currentDrawCall = nullptr;
}; };
auto FlushDrawData = [&]()
{
FlushDrawCall();
currentDrawDataBinding = nullptr;
};
auto Flush = [&]() auto Flush = [&]()
{ {
// changing vertex buffer always mean we have to switch draw calls // changing vertex buffer always mean we have to switch draw calls
@ -85,6 +96,7 @@ namespace Nz
}; };
std::size_t oldDrawCallCount = data.drawCalls.size(); std::size_t oldDrawCallCount = data.drawCalls.size();
const auto& defaultSampler = graphics->GetSamplerCache().Get({});
for (std::size_t i = 0; i < elementCount; ++i) for (std::size_t i = 0; i < elementCount; ++i)
{ {
@ -122,6 +134,12 @@ namespace Nz
currentInstanceBinding = &spriteChain.GetInstanceBinding(); currentInstanceBinding = &spriteChain.GetInstanceBinding();
} }
if (currentTextureOverlay != spriteChain.GetTextureOverlay())
{
FlushDrawData();
currentTextureOverlay = spriteChain.GetTextureOverlay();
}
std::size_t remainingQuads = spriteChain.GetSpriteCount(); std::size_t remainingQuads = spriteChain.GetSpriteCount();
while (remainingQuads > 0) while (remainingQuads > 0)
{ {
@ -149,11 +167,29 @@ namespace Nz
data.vertexBuffers.emplace_back(std::move(vertexBuffer)); data.vertexBuffers.emplace_back(std::move(vertexBuffer));
} }
if (!currentDrawDataBinding)
{
ShaderBindingPtr drawDataBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::DrawDataBindingSet);
drawDataBinding->Update({
{
0,
ShaderBinding::TextureBinding {
currentTextureOverlay, defaultSampler.get()
}
}
});
currentDrawDataBinding = drawDataBinding.get();
data.shaderBindings.emplace_back(std::move(drawDataBinding));
}
if (!currentDrawCall) if (!currentDrawCall)
{ {
data.drawCalls.push_back(SpriteChainRendererData::DrawCall{ data.drawCalls.push_back(SpriteChainRendererData::DrawCall{
currentVertexBuffer, currentVertexBuffer,
currentPipeline, currentPipeline,
currentDrawDataBinding,
currentInstanceBinding, currentInstanceBinding,
currentMaterialBinding, currentMaterialBinding,
6 * firstQuadIndex, 6 * firstQuadIndex,
@ -216,6 +252,7 @@ namespace Nz
const AbstractBuffer* currentVertexBuffer = nullptr; const AbstractBuffer* currentVertexBuffer = nullptr;
const RenderPipeline* currentPipeline = nullptr; const RenderPipeline* currentPipeline = nullptr;
const ShaderBinding* currentDrawDataBinding = nullptr;
const ShaderBinding* currentInstanceBinding = nullptr; const ShaderBinding* currentInstanceBinding = nullptr;
const ShaderBinding* currentMaterialBinding = nullptr; const ShaderBinding* currentMaterialBinding = nullptr;
@ -241,6 +278,12 @@ namespace Nz
currentPipeline = drawCall.renderPipeline; currentPipeline = drawCall.renderPipeline;
} }
if (currentDrawDataBinding != drawCall.drawDataBinding)
{
commandBuffer.BindShaderBinding(Graphics::DrawDataBindingSet, *drawCall.drawDataBinding);
currentDrawDataBinding = drawCall.drawDataBinding;
}
if (currentMaterialBinding != drawCall.materialBinding) if (currentMaterialBinding != drawCall.materialBinding)
{ {
commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, *drawCall.materialBinding); commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, *drawCall.materialBinding);
@ -270,6 +313,10 @@ namespace Nz
} }
data.vertexBuffers.clear(); data.vertexBuffers.clear();
for (auto& shaderBinding : data.shaderBindings)
currentFrame.PushForRelease(std::move(shaderBinding));
data.shaderBindings.clear();
data.drawCalls.clear(); data.drawCalls.clear();
} }
} }

View File

@ -10,6 +10,23 @@
namespace Nz namespace Nz
{ {
SubmeshRenderer::SubmeshRenderer()
{
Graphics* graphics = Graphics::Instance();
const auto& whiteTexture = graphics->GetDefaultTextures().whiteTexture2d;
const auto& defaultSampler = graphics->GetSamplerCache().Get({});
m_renderDataBinding = graphics->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::DrawDataBindingSet);
m_renderDataBinding->Update({
{
0,
ShaderBinding::TextureBinding {
whiteTexture.get(), defaultSampler.get()
}
}
});
}
std::unique_ptr<ElementRendererData> SubmeshRenderer::InstanciateData() std::unique_ptr<ElementRendererData> SubmeshRenderer::InstanciateData()
{ {
return {}; return {};
@ -22,6 +39,8 @@ namespace Nz
const RenderPipeline* currentPipeline = nullptr; const RenderPipeline* currentPipeline = nullptr;
const ShaderBinding* currentMaterialBinding = nullptr; const ShaderBinding* currentMaterialBinding = nullptr;
commandBuffer.BindShaderBinding(Graphics::DrawDataBindingSet, *m_renderDataBinding);
for (std::size_t i = 0; i < elementCount; ++i) for (std::size_t i = 0; i < elementCount; ++i)
{ {
assert(elements[i]->GetElementType() == UnderlyingCast(BasicRenderElement::Submesh)); assert(elements[i]->GetElementType() == UnderlyingCast(BasicRenderElement::Submesh));

View File

@ -68,11 +68,11 @@ namespace Nz
{ {
auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, binding.bindingIndex); auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, binding.bindingIndex);
if (OpenGLTexture* glTexture = static_cast<OpenGLTexture*>(arg.texture)) if (const OpenGLTexture* glTexture = static_cast<const OpenGLTexture*>(arg.texture))
{ {
textureDescriptor.texture = glTexture->GetTexture().GetObjectId(); textureDescriptor.texture = glTexture->GetTexture().GetObjectId();
if (OpenGLTextureSampler* glSampler = static_cast<OpenGLTextureSampler*>(arg.sampler)) if (const OpenGLTextureSampler* glSampler = static_cast<const OpenGLTextureSampler*>(arg.sampler))
textureDescriptor.sampler = glSampler->GetSampler(glTexture->GetLevelCount() > 1).GetObjectId(); textureDescriptor.sampler = glSampler->GetSampler(glTexture->GetLevelCount() > 1).GetObjectId();
else else
textureDescriptor.sampler = 0; textureDescriptor.sampler = 0;

View File

@ -34,8 +34,8 @@ namespace Nz
if constexpr (std::is_same_v<T, TextureBinding>) if constexpr (std::is_same_v<T, TextureBinding>)
{ {
VulkanTexture* vkTexture = static_cast<VulkanTexture*>(arg.texture); const VulkanTexture* vkTexture = static_cast<const VulkanTexture*>(arg.texture);
VulkanTextureSampler* vkSampler = static_cast<VulkanTextureSampler*>(arg.sampler); const VulkanTextureSampler* vkSampler = static_cast<const VulkanTextureSampler*>(arg.sampler);
VkDescriptorImageInfo& imageInfo = imageBinding.emplace_back(); VkDescriptorImageInfo& imageInfo = imageBinding.emplace_back();
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;