Merge branch 'master' into automatic-file-fix
This commit is contained in:
commit
a3d9aaf1fb
|
|
@ -15,7 +15,7 @@ struct ViewerData
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
||||||
[set(1), binding(0)] colorTexture: sampler2D<f32>,
|
[set(0), binding(1)] colorTexture: sampler2D<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FragIn
|
struct FragIn
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ struct ViewerData
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
||||||
[set(1), binding(0)] colorTexture: sampler2D<f32>,
|
[set(0), binding(1)] colorTexture: sampler2D<f32>,
|
||||||
[set(1), binding(1)] bloomTexture: sampler2D<f32>,
|
[set(0), binding(2)] bloomTexture: sampler2D<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FragIn
|
struct FragIn
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,12 @@ struct ViewerData
|
||||||
|
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
[binding(0)] settings: uniform<BasicSettings>,
|
||||||
[set(1), binding(0)] instanceData: uniform<InstanceData>,
|
[binding(1)] MaterialDiffuseMap: sampler2D<f32>,
|
||||||
[set(2), binding(0)] settings: uniform<BasicSettings>,
|
[binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
||||||
[set(2), binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
[binding(3)] TextureOverlay: sampler2D<f32>,
|
||||||
[set(2), binding(1)] MaterialDiffuseMap: sampler2D<f32>
|
[binding(4)] instanceData: uniform<InstanceData>,
|
||||||
|
[binding(5)] viewerData: uniform<ViewerData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InputData
|
struct InputData
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ struct ViewerData
|
||||||
|
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
[binding(0)] settings: uniform<BasicSettings>,
|
||||||
[set(1), binding(0)] instanceData: uniform<InstanceData>,
|
[binding(4)] instanceData: uniform<InstanceData>,
|
||||||
[set(2), binding(0)] settings: uniform<BasicSettings>,
|
[binding(5)] viewerData: uniform<ViewerData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InputData
|
struct InputData
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ struct ViewerData
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
||||||
[set(1), binding(0)] colorTexture: sampler2D<f32>,
|
[set(0), binding(1)] colorTexture: sampler2D<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FragIn
|
struct FragIn
|
||||||
|
|
|
||||||
|
|
@ -41,19 +41,14 @@ struct ViewerData
|
||||||
[set(0)]
|
[set(0)]
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[binding(0)] viewerData: uniform<ViewerData>
|
[binding(0)] viewerData: uniform<ViewerData>,
|
||||||
|
[binding(1)] colorTexture: sampler2D<f32>,
|
||||||
|
[binding(2)] normalTexture: sampler2D<f32>,
|
||||||
|
[binding(3)] positionTexture: sampler2D<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
[set(1)]
|
[set(1)]
|
||||||
external
|
external
|
||||||
{
|
|
||||||
[binding(0)] colorTexture: sampler2D<f32>,
|
|
||||||
[binding(1)] normalTexture: sampler2D<f32>,
|
|
||||||
[binding(2)] positionTexture: sampler2D<f32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
[set(2)]
|
|
||||||
external
|
|
||||||
{
|
{
|
||||||
[binding(0)] lightParameters: uniform<SpotLight>,
|
[binding(0)] lightParameters: uniform<SpotLight>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ struct ViewerData
|
||||||
|
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(1), binding(0)] skybox: samplerCube<f32>
|
[binding(0)] viewerData: uniform<ViewerData>,
|
||||||
|
[binding(1)] skybox: samplerCube<f32>
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VertOut
|
struct VertOut
|
||||||
|
|
@ -40,11 +41,6 @@ fn main(input: VertOut) -> FragOut
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
external
|
|
||||||
{
|
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VertIn
|
struct VertIn
|
||||||
{
|
{
|
||||||
[location(0)] position: vec3<f32>
|
[location(0)] position: vec3<f32>
|
||||||
|
|
|
||||||
|
|
@ -129,11 +129,11 @@ int main()
|
||||||
std::shared_ptr<Nz::GraphicalMesh> cubeMeshGfx = std::make_shared<Nz::GraphicalMesh>(*cubeMesh);
|
std::shared_ptr<Nz::GraphicalMesh> cubeMeshGfx = std::make_shared<Nz::GraphicalMesh>(*cubeMesh);
|
||||||
|
|
||||||
Nz::RenderPipelineLayoutInfo skyboxPipelineLayoutInfo;
|
Nz::RenderPipelineLayoutInfo skyboxPipelineLayoutInfo;
|
||||||
Nz::Graphics::FillViewerPipelineLayout(skyboxPipelineLayoutInfo);
|
Nz::Graphics::FillViewerPipelineLayout(skyboxPipelineLayoutInfo, 0);
|
||||||
|
|
||||||
auto& textureBinding = skyboxPipelineLayoutInfo.bindings.emplace_back();
|
auto& textureBinding = skyboxPipelineLayoutInfo.bindings.emplace_back();
|
||||||
textureBinding.setIndex = 1;
|
textureBinding.setIndex = 0;
|
||||||
textureBinding.bindingIndex = 0;
|
textureBinding.bindingIndex = 1;
|
||||||
textureBinding.shaderStageFlags = Nz::ShaderStageType::Fragment;
|
textureBinding.shaderStageFlags = Nz::ShaderStageType::Fragment;
|
||||||
textureBinding.type = Nz::ShaderBindingType::Texture;
|
textureBinding.type = Nz::ShaderBindingType::Texture;
|
||||||
|
|
||||||
|
|
@ -238,20 +238,20 @@ int main()
|
||||||
|
|
||||||
|
|
||||||
Nz::RenderPipelineLayoutInfo lightingPipelineLayoutInfo;
|
Nz::RenderPipelineLayoutInfo lightingPipelineLayoutInfo;
|
||||||
Nz::Graphics::FillViewerPipelineLayout(lightingPipelineLayoutInfo);
|
Nz::Graphics::FillViewerPipelineLayout(lightingPipelineLayoutInfo, 0);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 3; ++i)
|
for (unsigned int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
lightingPipelineLayoutInfo.bindings.push_back({
|
lightingPipelineLayoutInfo.bindings.push_back({
|
||||||
1,
|
0,
|
||||||
i,
|
i + 1,
|
||||||
Nz::ShaderBindingType::Texture,
|
Nz::ShaderBindingType::Texture,
|
||||||
Nz::ShaderStageType::Fragment,
|
Nz::ShaderStageType::Fragment,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
lightingPipelineLayoutInfo.bindings.push_back({
|
lightingPipelineLayoutInfo.bindings.push_back({
|
||||||
2,
|
1,
|
||||||
0,
|
0,
|
||||||
Nz::ShaderBindingType::UniformBuffer,
|
Nz::ShaderBindingType::UniformBuffer,
|
||||||
Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex,
|
Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex,
|
||||||
|
|
@ -334,10 +334,10 @@ int main()
|
||||||
// Bloom data
|
// Bloom data
|
||||||
|
|
||||||
Nz::RenderPipelineLayoutInfo bloomPipelineLayoutInfo;
|
Nz::RenderPipelineLayoutInfo bloomPipelineLayoutInfo;
|
||||||
Nz::Graphics::FillViewerPipelineLayout(bloomPipelineLayoutInfo);
|
Nz::Graphics::FillViewerPipelineLayout(bloomPipelineLayoutInfo, 0);
|
||||||
|
|
||||||
bloomPipelineLayoutInfo.bindings.push_back({
|
bloomPipelineLayoutInfo.bindings.push_back({
|
||||||
1, 0,
|
0, 1,
|
||||||
Nz::ShaderBindingType::Texture,
|
Nz::ShaderBindingType::Texture,
|
||||||
Nz::ShaderStageType::Fragment,
|
Nz::ShaderStageType::Fragment,
|
||||||
});
|
});
|
||||||
|
|
@ -362,16 +362,16 @@ int main()
|
||||||
|
|
||||||
|
|
||||||
Nz::RenderPipelineLayoutInfo bloomBlendPipelineLayoutInfo;
|
Nz::RenderPipelineLayoutInfo bloomBlendPipelineLayoutInfo;
|
||||||
Nz::Graphics::FillViewerPipelineLayout(bloomBlendPipelineLayoutInfo);
|
Nz::Graphics::FillViewerPipelineLayout(bloomBlendPipelineLayoutInfo, 0);
|
||||||
|
|
||||||
bloomBlendPipelineLayoutInfo.bindings.push_back({
|
bloomBlendPipelineLayoutInfo.bindings.push_back({
|
||||||
1, 0,
|
0, 1,
|
||||||
Nz::ShaderBindingType::Texture,
|
Nz::ShaderBindingType::Texture,
|
||||||
Nz::ShaderStageType::Fragment,
|
Nz::ShaderStageType::Fragment,
|
||||||
});
|
});
|
||||||
|
|
||||||
bloomBlendPipelineLayoutInfo.bindings.push_back({
|
bloomBlendPipelineLayoutInfo.bindings.push_back({
|
||||||
1, 1,
|
0, 2,
|
||||||
Nz::ShaderBindingType::Texture,
|
Nz::ShaderBindingType::Texture,
|
||||||
Nz::ShaderStageType::Fragment,
|
Nz::ShaderStageType::Fragment,
|
||||||
});
|
});
|
||||||
|
|
@ -519,10 +519,17 @@ int main()
|
||||||
|
|
||||||
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
|
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
|
||||||
|
|
||||||
std::shared_ptr<Nz::ShaderBinding> skyboxShaderBinding = skyboxPipelineLayout->AllocateShaderBinding(1);
|
std::shared_ptr<Nz::ShaderBinding> skyboxShaderBinding = skyboxPipelineLayout->AllocateShaderBinding(0);
|
||||||
skyboxShaderBinding->Update({
|
skyboxShaderBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerInstance.GetViewerBuffer().get(),
|
||||||
|
0, viewerInstance.GetViewerBuffer()->GetSize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
skyboxTexture.get(),
|
skyboxTexture.get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
|
|
@ -645,8 +652,6 @@ int main()
|
||||||
builder.SetScissor(renderArea);
|
builder.SetScissor(renderArea);
|
||||||
builder.SetViewport(renderArea);
|
builder.SetViewport(renderArea);
|
||||||
|
|
||||||
builder.BindShaderBinding(Nz::Graphics::ViewerBindingSet, viewerInstance.GetShaderBinding());
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Nz::RenderElement>> elements;
|
std::vector<std::unique_ptr<Nz::RenderElement>> elements;
|
||||||
spaceshipModel.BuildElement(forwardPassIndex, modelInstance1, elements);
|
spaceshipModel.BuildElement(forwardPassIndex, modelInstance1, elements);
|
||||||
spaceshipModel.BuildElement(forwardPassIndex, modelInstance2, elements);
|
spaceshipModel.BuildElement(forwardPassIndex, modelInstance2, elements);
|
||||||
|
|
@ -656,7 +661,10 @@ int main()
|
||||||
for (const auto& element : elements)
|
for (const auto& element : elements)
|
||||||
elementPointers.emplace_back(element.get());
|
elementPointers.emplace_back(element.get());
|
||||||
|
|
||||||
submeshRenderer.Render(*submeshRendererData, builder, elementPointers.data(), elementPointers.size());
|
Nz::RenderFrame dummy;
|
||||||
|
|
||||||
|
submeshRenderer.Prepare(viewerInstance, *submeshRendererData, dummy, elementPointers.data(), elementPointers.size());
|
||||||
|
submeshRenderer.Render(viewerInstance, *submeshRendererData, builder, elementPointers.data(), elementPointers.size());
|
||||||
});
|
});
|
||||||
|
|
||||||
Nz::FramePass& lightingPass = graph.AddPass("Lighting pass");
|
Nz::FramePass& lightingPass = graph.AddPass("Lighting pass");
|
||||||
|
|
@ -674,12 +682,11 @@ int main()
|
||||||
builder.BindIndexBuffer(*coneMeshGfx->GetIndexBuffer(0).get());
|
builder.BindIndexBuffer(*coneMeshGfx->GetIndexBuffer(0).get());
|
||||||
builder.BindVertexBuffer(0, *coneMeshGfx->GetVertexBuffer(0).get());
|
builder.BindVertexBuffer(0, *coneMeshGfx->GetVertexBuffer(0).get());
|
||||||
|
|
||||||
builder.BindShaderBinding(0, viewerInstance.GetShaderBinding());
|
builder.BindShaderBinding(0, *gbufferShaderBinding);
|
||||||
builder.BindShaderBinding(1, *gbufferShaderBinding);
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < spotLights.size(); ++i)
|
for (std::size_t i = 0; i < spotLights.size(); ++i)
|
||||||
{
|
{
|
||||||
builder.BindShaderBinding(2, *lightingShaderBindings[i]);
|
builder.BindShaderBinding(1, *lightingShaderBindings[i]);
|
||||||
|
|
||||||
builder.BindPipeline(*stencilPipeline);
|
builder.BindPipeline(*stencilPipeline);
|
||||||
builder.DrawIndexed(coneMeshGfx->GetIndexCount(0));
|
builder.DrawIndexed(coneMeshGfx->GetIndexCount(0));
|
||||||
|
|
@ -702,14 +709,13 @@ int main()
|
||||||
builder.SetScissor(renderArea);
|
builder.SetScissor(renderArea);
|
||||||
builder.SetViewport(renderArea);
|
builder.SetViewport(renderArea);
|
||||||
|
|
||||||
builder.BindShaderBinding(0, viewerInstance.GetShaderBinding());
|
builder.BindShaderBinding(0, *skyboxShaderBinding);
|
||||||
builder.BindShaderBinding(1, *skyboxShaderBinding);
|
|
||||||
|
|
||||||
builder.BindIndexBuffer(*cubeMeshGfx->GetIndexBuffer(0));
|
builder.BindIndexBuffer(*cubeMeshGfx->GetIndexBuffer(0));
|
||||||
builder.BindVertexBuffer(0, *cubeMeshGfx->GetVertexBuffer(0));
|
builder.BindVertexBuffer(0, *cubeMeshGfx->GetVertexBuffer(0));
|
||||||
builder.BindPipeline(*skyboxPipeline);
|
builder.BindPipeline(*skyboxPipeline);
|
||||||
|
|
||||||
builder.DrawIndexed(static_cast<Nz::UInt32>(cubeMeshGfx->GetIndexCount(0)));
|
builder.DrawIndexed(Nz::SafeCast<Nz::UInt32>(cubeMeshGfx->GetIndexCount(0)));
|
||||||
});
|
});
|
||||||
forwardPass.SetExecutionCallback([&]
|
forwardPass.SetExecutionCallback([&]
|
||||||
{
|
{
|
||||||
|
|
@ -727,8 +733,7 @@ int main()
|
||||||
builder.SetScissor(renderArea);
|
builder.SetScissor(renderArea);
|
||||||
builder.SetViewport(renderArea);
|
builder.SetViewport(renderArea);
|
||||||
|
|
||||||
builder.BindShaderBinding(0, viewerInstance.GetShaderBinding());
|
builder.BindShaderBinding(0, *bloomBrightShaderBinding);
|
||||||
builder.BindShaderBinding(1, *bloomBrightShaderBinding);
|
|
||||||
|
|
||||||
builder.BindPipeline(*bloomBrightPipeline);
|
builder.BindPipeline(*bloomBrightPipeline);
|
||||||
builder.BindVertexBuffer(0, *fullscreenVertexBuffer);
|
builder.BindVertexBuffer(0, *fullscreenVertexBuffer);
|
||||||
|
|
@ -749,8 +754,7 @@ int main()
|
||||||
builder.SetScissor(renderArea);
|
builder.SetScissor(renderArea);
|
||||||
builder.SetViewport(renderArea);
|
builder.SetViewport(renderArea);
|
||||||
|
|
||||||
builder.BindShaderBinding(0, viewerInstance.GetShaderBinding());
|
builder.BindShaderBinding(0, *gaussianBlurShaderBinding);
|
||||||
builder.BindShaderBinding(1, *gaussianBlurShaderBinding);
|
|
||||||
builder.BindPipeline(*gaussianBlurPipeline);
|
builder.BindPipeline(*gaussianBlurPipeline);
|
||||||
builder.BindVertexBuffer(0, *fullscreenVertexBuffer);
|
builder.BindVertexBuffer(0, *fullscreenVertexBuffer);
|
||||||
|
|
||||||
|
|
@ -770,8 +774,7 @@ int main()
|
||||||
builder.SetScissor(renderArea);
|
builder.SetScissor(renderArea);
|
||||||
builder.SetViewport(renderArea);
|
builder.SetViewport(renderArea);
|
||||||
|
|
||||||
builder.BindShaderBinding(0, viewerInstance.GetShaderBinding());
|
builder.BindShaderBinding(0, *bloomBlendShaderBinding);
|
||||||
builder.BindShaderBinding(1, *bloomBlendShaderBinding);
|
|
||||||
builder.BindPipeline(*bloomBlendPipeline);
|
builder.BindPipeline(*bloomBlendPipeline);
|
||||||
builder.BindVertexBuffer(0, *fullscreenVertexBuffer);
|
builder.BindVertexBuffer(0, *fullscreenVertexBuffer);
|
||||||
|
|
||||||
|
|
@ -936,24 +939,31 @@ int main()
|
||||||
{
|
{
|
||||||
frame.PushForRelease(std::move(gbufferShaderBinding));
|
frame.PushForRelease(std::move(gbufferShaderBinding));
|
||||||
|
|
||||||
gbufferShaderBinding = lightingPipelineInfo.pipelineLayout->AllocateShaderBinding(1);
|
gbufferShaderBinding = lightingPipelineInfo.pipelineLayout->AllocateShaderBinding(0);
|
||||||
gbufferShaderBinding->Update({
|
gbufferShaderBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerInstance.GetViewerBuffer().get(),
|
||||||
|
0, viewerInstance.GetViewerBuffer()->GetSize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
bakedGraph.GetAttachmentTexture(colorTexture).get(),
|
bakedGraph.GetAttachmentTexture(colorTexture).get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
1,
|
2,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
bakedGraph.GetAttachmentTexture(normalTexture).get(),
|
bakedGraph.GetAttachmentTexture(normalTexture).get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
2,
|
3,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
bakedGraph.GetAttachmentTexture(positionTexture).get(),
|
bakedGraph.GetAttachmentTexture(positionTexture).get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
|
|
@ -966,7 +976,7 @@ int main()
|
||||||
|
|
||||||
for (std::size_t i = 0; i < MaxPointLight; ++i)
|
for (std::size_t i = 0; i < MaxPointLight; ++i)
|
||||||
{
|
{
|
||||||
std::shared_ptr<Nz::ShaderBinding> lightingShaderBinding = lightingPipelineInfo.pipelineLayout->AllocateShaderBinding(2);
|
std::shared_ptr<Nz::ShaderBinding> lightingShaderBinding = lightingPipelineInfo.pipelineLayout->AllocateShaderBinding(1);
|
||||||
lightingShaderBinding->Update({
|
lightingShaderBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
|
@ -982,10 +992,17 @@ int main()
|
||||||
|
|
||||||
frame.PushForRelease(std::move(bloomBrightShaderBinding));
|
frame.PushForRelease(std::move(bloomBrightShaderBinding));
|
||||||
|
|
||||||
bloomBrightShaderBinding = bloomPipelineInfo.pipelineLayout->AllocateShaderBinding(1);
|
bloomBrightShaderBinding = bloomPipelineInfo.pipelineLayout->AllocateShaderBinding(0);
|
||||||
bloomBrightShaderBinding->Update({
|
bloomBrightShaderBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerInstance.GetViewerBuffer().get(),
|
||||||
|
0, viewerInstance.GetViewerBuffer()->GetSize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
bakedGraph.GetAttachmentTexture(lightOutput).get(),
|
bakedGraph.GetAttachmentTexture(lightOutput).get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
|
|
@ -995,10 +1012,17 @@ int main()
|
||||||
|
|
||||||
frame.PushForRelease(std::move(gaussianBlurShaderBinding));
|
frame.PushForRelease(std::move(gaussianBlurShaderBinding));
|
||||||
|
|
||||||
gaussianBlurShaderBinding = bloomPipelineInfo.pipelineLayout->AllocateShaderBinding(1);
|
gaussianBlurShaderBinding = bloomPipelineInfo.pipelineLayout->AllocateShaderBinding(0);
|
||||||
gaussianBlurShaderBinding->Update({
|
gaussianBlurShaderBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerInstance.GetViewerBuffer().get(),
|
||||||
|
0, viewerInstance.GetViewerBuffer()->GetSize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
bakedGraph.GetAttachmentTexture(bloomTextureA).get(),
|
bakedGraph.GetAttachmentTexture(bloomTextureA).get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
|
|
@ -1008,17 +1032,24 @@ int main()
|
||||||
|
|
||||||
frame.PushForRelease(std::move(bloomBlendShaderBinding));
|
frame.PushForRelease(std::move(bloomBlendShaderBinding));
|
||||||
|
|
||||||
bloomBlendShaderBinding = bloomBlendPipelineInfo.pipelineLayout->AllocateShaderBinding(1);
|
bloomBlendShaderBinding = bloomBlendPipelineInfo.pipelineLayout->AllocateShaderBinding(0);
|
||||||
bloomBlendShaderBinding->Update({
|
bloomBlendShaderBinding->Update({
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
viewerInstance.GetViewerBuffer().get(),
|
||||||
|
0, viewerInstance.GetViewerBuffer()->GetSize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
bakedGraph.GetAttachmentTexture(lightOutput).get(),
|
bakedGraph.GetAttachmentTexture(lightOutput).get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
1,
|
2,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
bakedGraph.GetAttachmentTexture(bloomTextureB).get(),
|
bakedGraph.GetAttachmentTexture(bloomTextureB).get(),
|
||||||
textureSampler.get()
|
textureSampler.get()
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,11 @@ int main()
|
||||||
registry.get<Nz::NodeComponent>(viewer).SetParent(registry, headingEntity);
|
registry.get<Nz::NodeComponent>(viewer).SetParent(registry, headingEntity);
|
||||||
registry.get<Nz::NodeComponent>(viewer).SetPosition(Nz::Vector3f::Backward() * 2.5f + Nz::Vector3f::Up() * 1.f);
|
registry.get<Nz::NodeComponent>(viewer).SetPosition(Nz::Vector3f::Backward() * 2.5f + Nz::Vector3f::Up() * 1.f);
|
||||||
|
|
||||||
for (std::size_t x = 0; x < 1; ++x)
|
for (std::size_t x = 0; x < 2; ++x)
|
||||||
{
|
{
|
||||||
for (std::size_t y = 0; y < 1; ++y)
|
for (std::size_t y = 0; y < 2; ++y)
|
||||||
{
|
{
|
||||||
for (std::size_t z = 0; z < 1; ++z)
|
for (std::size_t z = 0; z < 2; ++z)
|
||||||
{
|
{
|
||||||
entt::entity entity = registry.create();
|
entt::entity entity = registry.create();
|
||||||
auto& entityGfx = registry.emplace<Nz::GraphicsComponent>(entity);
|
auto& entityGfx = registry.emplace<Nz::GraphicsComponent>(entity);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,16 @@ namespace Nz
|
||||||
template<typename T> void HashCombine(std::size_t& seed, const T& v);
|
template<typename T> void HashCombine(std::size_t& seed, const T& v);
|
||||||
template<typename T> bool IsPowerOfTwo(T value);
|
template<typename T> bool IsPowerOfTwo(T value);
|
||||||
template<typename T> T ReverseBits(T integer);
|
template<typename T> T ReverseBits(T integer);
|
||||||
|
#ifdef NAZARA_DEBUG
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_integral_v<To> && std::is_integral_v<From>, int> = 0> To SafeCast(From value);
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_floating_point_v<To> && std::is_floating_point_v<From>, int> = 0> To SafeCast(From value);
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_integral_v<To> && std::is_floating_point_v<From>, int> = 0> To SafeCast(From value);
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_floating_point_v<To> && std::is_integral_v<From>, int> = 0> To SafeCast(From value);
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_enum_v<To>&& std::is_integral_v<From>, int> = 0> To SafeCast(From value);
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_integral_v<To>&& std::is_enum_v<From>, int> = 0> To SafeCast(From value);
|
||||||
|
#else
|
||||||
|
template<typename To, typename From> To SafeCast(From value);
|
||||||
|
#endif
|
||||||
template<typename T> constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>;
|
template<typename T> constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <Nazara/Core/Stream.hpp>
|
#include <Nazara/Core/Stream.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <limits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <Nazara/Core/Debug.hpp>
|
#include <Nazara/Core/Debug.hpp>
|
||||||
|
|
||||||
|
|
@ -291,6 +292,75 @@ namespace Nz
|
||||||
return reversed;
|
return reversed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NAZARA_DEBUG
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_integral_v<To> && std::is_integral_v<From>, int>>
|
||||||
|
To SafeCast(From value)
|
||||||
|
{
|
||||||
|
// Type capable of storing the biggest value between the two types
|
||||||
|
using MaxValueType = std::conditional_t<(sizeof(From) > sizeof(To) || (sizeof(From) == sizeof(To) && std::is_signed_v<To>)), From, To>;
|
||||||
|
// Type capable of storing the smallest value between the two types
|
||||||
|
using MinValueType = std::conditional_t<(sizeof(From) > sizeof(To) || (sizeof(From) == sizeof(To) && std::is_signed_v<From>)), From, To>;
|
||||||
|
|
||||||
|
if constexpr (!std::is_signed_v<To>)
|
||||||
|
assert(value >= 0);
|
||||||
|
|
||||||
|
assert(static_cast<MaxValueType>(value) <= static_cast<MaxValueType>(std::numeric_limits<To>::max()));
|
||||||
|
assert(static_cast<MinValueType>(value) >= static_cast<MinValueType>(std::numeric_limits<To>::lowest()));
|
||||||
|
|
||||||
|
return static_cast<To>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_floating_point_v<To> && std::is_floating_point_v<From>, int>>
|
||||||
|
To SafeCast(From value)
|
||||||
|
{
|
||||||
|
// Type capable of storing the biggest value between the two types
|
||||||
|
using MaxValueType = std::conditional_t<(sizeof(From) > sizeof(To)), From, To>;
|
||||||
|
// Type capable of storing the smallest value between the two types
|
||||||
|
using MinValueType = std::conditional_t<(sizeof(From) > sizeof(To)), From, To>;
|
||||||
|
|
||||||
|
assert(static_cast<MaxValueType>(value) <= static_cast<MaxValueType>(std::numeric_limits<To>::max()));
|
||||||
|
assert(static_cast<MinValueType>(value) >= static_cast<MinValueType>(std::numeric_limits<To>::lowest()));
|
||||||
|
|
||||||
|
return static_cast<To>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_integral_v<To> && std::is_floating_point_v<From>, int>>
|
||||||
|
To SafeCast(From value)
|
||||||
|
{
|
||||||
|
assert(floor(value) == value);
|
||||||
|
|
||||||
|
assert(value <= static_cast<From>(std::numeric_limits<To>::max()));
|
||||||
|
assert(value >= static_cast<From>(std::numeric_limits<To>::lowest()));
|
||||||
|
|
||||||
|
return static_cast<To>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_floating_point_v<To> && std::is_integral_v<From>, int>>
|
||||||
|
To SafeCast(From value)
|
||||||
|
{
|
||||||
|
return static_cast<To>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_enum_v<To> && std::is_integral_v<From>, int>>
|
||||||
|
To SafeCast(From value)
|
||||||
|
{
|
||||||
|
return static_cast<To>(SafeCast<std::underlying_type_t<To>>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename To, typename From, std::enable_if_t<std::is_integral_v<To> && std::is_enum_v<From>, int>>
|
||||||
|
To SafeCast(From value)
|
||||||
|
{
|
||||||
|
return SafeCast<To>(static_cast<std::underlying_type_t<From>>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
template<typename To, typename From>
|
||||||
|
To SafeCast(From value)
|
||||||
|
{
|
||||||
|
return static_cast<To>(value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>
|
constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ namespace Nz
|
||||||
class CommandBufferBuilder;
|
class CommandBufferBuilder;
|
||||||
class RenderElement;
|
class RenderElement;
|
||||||
class RenderFrame;
|
class RenderFrame;
|
||||||
|
class ViewerInstance;
|
||||||
struct ElementRendererData;
|
struct ElementRendererData;
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API ElementRenderer
|
class NAZARA_GRAPHICS_API ElementRenderer
|
||||||
|
|
@ -28,8 +29,8 @@ namespace Nz
|
||||||
virtual ~ElementRenderer();
|
virtual ~ElementRenderer();
|
||||||
|
|
||||||
virtual std::unique_ptr<ElementRendererData> InstanciateData() = 0;
|
virtual std::unique_ptr<ElementRendererData> InstanciateData() = 0;
|
||||||
virtual void Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
|
virtual void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
|
||||||
virtual void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) = 0;
|
virtual void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) = 0;
|
||||||
virtual void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
virtual void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,17 @@ namespace Nz
|
||||||
Orthographic,
|
Orthographic,
|
||||||
Perspective
|
Perspective
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class PredefinedShaderBinding
|
||||||
|
{
|
||||||
|
InstanceDataUbo,
|
||||||
|
OverlayTexture,
|
||||||
|
ViewerDataUbo,
|
||||||
|
|
||||||
|
Max = ViewerDataUbo
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr std::size_t PredefinedShaderBindingCount = static_cast<std::size_t>(PredefinedShaderBinding::Max) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NAZARA_GRAPHICS_ENUMS_HPP
|
#endif // NAZARA_GRAPHICS_ENUMS_HPP
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ namespace Nz
|
||||||
RenderQueue<RenderElement*> depthPrepassRenderQueue;
|
RenderQueue<RenderElement*> depthPrepassRenderQueue;
|
||||||
RenderQueue<RenderElement*> forwardRenderQueue;
|
RenderQueue<RenderElement*> forwardRenderQueue;
|
||||||
ShaderBindingPtr blitShaderBinding;
|
ShaderBindingPtr blitShaderBinding;
|
||||||
|
bool prepare = true;
|
||||||
bool rebuildDepthPrepass = true;
|
bool rebuildDepthPrepass = true;
|
||||||
bool rebuildForwardPass = true;
|
bool rebuildForwardPass = true;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ namespace Nz
|
||||||
inline MaterialPassRegistry& GetMaterialPassRegistry();
|
inline MaterialPassRegistry& GetMaterialPassRegistry();
|
||||||
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
|
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
|
||||||
inline PixelFormat GetPreferredDepthStencilFormat() const;
|
inline PixelFormat GetPreferredDepthStencilFormat() const;
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& GetReferencePipelineLayout() const;
|
|
||||||
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
|
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
|
||||||
inline const RenderPassCache& GetRenderPassCache() const;
|
inline const RenderPassCache& GetRenderPassCache() const;
|
||||||
inline TextureSamplerCache& GetSamplerCache();
|
inline TextureSamplerCache& GetSamplerCache();
|
||||||
|
|
@ -55,17 +54,12 @@ namespace Nz
|
||||||
|
|
||||||
struct DefaultTextures
|
struct DefaultTextures
|
||||||
{
|
{
|
||||||
std::shared_ptr<Texture> whiteTexture2d;
|
std::array<std::shared_ptr<Texture>, ImageTypeCount> whiteTextures;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr UInt32 DrawDataBindingSet = 2;
|
static void FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
|
||||||
static constexpr UInt32 MaterialBindingSet = 3;
|
static void FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
|
||||||
static constexpr UInt32 ViewerBindingSet = 0;
|
static void FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set);
|
||||||
static constexpr UInt32 WorldBindingSet = 1;
|
|
||||||
|
|
||||||
static void FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = DrawDataBindingSet);
|
|
||||||
static void FillViewerPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = ViewerBindingSet);
|
|
||||||
static void FillWorldPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set = WorldBindingSet);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void BuildBlitPipeline();
|
void BuildBlitPipeline();
|
||||||
|
|
@ -80,7 +74,6 @@ namespace Nz
|
||||||
std::shared_ptr<RenderDevice> m_renderDevice;
|
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||||
std::shared_ptr<RenderPipeline> m_blitPipeline;
|
std::shared_ptr<RenderPipeline> m_blitPipeline;
|
||||||
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
|
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
|
||||||
std::shared_ptr<RenderPipelineLayout> m_referencePipelineLayout;
|
|
||||||
std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration;
|
std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration;
|
||||||
DefaultTextures m_defaultTextures;
|
DefaultTextures m_defaultTextures;
|
||||||
MaterialPassRegistry m_materialPassRegistry;
|
MaterialPassRegistry m_materialPassRegistry;
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,6 @@ namespace Nz
|
||||||
return m_preferredDepthStencilFormat;
|
return m_preferredDepthStencilFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& Graphics::GetReferencePipelineLayout() const
|
|
||||||
{
|
|
||||||
return m_referencePipelineLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const std::shared_ptr<RenderDevice>& Graphics::GetRenderDevice() const
|
inline const std::shared_ptr<RenderDevice>& Graphics::GetRenderDevice() const
|
||||||
{
|
{
|
||||||
return m_renderDevice;
|
return m_renderDevice;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Nz
|
||||||
inline void AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass);
|
inline void AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass);
|
||||||
inline void AddPass(std::string passName, std::shared_ptr<MaterialPass> pass);
|
inline void AddPass(std::string passName, std::shared_ptr<MaterialPass> pass);
|
||||||
|
|
||||||
inline MaterialPass* GetPass(std::size_t passIndex) const;
|
inline const std::shared_ptr<MaterialPass>& GetPass(std::size_t passIndex) const;
|
||||||
|
|
||||||
inline bool HasPass(std::size_t passIndex) const;
|
inline bool HasPass(std::size_t passIndex) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,23 @@ namespace Nz
|
||||||
return AddPass(registry.GetPassIndex(passName), std::move(pass));
|
return AddPass(registry.GetPassIndex(passName), std::move(pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MaterialPass* Material::GetPass(std::size_t passIndex) const
|
inline const std::shared_ptr<MaterialPass>& Material::GetPass(std::size_t passIndex) const
|
||||||
{
|
{
|
||||||
if (passIndex >= m_passes.size())
|
if (passIndex >= m_passes.size())
|
||||||
return nullptr;
|
{
|
||||||
|
static std::shared_ptr<MaterialPass> dummy;
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
return m_passes[passIndex].get();
|
return m_passes[passIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Material::HasPass(std::size_t passIndex) const
|
inline bool Material::HasPass(std::size_t passIndex) const
|
||||||
{
|
{
|
||||||
return GetPass(passIndex) != nullptr;
|
if (passIndex >= m_passes.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return m_passes[passIndex] != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Material::RemovePass(std::size_t passIndex)
|
inline void Material::RemovePass(std::size_t passIndex)
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ namespace Nz
|
||||||
|
|
||||||
inline void EnsurePipelineUpdate() const;
|
inline void EnsurePipelineUpdate() const;
|
||||||
|
|
||||||
|
void FillShaderBinding(std::vector<ShaderBinding::Binding>& bindings) const;
|
||||||
|
|
||||||
inline RendererComparison GetDepthCompareFunc() const;
|
inline RendererComparison GetDepthCompareFunc() const;
|
||||||
inline BlendEquation GetBlendAlphaModeEquation() const;
|
inline BlendEquation GetBlendAlphaModeEquation() const;
|
||||||
inline BlendEquation GetBlendColorModeEquation() const;
|
inline BlendEquation GetBlendColorModeEquation() const;
|
||||||
|
|
@ -70,7 +72,6 @@ namespace Nz
|
||||||
inline PrimitiveMode GetPrimitiveMode() const;
|
inline PrimitiveMode GetPrimitiveMode() const;
|
||||||
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
||||||
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
|
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
|
||||||
inline ShaderBinding& GetShaderBinding();
|
|
||||||
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
|
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
|
||||||
inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const;
|
inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const;
|
||||||
inline const std::shared_ptr<AbstractBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
|
inline const std::shared_ptr<AbstractBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
|
||||||
|
|
@ -109,12 +110,11 @@ namespace Nz
|
||||||
NazaraSignal(OnMaterialRelease, const MaterialPass* /*material*/);
|
NazaraSignal(OnMaterialRelease, const MaterialPass* /*material*/);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline void InvalidateCommandBuffer();
|
||||||
inline void InvalidatePipeline();
|
inline void InvalidatePipeline();
|
||||||
inline void InvalidateShaderBinding();
|
|
||||||
inline void InvalidateTextureSampler(std::size_t textureIndex);
|
inline void InvalidateTextureSampler(std::size_t textureIndex);
|
||||||
inline void InvalidateUniformData(std::size_t uniformBufferIndex);
|
inline void InvalidateUniformData(std::size_t uniformBufferIndex);
|
||||||
void UpdatePipeline() const;
|
void UpdatePipeline() const;
|
||||||
void UpdateShaderBinding();
|
|
||||||
|
|
||||||
struct MaterialTexture
|
struct MaterialTexture
|
||||||
{
|
{
|
||||||
|
|
@ -137,10 +137,8 @@ namespace Nz
|
||||||
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
||||||
mutable MaterialPipelineInfo m_pipelineInfo;
|
mutable MaterialPipelineInfo m_pipelineInfo;
|
||||||
MaterialPassFlags m_flags;
|
MaterialPassFlags m_flags;
|
||||||
ShaderBindingPtr m_shaderBinding;
|
|
||||||
bool m_forceCommandBufferRegeneration;
|
bool m_forceCommandBufferRegeneration;
|
||||||
mutable bool m_pipelineUpdated;
|
mutable bool m_pipelineUpdated;
|
||||||
bool m_shaderBindingUpdated;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -373,12 +373,6 @@ namespace Nz
|
||||||
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
|
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ShaderBinding& MaterialPass::GetShaderBinding()
|
|
||||||
{
|
|
||||||
assert(m_shaderBinding);
|
|
||||||
return *m_shaderBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const std::shared_ptr<Texture>& MaterialPass::GetTexture(std::size_t textureIndex) const
|
inline const std::shared_ptr<Texture>& MaterialPass::GetTexture(std::size_t textureIndex) const
|
||||||
{
|
{
|
||||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||||
|
|
@ -614,7 +608,8 @@ namespace Nz
|
||||||
if (m_textures[textureIndex].texture != texture)
|
if (m_textures[textureIndex].texture != texture)
|
||||||
{
|
{
|
||||||
m_textures[textureIndex].texture = std::move(texture);
|
m_textures[textureIndex].texture = std::move(texture);
|
||||||
InvalidateShaderBinding();
|
|
||||||
|
InvalidateCommandBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -624,6 +619,7 @@ namespace Nz
|
||||||
if (m_textures[textureIndex].samplerInfo != samplerInfo)
|
if (m_textures[textureIndex].samplerInfo != samplerInfo)
|
||||||
{
|
{
|
||||||
m_textures[textureIndex].samplerInfo = std::move(samplerInfo);
|
m_textures[textureIndex].samplerInfo = std::move(samplerInfo);
|
||||||
|
|
||||||
InvalidateTextureSampler(textureIndex);
|
InvalidateTextureSampler(textureIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -635,10 +631,17 @@ namespace Nz
|
||||||
{
|
{
|
||||||
m_uniformBuffers[bufferIndex].buffer = std::move(uniformBuffer);
|
m_uniformBuffers[bufferIndex].buffer = std::move(uniformBuffer);
|
||||||
m_uniformBuffers[bufferIndex].dataInvalidated = true;
|
m_uniformBuffers[bufferIndex].dataInvalidated = true;
|
||||||
InvalidateShaderBinding();
|
|
||||||
|
InvalidateCommandBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void MaterialPass::InvalidateCommandBuffer()
|
||||||
|
{
|
||||||
|
m_forceCommandBufferRegeneration = true;
|
||||||
|
OnMaterialInvalidated(this);
|
||||||
|
}
|
||||||
|
|
||||||
inline void MaterialPass::InvalidatePipeline()
|
inline void MaterialPass::InvalidatePipeline()
|
||||||
{
|
{
|
||||||
m_forceCommandBufferRegeneration = true;
|
m_forceCommandBufferRegeneration = true;
|
||||||
|
|
@ -647,20 +650,12 @@ namespace Nz
|
||||||
OnMaterialInvalidated(this);
|
OnMaterialInvalidated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MaterialPass::InvalidateShaderBinding()
|
|
||||||
{
|
|
||||||
m_forceCommandBufferRegeneration = true;
|
|
||||||
m_shaderBindingUpdated = false;
|
|
||||||
|
|
||||||
OnMaterialInvalidated(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void MaterialPass::InvalidateTextureSampler(std::size_t textureIndex)
|
inline void MaterialPass::InvalidateTextureSampler(std::size_t textureIndex)
|
||||||
{
|
{
|
||||||
assert(textureIndex < m_textures.size());
|
assert(textureIndex < m_textures.size());
|
||||||
m_textures[textureIndex].sampler.reset();
|
m_textures[textureIndex].sampler.reset();
|
||||||
|
|
||||||
InvalidateShaderBinding();
|
InvalidateCommandBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)
|
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)
|
||||||
|
|
@ -674,4 +669,3 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Graphics/DebugOff.hpp>
|
#include <Nazara/Graphics/DebugOff.hpp>
|
||||||
#include "MaterialPass.hpp"
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ namespace Nz
|
||||||
struct SharedUniformBlock;
|
struct SharedUniformBlock;
|
||||||
struct Texture;
|
struct Texture;
|
||||||
struct UniformBlock;
|
struct UniformBlock;
|
||||||
|
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
|
||||||
|
|
||||||
inline MaterialSettings();
|
inline MaterialSettings();
|
||||||
inline MaterialSettings(Builder builder);
|
inline MaterialSettings(Builder builder);
|
||||||
|
|
@ -38,6 +39,7 @@ namespace Nz
|
||||||
inline const Builder& GetBuilderData() const;
|
inline const Builder& GetBuilderData() const;
|
||||||
inline const std::vector<Option>& GetOptions() const;
|
inline const std::vector<Option>& GetOptions() const;
|
||||||
inline std::size_t GetOptionIndex(const std::string_view& name) const;
|
inline std::size_t GetOptionIndex(const std::string_view& name) const;
|
||||||
|
inline std::size_t GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const;
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
|
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
|
||||||
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType stage) const;
|
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType stage) const;
|
||||||
inline const std::vector<std::shared_ptr<UberShader>>& GetShaders() const;
|
inline const std::vector<std::shared_ptr<UberShader>>& GetShaders() const;
|
||||||
|
|
@ -59,11 +61,14 @@ namespace Nz
|
||||||
|
|
||||||
struct Builder
|
struct Builder
|
||||||
{
|
{
|
||||||
|
inline Builder();
|
||||||
|
|
||||||
std::vector<std::shared_ptr<UberShader>> shaders;
|
std::vector<std::shared_ptr<UberShader>> shaders;
|
||||||
std::vector<Option> options;
|
std::vector<Option> options;
|
||||||
std::vector<Texture> textures;
|
std::vector<Texture> textures;
|
||||||
std::vector<UniformBlock> uniformBlocks;
|
std::vector<UniformBlock> uniformBlocks;
|
||||||
std::vector<SharedUniformBlock> sharedUniformBlocks;
|
std::vector<SharedUniformBlock> sharedUniformBlocks;
|
||||||
|
PredefinedBinding predefinedBindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Option
|
struct Option
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,11 @@ namespace Nz
|
||||||
m_data(std::move(data))
|
m_data(std::move(data))
|
||||||
{
|
{
|
||||||
RenderPipelineLayoutInfo info;
|
RenderPipelineLayoutInfo info;
|
||||||
Graphics::FillDrawDataPipelineLayout(info);
|
|
||||||
Graphics::FillViewerPipelineLayout(info);
|
|
||||||
Graphics::FillWorldPipelineLayout(info);
|
|
||||||
|
|
||||||
for (const Texture& textureInfo : m_data.textures)
|
for (const Texture& textureInfo : m_data.textures)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
Graphics::MaterialBindingSet,
|
0,
|
||||||
textureInfo.bindingIndex,
|
textureInfo.bindingIndex,
|
||||||
ShaderBindingType::Texture,
|
ShaderBindingType::Texture,
|
||||||
textureInfo.shaderStages
|
textureInfo.shaderStages
|
||||||
|
|
@ -35,7 +32,7 @@ namespace Nz
|
||||||
for (const UniformBlock& ubo : m_data.uniformBlocks)
|
for (const UniformBlock& ubo : m_data.uniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
Graphics::MaterialBindingSet,
|
0,
|
||||||
ubo.bindingIndex,
|
ubo.bindingIndex,
|
||||||
ShaderBindingType::UniformBuffer,
|
ShaderBindingType::UniformBuffer,
|
||||||
ubo.shaderStages
|
ubo.shaderStages
|
||||||
|
|
@ -45,7 +42,7 @@ namespace Nz
|
||||||
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
|
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
Graphics::MaterialBindingSet,
|
0,
|
||||||
ubo.bindingIndex,
|
ubo.bindingIndex,
|
||||||
ShaderBindingType::UniformBuffer,
|
ShaderBindingType::UniformBuffer,
|
||||||
ubo.shaderStages
|
ubo.shaderStages
|
||||||
|
|
@ -76,6 +73,11 @@ namespace Nz
|
||||||
return InvalidIndex;
|
return InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::size_t MaterialSettings::GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const
|
||||||
|
{
|
||||||
|
return m_data.predefinedBindings[UnderlyingCast(shaderBinding)];
|
||||||
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
|
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
|
||||||
{
|
{
|
||||||
return m_pipelineLayout;
|
return m_pipelineLayout;
|
||||||
|
|
@ -193,6 +195,11 @@ namespace Nz
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline MaterialSettings::Builder::Builder()
|
||||||
|
{
|
||||||
|
predefinedBindings.fill(InvalidIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Graphics/DebugOff.hpp>
|
#include <Nazara/Graphics/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Nz
|
||||||
std::array<std::size_t, 3> lightArray;
|
std::array<std::size_t, 3> lightArray;
|
||||||
std::size_t lightArraySize;
|
std::size_t lightArraySize;
|
||||||
|
|
||||||
static PredefinedLightData GetOffset();
|
static PredefinedLightData GetOffsets();
|
||||||
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -42,6 +42,7 @@ namespace Nz
|
||||||
std::size_t worldMatrixOffset;
|
std::size_t worldMatrixOffset;
|
||||||
|
|
||||||
static PredefinedInstanceData GetOffsets();
|
static PredefinedInstanceData GetOffsets();
|
||||||
|
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NAZARA_GRAPHICS_API PredefinedViewerData
|
struct NAZARA_GRAPHICS_API PredefinedViewerData
|
||||||
|
|
@ -58,6 +59,7 @@ namespace Nz
|
||||||
std::size_t viewProjMatrixOffset;
|
std::size_t viewProjMatrixOffset;
|
||||||
|
|
||||||
static PredefinedViewerData GetOffsets();
|
static PredefinedViewerData GetOffsets();
|
||||||
|
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Graphics/RenderElement.hpp>
|
#include <Nazara/Graphics/RenderElement.hpp>
|
||||||
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline RenderElement::RenderElement(BasicRenderElement elementType) :
|
inline RenderElement::RenderElement(BasicRenderElement elementType) :
|
||||||
RenderElement(static_cast<UInt8>(elementType))
|
RenderElement(SafeCast<UInt8>(elementType))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define NAZARA_GRAPHICS_RENDERSPRITECHAIN_HPP
|
#define NAZARA_GRAPHICS_RENDERSPRITECHAIN_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||||
#include <Nazara/Graphics/RenderElement.hpp>
|
#include <Nazara/Graphics/RenderElement.hpp>
|
||||||
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
||||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||||
|
|
@ -17,36 +18,35 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class AbstractBuffer;
|
class AbstractBuffer;
|
||||||
class RenderPipeline;
|
class MaterialPass;
|
||||||
class ShaderBinding;
|
|
||||||
class VertexDeclaration;
|
class VertexDeclaration;
|
||||||
|
class ViewerInstance;
|
||||||
|
|
||||||
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::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const WorldInstance& worldInstance, const MaterialPassFlags& matFlags);
|
inline RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData);
|
||||||
~RenderSpriteChain() = default;
|
~RenderSpriteChain() = default;
|
||||||
|
|
||||||
inline UInt64 ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
||||||
|
|
||||||
inline const ShaderBinding& GetInstanceBinding() const;
|
inline const MaterialPass& GetMaterialPass() const;
|
||||||
inline const ShaderBinding& GetMaterialBinding() const;
|
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 Texture* GetTextureOverlay() const;
|
||||||
inline const VertexDeclaration* GetVertexDeclaration() const;
|
inline const VertexDeclaration* GetVertexDeclaration() const;
|
||||||
|
inline const WorldInstance& GetWorldInstance() const;
|
||||||
|
|
||||||
inline void Register(RenderQueueRegistry& registry) const override;
|
inline void Register(RenderQueueRegistry& registry) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<MaterialPass> m_materialPass;
|
||||||
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::shared_ptr<Texture> m_textureOverlay;
|
||||||
std::size_t m_spriteCount;
|
std::size_t m_spriteCount;
|
||||||
const void* m_spriteData;
|
const void* m_spriteData;
|
||||||
MaterialPassFlags m_matFlags;
|
|
||||||
const ShaderBinding& m_materialBinding;
|
|
||||||
const WorldInstance& m_worldInstance;
|
const WorldInstance& m_worldInstance;
|
||||||
int m_renderLayer;
|
int m_renderLayer;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,27 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
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 WorldInstance& worldInstance, const MaterialPassFlags& matFlags) :
|
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData) :
|
||||||
RenderElement(BasicRenderElement::SpriteChain),
|
RenderElement(BasicRenderElement::SpriteChain),
|
||||||
|
m_materialPass(std::move(materialPass)),
|
||||||
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_textureOverlay(std::move(textureOverlay)),
|
||||||
m_spriteCount(spriteCount),
|
m_spriteCount(spriteCount),
|
||||||
m_spriteData(spriteData),
|
m_spriteData(spriteData),
|
||||||
m_matFlags(matFlags),
|
|
||||||
m_materialBinding(materialBinding),
|
|
||||||
m_worldInstance(worldInstance),
|
m_worldInstance(worldInstance),
|
||||||
m_renderLayer(renderLayer)
|
m_renderLayer(renderLayer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline UInt64 RenderSpriteChain::ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const
|
inline UInt64 RenderSpriteChain::ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const
|
||||||
{
|
{
|
||||||
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
||||||
UInt64 elementType = GetElementType();
|
UInt64 elementType = GetElementType();
|
||||||
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
||||||
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
|
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
|
||||||
|
|
||||||
if (m_matFlags.Test(MaterialPassFlag::Transparent))
|
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::Transparent))
|
||||||
{
|
{
|
||||||
UInt64 matFlags = 1;
|
UInt64 matFlags = 1;
|
||||||
|
|
||||||
|
|
@ -66,19 +65,14 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ShaderBinding& RenderSpriteChain::GetInstanceBinding() const
|
inline const MaterialPass& RenderSpriteChain::GetMaterialPass() const
|
||||||
{
|
{
|
||||||
return m_worldInstance.GetShaderBinding();
|
return *m_materialPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ShaderBinding& RenderSpriteChain::GetMaterialBinding() const
|
inline const RenderPipeline& RenderSpriteChain::GetRenderPipeline() const
|
||||||
{
|
{
|
||||||
return m_materialBinding;
|
return *m_renderPipeline;
|
||||||
}
|
|
||||||
|
|
||||||
inline const RenderPipeline* RenderSpriteChain::GetRenderPipeline() const
|
|
||||||
{
|
|
||||||
return m_renderPipeline.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t RenderSpriteChain::GetSpriteCount() const
|
inline std::size_t RenderSpriteChain::GetSpriteCount() const
|
||||||
|
|
@ -101,6 +95,11 @@ namespace Nz
|
||||||
return m_vertexDeclaration.get();
|
return m_vertexDeclaration.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const WorldInstance& RenderSpriteChain::GetWorldInstance() const
|
||||||
|
{
|
||||||
|
return m_worldInstance;
|
||||||
|
}
|
||||||
|
|
||||||
inline void RenderSpriteChain::Register(RenderQueueRegistry& registry) const
|
inline void RenderSpriteChain::Register(RenderQueueRegistry& registry) const
|
||||||
{
|
{
|
||||||
registry.RegisterLayer(m_renderLayer);
|
registry.RegisterLayer(m_renderLayer);
|
||||||
|
|
|
||||||
|
|
@ -17,33 +17,33 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class AbstractBuffer;
|
class AbstractBuffer;
|
||||||
|
class MaterialPass;
|
||||||
class RenderPipeline;
|
class RenderPipeline;
|
||||||
class ShaderBinding;
|
class ShaderBinding;
|
||||||
|
|
||||||
class RenderSubmesh : public RenderElement
|
class RenderSubmesh : public RenderElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline RenderSubmesh(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer, const WorldInstance& worldInstance, const ShaderBinding& materialBinding, const MaterialPassFlags& matFlags);
|
inline RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer);
|
||||||
~RenderSubmesh() = default;
|
~RenderSubmesh() = default;
|
||||||
|
|
||||||
inline UInt64 ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
||||||
|
|
||||||
inline const AbstractBuffer* GetIndexBuffer() const;
|
inline const AbstractBuffer* GetIndexBuffer() const;
|
||||||
inline std::size_t GetIndexCount() const;
|
inline std::size_t GetIndexCount() const;
|
||||||
|
inline const MaterialPass& GetMaterialPass() const;
|
||||||
inline const RenderPipeline* GetRenderPipeline() const;
|
inline const RenderPipeline* GetRenderPipeline() const;
|
||||||
inline const ShaderBinding& GetInstanceBinding() const;
|
|
||||||
inline const ShaderBinding& GetMaterialBinding() const;
|
|
||||||
inline const AbstractBuffer* GetVertexBuffer() const;
|
inline const AbstractBuffer* GetVertexBuffer() const;
|
||||||
|
inline const WorldInstance& GetWorldInstance() const;
|
||||||
|
|
||||||
inline void Register(RenderQueueRegistry& registry) const override;
|
inline void Register(RenderQueueRegistry& registry) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<AbstractBuffer> m_indexBuffer;
|
std::shared_ptr<AbstractBuffer> m_indexBuffer;
|
||||||
std::shared_ptr<AbstractBuffer> m_vertexBuffer;
|
std::shared_ptr<AbstractBuffer> m_vertexBuffer;
|
||||||
|
std::shared_ptr<MaterialPass> m_materialPass;
|
||||||
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
||||||
std::size_t m_indexCount;
|
std::size_t m_indexCount;
|
||||||
MaterialPassFlags m_matFlags;
|
|
||||||
const ShaderBinding& m_materialBinding;
|
|
||||||
const WorldInstance& m_worldInstance;
|
const WorldInstance& m_worldInstance;
|
||||||
int m_renderLayer;
|
int m_renderLayer;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,31 +4,31 @@
|
||||||
|
|
||||||
#include <Nazara/Graphics/RenderSubmesh.hpp>
|
#include <Nazara/Graphics/RenderSubmesh.hpp>
|
||||||
#include <Nazara/Graphics/Algorithm.hpp>
|
#include <Nazara/Graphics/Algorithm.hpp>
|
||||||
|
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer, const WorldInstance& worldInstance, const ShaderBinding& materialBinding, const MaterialPassFlags& matFlags) :
|
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer) :
|
||||||
RenderElement(BasicRenderElement::Submesh),
|
RenderElement(BasicRenderElement::Submesh),
|
||||||
m_indexBuffer(std::move(indexBuffer)),
|
m_indexBuffer(std::move(indexBuffer)),
|
||||||
m_vertexBuffer(std::move(vertexBuffer)),
|
m_vertexBuffer(std::move(vertexBuffer)),
|
||||||
|
m_materialPass(std::move(materialPass)),
|
||||||
m_renderPipeline(std::move(renderPipeline)),
|
m_renderPipeline(std::move(renderPipeline)),
|
||||||
m_indexCount(indexCount),
|
m_indexCount(indexCount),
|
||||||
m_matFlags(matFlags),
|
|
||||||
m_materialBinding(materialBinding),
|
|
||||||
m_worldInstance(worldInstance),
|
m_worldInstance(worldInstance),
|
||||||
m_renderLayer(renderLayer)
|
m_renderLayer(renderLayer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline UInt64 RenderSubmesh::ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const
|
inline UInt64 RenderSubmesh::ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const
|
||||||
{
|
{
|
||||||
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
||||||
UInt64 elementType = GetElementType();
|
UInt64 elementType = GetElementType();
|
||||||
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
||||||
UInt64 vertexBufferIndex = registry.FetchVertexBuffer(m_vertexBuffer.get());
|
UInt64 vertexBufferIndex = registry.FetchVertexBuffer(m_vertexBuffer.get());
|
||||||
|
|
||||||
if (m_matFlags.Test(MaterialPassFlag::Transparent))
|
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::Transparent))
|
||||||
{
|
{
|
||||||
UInt64 matFlags = 1;
|
UInt64 matFlags = 1;
|
||||||
|
|
||||||
|
|
@ -74,26 +74,26 @@ namespace Nz
|
||||||
return m_indexCount;
|
return m_indexCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const MaterialPass& RenderSubmesh::GetMaterialPass() const
|
||||||
|
{
|
||||||
|
return *m_materialPass;
|
||||||
|
}
|
||||||
|
|
||||||
inline const RenderPipeline* RenderSubmesh::GetRenderPipeline() const
|
inline const RenderPipeline* RenderSubmesh::GetRenderPipeline() const
|
||||||
{
|
{
|
||||||
return m_renderPipeline.get();
|
return m_renderPipeline.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ShaderBinding& RenderSubmesh::GetInstanceBinding() const
|
|
||||||
{
|
|
||||||
return m_worldInstance.GetShaderBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const ShaderBinding& RenderSubmesh::GetMaterialBinding() const
|
|
||||||
{
|
|
||||||
return m_materialBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const AbstractBuffer* RenderSubmesh::GetVertexBuffer() const
|
inline const AbstractBuffer* RenderSubmesh::GetVertexBuffer() const
|
||||||
{
|
{
|
||||||
return m_vertexBuffer.get();
|
return m_vertexBuffer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const WorldInstance& RenderSubmesh::GetWorldInstance() const
|
||||||
|
{
|
||||||
|
return m_worldInstance;
|
||||||
|
}
|
||||||
|
|
||||||
inline void RenderSubmesh::Register(RenderQueueRegistry& registry) const
|
inline void RenderSubmesh::Register(RenderQueueRegistry& registry) const
|
||||||
{
|
{
|
||||||
registry.RegisterLayer(m_renderLayer);
|
registry.RegisterLayer(m_renderLayer);
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ namespace Nz
|
||||||
~SpriteChainRenderer() = default;
|
~SpriteChainRenderer() = default;
|
||||||
|
|
||||||
std::unique_ptr<ElementRendererData> InstanciateData();
|
std::unique_ptr<ElementRendererData> InstanciateData();
|
||||||
void Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
|
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
|
||||||
void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
|
void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
|
||||||
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -52,6 +52,7 @@ namespace Nz
|
||||||
std::size_t m_maxVertexBufferSize;
|
std::size_t m_maxVertexBufferSize;
|
||||||
std::size_t m_maxVertexCount;
|
std::size_t m_maxVertexCount;
|
||||||
std::vector<BufferCopy> m_pendingCopies;
|
std::vector<BufferCopy> m_pendingCopies;
|
||||||
|
std::vector<ShaderBinding::Binding> m_bindingCache;
|
||||||
RenderDevice& m_device;
|
RenderDevice& m_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -61,9 +62,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const AbstractBuffer* vertexBuffer;
|
const AbstractBuffer* vertexBuffer;
|
||||||
const RenderPipeline* renderPipeline;
|
const RenderPipeline* renderPipeline;
|
||||||
const ShaderBinding* drawDataBinding;
|
const ShaderBinding* shaderBinding;
|
||||||
const ShaderBinding* instanceBinding;
|
|
||||||
const ShaderBinding* materialBinding;
|
|
||||||
std::size_t firstIndex;
|
std::size_t firstIndex;
|
||||||
std::size_t quadCount;
|
std::size_t quadCount;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
class AbstractBuffer;
|
||||||
|
class RenderPipeline;
|
||||||
|
class ShaderBinding;
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API SubmeshRenderer : public ElementRenderer
|
class NAZARA_GRAPHICS_API SubmeshRenderer : public ElementRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -20,10 +24,27 @@ namespace Nz
|
||||||
~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 Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
|
||||||
|
void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
|
||||||
|
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ShaderBindingPtr m_renderDataBinding;
|
std::vector<ShaderBinding::Binding> m_bindingCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SubmeshRendererData : public ElementRendererData
|
||||||
|
{
|
||||||
|
struct DrawCall
|
||||||
|
{
|
||||||
|
const AbstractBuffer* indexBuffer;
|
||||||
|
const AbstractBuffer* vertexBuffer;
|
||||||
|
const RenderPipeline* renderPipeline;
|
||||||
|
const ShaderBinding* shaderBinding;
|
||||||
|
std::size_t indexCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<DrawCall> drawCalls;
|
||||||
|
std::vector<ShaderBindingPtr> shaderBindings;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,8 @@ namespace Nz
|
||||||
inline const Matrix4f& GetProjectionMatrix() const;
|
inline const Matrix4f& GetProjectionMatrix() const;
|
||||||
inline const Matrix4f& GetViewMatrix() const;
|
inline const Matrix4f& GetViewMatrix() const;
|
||||||
inline const Matrix4f& GetViewProjMatrix() const;
|
inline const Matrix4f& GetViewProjMatrix() const;
|
||||||
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
inline std::shared_ptr<AbstractBuffer>& GetViewerBuffer();
|
||||||
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
inline const std::shared_ptr<AbstractBuffer>& GetViewerBuffer() const;
|
||||||
inline ShaderBinding& GetShaderBinding();
|
|
||||||
|
|
||||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||||
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
|
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
|
||||||
|
|
@ -59,7 +58,6 @@ namespace Nz
|
||||||
Matrix4f m_projectionMatrix;
|
Matrix4f m_projectionMatrix;
|
||||||
Matrix4f m_viewProjMatrix;
|
Matrix4f m_viewProjMatrix;
|
||||||
Matrix4f m_viewMatrix;
|
Matrix4f m_viewMatrix;
|
||||||
ShaderBindingPtr m_shaderBinding;
|
|
||||||
Vector2f m_targetSize;
|
Vector2f m_targetSize;
|
||||||
bool m_dataInvalided;
|
bool m_dataInvalided;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -38,21 +38,16 @@ namespace Nz
|
||||||
return m_viewProjMatrix;
|
return m_viewProjMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<AbstractBuffer>& ViewerInstance::GetInstanceBuffer()
|
inline std::shared_ptr<AbstractBuffer>& ViewerInstance::GetViewerBuffer()
|
||||||
{
|
{
|
||||||
return m_viewerDataBuffer;
|
return m_viewerDataBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<AbstractBuffer>& ViewerInstance::GetInstanceBuffer() const
|
inline const std::shared_ptr<AbstractBuffer>& ViewerInstance::GetViewerBuffer() const
|
||||||
{
|
{
|
||||||
return m_viewerDataBuffer;
|
return m_viewerDataBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ShaderBinding& ViewerInstance::GetShaderBinding()
|
|
||||||
{
|
|
||||||
return *m_shaderBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
|
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
|
||||||
{
|
{
|
||||||
m_projectionMatrix = projectionMatrix;
|
m_projectionMatrix = projectionMatrix;
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,6 @@ namespace Nz
|
||||||
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
|
||||||
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
|
||||||
inline const Matrix4f& GetInvWorldMatrix() const;
|
inline const Matrix4f& GetInvWorldMatrix() const;
|
||||||
inline ShaderBinding& GetShaderBinding();
|
|
||||||
inline const ShaderBinding& GetShaderBinding() const;
|
|
||||||
inline const Matrix4f& GetWorldMatrix() const;
|
inline const Matrix4f& GetWorldMatrix() const;
|
||||||
|
|
||||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||||
|
|
@ -49,7 +47,6 @@ namespace Nz
|
||||||
std::shared_ptr<AbstractBuffer> m_instanceDataBuffer;
|
std::shared_ptr<AbstractBuffer> m_instanceDataBuffer;
|
||||||
Matrix4f m_invWorldMatrix;
|
Matrix4f m_invWorldMatrix;
|
||||||
Matrix4f m_worldMatrix;
|
Matrix4f m_worldMatrix;
|
||||||
ShaderBindingPtr m_shaderBinding;
|
|
||||||
bool m_dataInvalided;
|
bool m_dataInvalided;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,16 +23,6 @@ namespace Nz
|
||||||
return m_invWorldMatrix;
|
return m_invWorldMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ShaderBinding& WorldInstance::GetShaderBinding()
|
|
||||||
{
|
|
||||||
return *m_shaderBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const ShaderBinding& WorldInstance::GetShaderBinding() const
|
|
||||||
{
|
|
||||||
return *m_shaderBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const Matrix4f& WorldInstance::GetWorldMatrix() const
|
inline const Matrix4f& WorldInstance::GetWorldMatrix() const
|
||||||
{
|
{
|
||||||
return m_worldMatrix;
|
return m_worldMatrix;
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,18 @@ namespace Nz
|
||||||
//Resize(m_preferredSize);
|
//Resize(m_preferredSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline entt::registry& BaseWidget::GetRegistry()
|
||||||
|
{
|
||||||
|
assert(m_registry);
|
||||||
|
return *m_registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const entt::registry& BaseWidget::GetRegistry() const
|
||||||
|
{
|
||||||
|
assert(m_registry);
|
||||||
|
return *m_registry;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool BaseWidget::IsRegisteredToCanvas() const
|
inline bool BaseWidget::IsRegisteredToCanvas() const
|
||||||
{
|
{
|
||||||
return m_canvas && m_canvasIndex != InvalidCanvasIndex;
|
return m_canvas && m_canvasIndex != InvalidCanvasIndex;
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,20 @@ namespace Nz
|
||||||
std::move(defaultValues)
|
std::move(defaultValues)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Common data
|
||||||
|
settings.textures.push_back({
|
||||||
|
3,
|
||||||
|
"TextureOverlay",
|
||||||
|
ImageType::E2D
|
||||||
|
});
|
||||||
|
|
||||||
|
settings.sharedUniformBlocks.push_back(PredefinedInstanceData::GetUniformBlock(4, ShaderStageType::Vertex));
|
||||||
|
settings.sharedUniformBlocks.push_back(PredefinedViewerData::GetUniformBlock(5, ShaderStageType_All));
|
||||||
|
|
||||||
|
settings.predefinedBindings[UnderlyingCast(PredefinedShaderBinding::InstanceDataUbo)] = 4;
|
||||||
|
settings.predefinedBindings[UnderlyingCast(PredefinedShaderBinding::OverlayTexture)] = 3;
|
||||||
|
settings.predefinedBindings[UnderlyingCast(PredefinedShaderBinding::ViewerDataUbo)] = 5;
|
||||||
|
|
||||||
settings.shaders = std::move(uberShaders);
|
settings.shaders = std::move(uberShaders);
|
||||||
|
|
||||||
for (std::shared_ptr<UberShader> uberShader : settings.shaders)
|
for (std::shared_ptr<UberShader> uberShader : settings.shaders)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
ElementRenderer::~ElementRenderer() = default;
|
ElementRenderer::~ElementRenderer() = default;
|
||||||
|
|
||||||
void ElementRenderer::Prepare(ElementRendererData& /*rendererData*/, RenderFrame& /*currentFrame*/, const Pointer<const RenderElement>* /*elements*/, std::size_t /*elementCount*/)
|
void ElementRenderer::Prepare(const ViewerInstance& /*viewerInstance*/, ElementRendererData& /*rendererData*/, RenderFrame& /*currentFrame*/, const Pointer<const RenderElement>* /*elements*/, std::size_t /*elementCount*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,21 +61,21 @@ namespace Nz
|
||||||
{
|
{
|
||||||
if (newMaterial)
|
if (newMaterial)
|
||||||
{
|
{
|
||||||
if (MaterialPass* pass = newMaterial->GetPass(m_depthPassIndex))
|
if (const auto& pass = newMaterial->GetPass(m_depthPassIndex))
|
||||||
RegisterMaterialPass(pass);
|
RegisterMaterialPass(pass.get());
|
||||||
|
|
||||||
if (MaterialPass* pass = newMaterial->GetPass(m_forwardPassIndex))
|
if (const auto& pass = newMaterial->GetPass(m_forwardPassIndex))
|
||||||
RegisterMaterialPass(pass);
|
RegisterMaterialPass(pass.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& prevMaterial = instancedRenderable->GetMaterial(materialIndex);
|
const auto& prevMaterial = instancedRenderable->GetMaterial(materialIndex);
|
||||||
if (prevMaterial)
|
if (prevMaterial)
|
||||||
{
|
{
|
||||||
if (MaterialPass* pass = prevMaterial->GetPass(m_depthPassIndex))
|
if (const auto& pass = prevMaterial->GetPass(m_depthPassIndex))
|
||||||
UnregisterMaterialPass(pass);
|
UnregisterMaterialPass(pass.get());
|
||||||
|
|
||||||
if (MaterialPass* pass = prevMaterial->GetPass(m_forwardPassIndex))
|
if (const auto& pass = prevMaterial->GetPass(m_forwardPassIndex))
|
||||||
UnregisterMaterialPass(pass);
|
UnregisterMaterialPass(pass.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto&& [viewer, viewerData] : m_viewers)
|
for (auto&& [viewer, viewerData] : m_viewers)
|
||||||
|
|
@ -90,11 +90,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
if (Material* mat = instancedRenderable->GetMaterial(i).get())
|
if (Material* mat = instancedRenderable->GetMaterial(i).get())
|
||||||
{
|
{
|
||||||
if (MaterialPass* pass = mat->GetPass(m_depthPassIndex))
|
if (const auto& pass = mat->GetPass(m_depthPassIndex))
|
||||||
RegisterMaterialPass(pass);
|
RegisterMaterialPass(pass.get());
|
||||||
|
|
||||||
if (MaterialPass* pass = mat->GetPass(m_forwardPassIndex))
|
if (const auto& pass = mat->GetPass(m_forwardPassIndex))
|
||||||
RegisterMaterialPass(pass);
|
RegisterMaterialPass(pass.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +157,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
viewerData.rebuildDepthPrepass = true;
|
viewerData.rebuildDepthPrepass = true;
|
||||||
viewerData.rebuildForwardPass = true;
|
viewerData.rebuildForwardPass = true;
|
||||||
prepare = true;
|
viewerData.prepare = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +215,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
viewerData.rebuildDepthPrepass = true;
|
viewerData.rebuildDepthPrepass = true;
|
||||||
viewerData.rebuildForwardPass = true;
|
viewerData.rebuildForwardPass = true;
|
||||||
prepare = true;
|
viewerData.prepare = true;
|
||||||
|
|
||||||
viewerData.visibilityHash = visibilityHash;
|
viewerData.visibilityHash = visibilityHash;
|
||||||
}
|
}
|
||||||
|
|
@ -264,46 +264,42 @@ namespace Nz
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prepare)
|
for (auto&& [viewer, viewerData] : m_viewers)
|
||||||
{
|
{
|
||||||
|
if (!viewerData.prepare)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < m_elementRenderers.size(); ++i)
|
for (std::size_t i = 0; i < m_elementRenderers.size(); ++i)
|
||||||
{
|
{
|
||||||
auto& elementRendererPtr = m_elementRenderers[i];
|
auto& elementRendererPtr = m_elementRenderers[i];
|
||||||
|
|
||||||
for (auto&& [_, viewerData] : m_viewers)
|
if (i >= viewerData.elementRendererData.size() || !viewerData.elementRendererData[i])
|
||||||
{
|
{
|
||||||
if (i >= viewerData.elementRendererData.size() || !viewerData.elementRendererData[i])
|
if (i >= viewerData.elementRendererData.size())
|
||||||
{
|
viewerData.elementRendererData.resize(i + 1);
|
||||||
if (i >= viewerData.elementRendererData.size())
|
|
||||||
viewerData.elementRendererData.resize(i + 1);
|
|
||||||
|
|
||||||
viewerData.elementRendererData[i] = elementRendererPtr->InstanciateData();
|
viewerData.elementRendererData[i] = elementRendererPtr->InstanciateData();
|
||||||
}
|
|
||||||
|
|
||||||
if (elementRendererPtr)
|
|
||||||
elementRendererPtr->Reset(*viewerData.elementRendererData[i], renderFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (elementRendererPtr)
|
||||||
|
elementRendererPtr->Reset(*viewerData.elementRendererData[i], renderFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto&& [_, viewerData] : m_viewers)
|
auto& rendererData = viewerData.elementRendererData;
|
||||||
|
|
||||||
|
const auto& viewerInstance = viewer->GetViewerInstance();
|
||||||
|
|
||||||
|
ProcessRenderQueue(viewerData.depthPrepassRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||||
{
|
{
|
||||||
auto& rendererData = viewerData.elementRendererData;
|
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
||||||
|
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
|
||||||
|
});
|
||||||
|
|
||||||
ProcessRenderQueue(viewerData.depthPrepassRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
ProcessRenderQueue(viewerData.forwardRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||||
{
|
{
|
||||||
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
||||||
elementRenderer.Prepare(*rendererData[elementType], renderFrame, elements, elementCount);
|
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
ProcessRenderQueue(viewerData.forwardRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
|
||||||
{
|
|
||||||
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
|
||||||
elementRenderer.Prepare(*rendererData[elementType], renderFrame, elements, elementCount);
|
|
||||||
});
|
|
||||||
|
|
||||||
viewerData.rebuildForwardPass = true;
|
|
||||||
viewerData.rebuildDepthPrepass = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_bakedFrameGraph.Resize(renderFrame))
|
if (m_bakedFrameGraph.Resize(renderFrame))
|
||||||
|
|
@ -335,6 +331,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
viewerData.rebuildForwardPass = false;
|
viewerData.rebuildForwardPass = false;
|
||||||
viewerData.rebuildDepthPrepass = false;
|
viewerData.rebuildDepthPrepass = false;
|
||||||
|
viewerData.prepare = false;
|
||||||
|
|
||||||
const RenderTarget& renderTarget = viewer->GetRenderTarget();
|
const RenderTarget& renderTarget = viewer->GetRenderTarget();
|
||||||
Recti renderRegion(0, 0, frameSize.x, frameSize.y);
|
Recti renderRegion(0, 0, frameSize.x, frameSize.y);
|
||||||
|
|
@ -388,17 +385,17 @@ namespace Nz
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_removedWorldInstances.insert(worldInstance);
|
m_removedWorldInstances.insert(worldInstance);
|
||||||
m_renderables.erase(instanceIt);;
|
m_renderables.erase(instanceIt);
|
||||||
}
|
}
|
||||||
|
|
||||||
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* pass = instancedRenderable->GetMaterial(i)->GetPass(m_depthPassIndex))
|
if (const auto& pass = instancedRenderable->GetMaterial(i)->GetPass(m_depthPassIndex))
|
||||||
UnregisterMaterialPass(pass);
|
UnregisterMaterialPass(pass.get());
|
||||||
|
|
||||||
if (MaterialPass* pass = instancedRenderable->GetMaterial(i)->GetPass(m_forwardPassIndex))
|
if (const auto& pass = instancedRenderable->GetMaterial(i)->GetPass(m_forwardPassIndex))
|
||||||
UnregisterMaterialPass(pass);
|
UnregisterMaterialPass(pass.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto&& [viewer, viewerData] : m_viewers)
|
for (auto&& [viewer, viewerData] : m_viewers)
|
||||||
|
|
@ -454,12 +451,12 @@ namespace Nz
|
||||||
builder.SetScissor(viewport);
|
builder.SetScissor(viewport);
|
||||||
builder.SetViewport(viewport);
|
builder.SetViewport(viewport);
|
||||||
|
|
||||||
builder.BindShaderBinding(Graphics::ViewerBindingSet, viewer->GetViewerInstance().GetShaderBinding());
|
const auto& viewerInstance = viewer->GetViewerInstance();
|
||||||
|
|
||||||
ProcessRenderQueue(viewerData.depthPrepassRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
ProcessRenderQueue(viewerData.depthPrepassRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||||
{
|
{
|
||||||
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
||||||
elementRenderer.Render(*viewerData.elementRendererData[elementType], builder, elements, elementCount);
|
elementRenderer.Render(viewerInstance, *viewerData.elementRendererData[elementType], builder, elements, elementCount);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -486,12 +483,12 @@ namespace Nz
|
||||||
builder.SetScissor(viewport);
|
builder.SetScissor(viewport);
|
||||||
builder.SetViewport(viewport);
|
builder.SetViewport(viewport);
|
||||||
|
|
||||||
builder.BindShaderBinding(Graphics::ViewerBindingSet, viewer->GetViewerInstance().GetShaderBinding());
|
const auto& viewerInstance = viewer->GetViewerInstance();
|
||||||
|
|
||||||
ProcessRenderQueue(viewerData.forwardRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
ProcessRenderQueue(viewerData.forwardRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||||
{
|
{
|
||||||
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
|
||||||
elementRenderer.Render(*viewerData.elementRendererData[elementType], builder, elements, elementCount);
|
elementRenderer.Render(viewerInstance , *viewerData.elementRendererData[elementType], builder, elements, elementCount);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,13 +67,6 @@ namespace Nz
|
||||||
|
|
||||||
MaterialPipeline::Initialize();
|
MaterialPipeline::Initialize();
|
||||||
|
|
||||||
RenderPipelineLayoutInfo referenceLayoutInfo;
|
|
||||||
FillDrawDataPipelineLayout(referenceLayoutInfo);
|
|
||||||
FillViewerPipelineLayout(referenceLayoutInfo);
|
|
||||||
FillWorldPipelineLayout(referenceLayoutInfo);
|
|
||||||
|
|
||||||
m_referencePipelineLayout = m_renderDevice->InstantiateRenderPipelineLayout(std::move(referenceLayoutInfo));
|
|
||||||
|
|
||||||
BuildDefaultTextures();
|
BuildDefaultTextures();
|
||||||
BuildFullscreenVertexBuffer();
|
BuildFullscreenVertexBuffer();
|
||||||
BuildBlitPipeline();
|
BuildBlitPipeline();
|
||||||
|
|
@ -117,7 +110,7 @@ namespace Nz
|
||||||
m_fullscreenVertexDeclaration.reset();
|
m_fullscreenVertexDeclaration.reset();
|
||||||
m_blitPipeline.reset();
|
m_blitPipeline.reset();
|
||||||
m_blitPipelineLayout.reset();
|
m_blitPipelineLayout.reset();
|
||||||
m_defaultTextures.whiteTexture2d.reset();
|
m_defaultTextures.whiteTextures.fill(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
|
void Graphics::FillDrawDataPipelineLayout(RenderPipelineLayoutInfo& layoutInfo, UInt32 set)
|
||||||
|
|
@ -191,10 +184,15 @@ namespace Nz
|
||||||
texInfo.pixelFormat = PixelFormat::L8;
|
texInfo.pixelFormat = PixelFormat::L8;
|
||||||
texInfo.type = ImageType::E2D;
|
texInfo.type = ImageType::E2D;
|
||||||
|
|
||||||
std::array<UInt8, 4> texData = { 0xFF, 0xFF, 0xFF, 0xFF };
|
std::array<UInt8, 6> whitePixels = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
||||||
m_defaultTextures.whiteTexture2d = m_renderDevice->InstantiateTexture(texInfo);
|
for (std::size_t i = 0; i < ImageTypeCount; ++i)
|
||||||
m_defaultTextures.whiteTexture2d->Update(texData.data());
|
{
|
||||||
|
texInfo.type = static_cast<ImageType>(i);
|
||||||
|
|
||||||
|
m_defaultTextures.whiteTextures[i] = m_renderDevice->InstantiateTexture(texInfo);
|
||||||
|
m_defaultTextures.whiteTextures[i]->Update(whitePixels.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ namespace Nz
|
||||||
MaterialPass::MaterialPass(std::shared_ptr<const MaterialSettings> settings) :
|
MaterialPass::MaterialPass(std::shared_ptr<const MaterialSettings> settings) :
|
||||||
m_settings(std::move(settings)),
|
m_settings(std::move(settings)),
|
||||||
m_forceCommandBufferRegeneration(false),
|
m_forceCommandBufferRegeneration(false),
|
||||||
m_pipelineUpdated(false),
|
m_pipelineUpdated(false)
|
||||||
m_shaderBindingUpdated(false)
|
|
||||||
{
|
{
|
||||||
m_pipelineInfo.settings = m_settings;
|
m_pipelineInfo.settings = m_settings;
|
||||||
|
|
||||||
|
|
@ -44,14 +43,14 @@ namespace Nz
|
||||||
const auto& textureSettings = m_settings->GetTextures();
|
const auto& textureSettings = m_settings->GetTextures();
|
||||||
const auto& uboSettings = m_settings->GetUniformBlocks();
|
const auto& uboSettings = m_settings->GetUniformBlocks();
|
||||||
|
|
||||||
m_textures.resize(m_settings->GetTextures().size());
|
m_textures.resize(textureSettings.size());
|
||||||
|
|
||||||
m_uniformBuffers.reserve(m_settings->GetUniformBlocks().size());
|
m_uniformBuffers.reserve(uboSettings.size());
|
||||||
for (const auto& uniformBufferInfo : m_settings->GetUniformBlocks())
|
for (const auto& uniformBufferInfo : uboSettings)
|
||||||
{
|
{
|
||||||
auto& uniformBuffer = m_uniformBuffers.emplace_back();
|
auto& uniformBuffer = m_uniformBuffers.emplace_back();
|
||||||
|
|
||||||
uniformBuffer.buffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(Nz::BufferType::Uniform);
|
uniformBuffer.buffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||||
if (!uniformBuffer.buffer->Initialize(uniformBufferInfo.blockSize, BufferUsage::Dynamic))
|
if (!uniformBuffer.buffer->Initialize(uniformBufferInfo.blockSize, BufferUsage::Dynamic))
|
||||||
throw std::runtime_error("failed to initialize UBO memory");
|
throw std::runtime_error("failed to initialize UBO memory");
|
||||||
|
|
||||||
|
|
@ -60,20 +59,60 @@ namespace Nz
|
||||||
uniformBuffer.data.resize(uniformBufferInfo.blockSize);
|
uniformBuffer.data.resize(uniformBufferInfo.blockSize);
|
||||||
std::memcpy(uniformBuffer.data.data(), uniformBufferInfo.defaultValues.data(), uniformBufferInfo.defaultValues.size());
|
std::memcpy(uniformBuffer.data.data(), uniformBufferInfo.defaultValues.data(), uniformBufferInfo.defaultValues.size());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UpdateShaderBinding();
|
void MaterialPass::FillShaderBinding(std::vector<ShaderBinding::Binding>& bindings) const
|
||||||
|
{
|
||||||
|
const auto& textureSettings = m_settings->GetTextures();
|
||||||
|
const auto& uboSettings = m_settings->GetUniformBlocks();
|
||||||
|
|
||||||
|
// Textures
|
||||||
|
for (std::size_t i = 0; i < m_textures.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto& textureSetting = textureSettings[i];
|
||||||
|
const auto& textureSlot = m_textures[i];
|
||||||
|
|
||||||
|
if (!textureSlot.sampler)
|
||||||
|
{
|
||||||
|
TextureSamplerCache& samplerCache = Graphics::Instance()->GetSamplerCache();
|
||||||
|
textureSlot.sampler = samplerCache.Get(textureSlot.samplerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Use "missing" texture
|
||||||
|
Texture* texture = textureSlot.texture.get();
|
||||||
|
if (!texture)
|
||||||
|
{
|
||||||
|
const auto& defaultTextures = Graphics::Instance()->GetDefaultTextures();
|
||||||
|
texture = defaultTextures.whiteTextures[UnderlyingCast(textureSetting.type)].get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bindings.push_back({
|
||||||
|
textureSetting.bindingIndex,
|
||||||
|
ShaderBinding::TextureBinding {
|
||||||
|
texture, textureSlot.sampler.get()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shared UBO (TODO)
|
||||||
|
|
||||||
|
// Owned UBO
|
||||||
|
for (std::size_t i = 0; i < m_uniformBuffers.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto& uboSetting = uboSettings[i];
|
||||||
|
const auto& uboSlot = m_uniformBuffers[i];
|
||||||
|
|
||||||
|
bindings.push_back({
|
||||||
|
uboSetting.bindingIndex,
|
||||||
|
ShaderBinding::UniformBufferBinding {
|
||||||
|
uboSlot.buffer.get(), 0, uboSlot.buffer->GetSize()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MaterialPass::Update(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
bool MaterialPass::Update(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
||||||
{
|
{
|
||||||
if (!m_shaderBindingUpdated)
|
|
||||||
{
|
|
||||||
renderFrame.PushForRelease(std::move(m_shaderBinding));
|
|
||||||
m_shaderBinding.reset();
|
|
||||||
|
|
||||||
UpdateShaderBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
UploadPool& uploadPool = renderFrame.GetUploadPool();
|
UploadPool& uploadPool = renderFrame.GetUploadPool();
|
||||||
|
|
||||||
for (auto& ubo : m_uniformBuffers)
|
for (auto& ubo : m_uniformBuffers)
|
||||||
|
|
@ -118,60 +157,4 @@ namespace Nz
|
||||||
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
|
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
|
||||||
m_pipelineUpdated = true;
|
m_pipelineUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialPass::UpdateShaderBinding()
|
|
||||||
{
|
|
||||||
assert(!m_shaderBinding);
|
|
||||||
|
|
||||||
const auto& textureSettings = m_settings->GetTextures();
|
|
||||||
const auto& uboSettings = m_settings->GetUniformBlocks();
|
|
||||||
|
|
||||||
// TODO: Use StackVector
|
|
||||||
std::vector<ShaderBinding::Binding> bindings;
|
|
||||||
|
|
||||||
// Textures
|
|
||||||
for (std::size_t i = 0; i < m_textures.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto& textureSetting = textureSettings[i];
|
|
||||||
const auto& textureSlot = m_textures[i];
|
|
||||||
|
|
||||||
if (!textureSlot.sampler)
|
|
||||||
{
|
|
||||||
TextureSamplerCache& samplerCache = Graphics::Instance()->GetSamplerCache();
|
|
||||||
textureSlot.sampler = samplerCache.Get(textureSlot.samplerInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Use "missing" texture
|
|
||||||
if (textureSlot.texture)
|
|
||||||
{
|
|
||||||
bindings.push_back({
|
|
||||||
textureSetting.bindingIndex,
|
|
||||||
ShaderBinding::TextureBinding {
|
|
||||||
textureSlot.texture.get(), textureSlot.sampler.get()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shared UBO (TODO)
|
|
||||||
|
|
||||||
// Owned UBO
|
|
||||||
for (std::size_t i = 0; i < m_uniformBuffers.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto& uboSetting = uboSettings[i];
|
|
||||||
const auto& uboSlot = m_uniformBuffers[i];
|
|
||||||
|
|
||||||
bindings.push_back({
|
|
||||||
uboSetting.bindingIndex,
|
|
||||||
ShaderBinding::UniformBufferBinding {
|
|
||||||
uboSlot.buffer.get(), 0, uboSlot.buffer->GetSize()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
m_shaderBinding = m_settings->GetRenderPipelineLayout()->AllocateShaderBinding(Graphics::MaterialBindingSet);
|
|
||||||
m_shaderBinding->Update(bindings.data(), bindings.size());
|
|
||||||
|
|
||||||
m_shaderBindingUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const auto& submeshData = m_submeshes[i];
|
const auto& submeshData = m_submeshes[i];
|
||||||
|
|
||||||
MaterialPass* materialPass = submeshData.material->GetPass(passIndex);
|
const auto& materialPass = submeshData.material->GetPass(passIndex);
|
||||||
if (!materialPass)
|
if (!materialPass)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ namespace Nz
|
||||||
const auto& vertexBuffer = m_graphicalMesh->GetVertexBuffer(i);
|
const auto& vertexBuffer = m_graphicalMesh->GetVertexBuffer(i);
|
||||||
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(submeshData.vertexBufferData);
|
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(submeshData.vertexBufferData);
|
||||||
|
|
||||||
elements.emplace_back(std::make_unique<RenderSubmesh>(0, renderPipeline, m_graphicalMesh->GetIndexCount(i), indexBuffer, vertexBuffer, worldInstance, materialPass->GetShaderBinding(), materialPass->GetFlags()));
|
elements.emplace_back(std::make_unique<RenderSubmesh>(0, materialPass, renderPipeline, worldInstance, m_graphicalMesh->GetIndexCount(i), indexBuffer, vertexBuffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
PredefinedLightData PredefinedLightData::GetOffset()
|
PredefinedLightData PredefinedLightData::GetOffsets()
|
||||||
{
|
{
|
||||||
PredefinedLightData lightData;
|
PredefinedLightData lightData;
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace Nz
|
||||||
|
|
||||||
MaterialSettings::SharedUniformBlock PredefinedLightData::GetUniformBlock()
|
MaterialSettings::SharedUniformBlock PredefinedLightData::GetUniformBlock()
|
||||||
{
|
{
|
||||||
PredefinedLightData lightData = GetOffset();
|
PredefinedLightData lightData = GetOffsets();
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformVariable> lightDataVariables;
|
std::vector<MaterialSettings::UniformVariable> lightDataVariables;
|
||||||
for (std::size_t i = 0; i < lightData.lightArray.size(); ++i)
|
for (std::size_t i = 0; i < lightData.lightArray.size(); ++i)
|
||||||
|
|
@ -67,6 +67,27 @@ namespace Nz
|
||||||
return instanceData;
|
return instanceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock PredefinedInstanceData::GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages)
|
||||||
|
{
|
||||||
|
PredefinedInstanceData instanceData = GetOffsets();
|
||||||
|
|
||||||
|
std::vector<MaterialSettings::UniformVariable> variables = {
|
||||||
|
{
|
||||||
|
{ "WorldMatrix", instanceData.worldMatrixOffset },
|
||||||
|
{ "InvWorldMatrix", instanceData.invWorldMatrixOffset }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock uniformBlock = {
|
||||||
|
bindingIndex,
|
||||||
|
"InstanceData",
|
||||||
|
std::move(variables),
|
||||||
|
shaderStages
|
||||||
|
};
|
||||||
|
|
||||||
|
return uniformBlock;
|
||||||
|
}
|
||||||
|
|
||||||
PredefinedViewerData PredefinedViewerData::GetOffsets()
|
PredefinedViewerData PredefinedViewerData::GetOffsets()
|
||||||
{
|
{
|
||||||
FieldOffsets viewerStruct(StructLayout::Std140);
|
FieldOffsets viewerStruct(StructLayout::Std140);
|
||||||
|
|
@ -86,4 +107,33 @@ namespace Nz
|
||||||
|
|
||||||
return viewerData;
|
return viewerData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock PredefinedViewerData::GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages)
|
||||||
|
{
|
||||||
|
PredefinedViewerData viewerData = GetOffsets();
|
||||||
|
|
||||||
|
std::vector<MaterialSettings::UniformVariable> variables = {
|
||||||
|
{
|
||||||
|
{ "EyePosition", viewerData.eyePositionOffset },
|
||||||
|
{ "InvProjMatrix", viewerData.invProjMatrixOffset },
|
||||||
|
{ "InvTargetSize", viewerData.invTargetSizeOffset },
|
||||||
|
{ "InvViewMatrix", viewerData.invViewMatrixOffset },
|
||||||
|
{ "InvViewProjMatrix", viewerData.invViewProjMatrixOffset },
|
||||||
|
{ "ProjMatrix", viewerData.projMatrixOffset },
|
||||||
|
{ "TargetSize", viewerData.targetSizeOffset },
|
||||||
|
{ "ViewMatrix", viewerData.viewMatrixOffset },
|
||||||
|
{ "ViewProjMatrix", viewerData.viewProjMatrixOffset }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MaterialSettings::SharedUniformBlock uniformBlock = {
|
||||||
|
bindingIndex,
|
||||||
|
"ViewerData",
|
||||||
|
std::move(variables),
|
||||||
|
shaderStages
|
||||||
|
};
|
||||||
|
|
||||||
|
return uniformBlock;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,12 @@ struct ViewerData
|
||||||
|
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
[binding(0)] settings: uniform<BasicSettings>,
|
||||||
[set(1), binding(0)] instanceData: uniform<InstanceData>,
|
[binding(1)] MaterialDiffuseMap: sampler2D<f32>,
|
||||||
[set(2), binding(0)] TextureOverlay: sampler2D<f32>,
|
[binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
||||||
[set(3), binding(0)] settings: uniform<BasicSettings>,
|
[binding(3)] TextureOverlay: sampler2D<f32>,
|
||||||
[set(3), binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
[binding(4)] instanceData: uniform<InstanceData>,
|
||||||
[set(3), binding(1)] MaterialDiffuseMap: sampler2D<f32>
|
[binding(5)] viewerData: uniform<ViewerData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fragment stage
|
// Fragment stage
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,12 @@ struct ViewerData
|
||||||
|
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
[set(0), binding(0)] viewerData: uniform<ViewerData>,
|
[binding(0)] settings: uniform<BasicSettings>,
|
||||||
[set(1), binding(0)] instanceData: uniform<InstanceData>,
|
[binding(1)] MaterialDiffuseMap: sampler2D<f32>,
|
||||||
[set(2), binding(0)] TextureOverlay: sampler2D<f32>,
|
[binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
||||||
[set(3), binding(0)] settings: uniform<BasicSettings>,
|
[binding(3)] TextureOverlay: sampler2D<f32>,
|
||||||
[set(3), binding(2)] MaterialAlphaMap: sampler2D<f32>,
|
[binding(4)] instanceData: uniform<InstanceData>,
|
||||||
[set(3), binding(1)] MaterialDiffuseMap: sampler2D<f32>
|
[binding(5)] viewerData: uniform<ViewerData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fragment stage
|
// Fragment stage
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace Nz
|
||||||
|
|
||||||
void Sprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const
|
void Sprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const
|
||||||
{
|
{
|
||||||
MaterialPass* materialPass = m_material->GetPass(passIndex);
|
const auto& materialPass = m_material->GetPass(passIndex);
|
||||||
if (!materialPass)
|
if (!materialPass)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -40,9 +40,9 @@ namespace Nz
|
||||||
};
|
};
|
||||||
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(vertexBufferData);
|
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(vertexBufferData);
|
||||||
|
|
||||||
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTexture2d;
|
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)];
|
||||||
|
|
||||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(0, renderPipeline, vertexDeclaration, whiteTexture, 1, m_vertices.data(), materialPass->GetShaderBinding(), worldInstance, materialPass->GetFlags()));
|
elements.emplace_back(std::make_unique<RenderSpriteChain>(0, materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, 1, m_vertices.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Color& Sprite::GetColor() const
|
inline const Color& Sprite::GetColor() const
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <Nazara/Graphics/SpriteChainRenderer.hpp>
|
#include <Nazara/Graphics/SpriteChainRenderer.hpp>
|
||||||
#include <Nazara/Graphics/Graphics.hpp>
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/RenderSpriteChain.hpp>
|
#include <Nazara/Graphics/RenderSpriteChain.hpp>
|
||||||
|
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||||
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||||
#include <Nazara/Renderer/RenderFrame.hpp>
|
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||||
#include <Nazara/Renderer/UploadPool.hpp>
|
#include <Nazara/Renderer/UploadPool.hpp>
|
||||||
|
|
@ -52,7 +53,7 @@ namespace Nz
|
||||||
return std::make_unique<SpriteChainRendererData>();
|
return std::make_unique<SpriteChainRendererData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteChainRenderer::Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
void SpriteChainRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||||
{
|
{
|
||||||
Graphics* graphics = Graphics::Instance();
|
Graphics* graphics = Graphics::Instance();
|
||||||
|
|
||||||
|
|
@ -65,10 +66,9 @@ 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* currentShaderBinding = nullptr;
|
||||||
const ShaderBinding* currentInstanceBinding = nullptr;
|
|
||||||
const ShaderBinding* currentMaterialBinding = nullptr;
|
|
||||||
const Texture* currentTextureOverlay = nullptr;
|
const Texture* currentTextureOverlay = nullptr;
|
||||||
|
const WorldInstance* currentWorldInstance = nullptr;
|
||||||
|
|
||||||
auto FlushDrawCall = [&]()
|
auto FlushDrawCall = [&]()
|
||||||
{
|
{
|
||||||
|
|
@ -79,7 +79,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
FlushDrawCall();
|
FlushDrawCall();
|
||||||
|
|
||||||
currentDrawDataBinding = nullptr;
|
currentShaderBinding = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto Flush = [&]()
|
auto Flush = [&]()
|
||||||
|
|
@ -122,24 +122,18 @@ namespace Nz
|
||||||
currentVertexDeclaration = vertexDeclaration;
|
currentVertexDeclaration = vertexDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPipeline != spriteChain.GetRenderPipeline())
|
if (currentPipeline != &spriteChain.GetRenderPipeline())
|
||||||
{
|
{
|
||||||
FlushDrawCall();
|
FlushDrawCall();
|
||||||
currentPipeline = spriteChain.GetRenderPipeline();
|
currentPipeline = &spriteChain.GetRenderPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentMaterialBinding != &spriteChain.GetMaterialBinding())
|
if (currentWorldInstance != &spriteChain.GetWorldInstance())
|
||||||
{
|
|
||||||
FlushDrawCall();
|
|
||||||
currentMaterialBinding = &spriteChain.GetMaterialBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentInstanceBinding != &spriteChain.GetInstanceBinding())
|
|
||||||
{
|
{
|
||||||
// TODO: Flushing draw calls on instance binding means we can have e.g. 1000 sprites rendered using a draw call for each one
|
// TODO: Flushing draw calls on instance binding means we can have e.g. 1000 sprites rendered using a draw call for each one
|
||||||
// which is far from being efficient, using some bindless could help (or at least instancing?)
|
// which is far from being efficient, using some bindless could help (or at least instancing?)
|
||||||
FlushDrawCall();
|
FlushDrawData();
|
||||||
currentInstanceBinding = &spriteChain.GetInstanceBinding();
|
currentWorldInstance = &spriteChain.GetWorldInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTextureOverlay != spriteChain.GetTextureOverlay())
|
if (currentTextureOverlay != spriteChain.GetTextureOverlay())
|
||||||
|
|
@ -177,19 +171,52 @@ namespace Nz
|
||||||
data.vertexBuffers.emplace_back(std::move(vertexBuffer));
|
data.vertexBuffers.emplace_back(std::move(vertexBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currentDrawDataBinding)
|
if (!currentShaderBinding)
|
||||||
{
|
{
|
||||||
ShaderBindingPtr drawDataBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::DrawDataBindingSet);
|
m_bindingCache.clear();
|
||||||
drawDataBinding->Update({
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
ShaderBinding::TextureBinding {
|
|
||||||
currentTextureOverlay, defaultSampler.get()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
currentDrawDataBinding = drawDataBinding.get();
|
const MaterialPass& materialPass = spriteChain.GetMaterialPass();
|
||||||
|
materialPass.FillShaderBinding(m_bindingCache);
|
||||||
|
|
||||||
|
// Predefined shader bindings
|
||||||
|
const auto& matSettings = materialPass.GetSettings();
|
||||||
|
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::InstanceDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||||
|
{
|
||||||
|
const auto& instanceBuffer = currentWorldInstance->GetInstanceBuffer();
|
||||||
|
|
||||||
|
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||||
|
bindingEntry.bindingIndex = bindingIndex;
|
||||||
|
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||||
|
instanceBuffer.get(),
|
||||||
|
0, instanceBuffer->GetSize()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::ViewerDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||||
|
{
|
||||||
|
const auto& viewerBuffer = viewerInstance.GetViewerBuffer();
|
||||||
|
|
||||||
|
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||||
|
bindingEntry.bindingIndex = bindingIndex;
|
||||||
|
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||||
|
viewerBuffer.get(),
|
||||||
|
0, viewerBuffer->GetSize()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::OverlayTexture); bindingIndex != MaterialSettings::InvalidIndex)
|
||||||
|
{
|
||||||
|
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||||
|
bindingEntry.bindingIndex = bindingIndex;
|
||||||
|
bindingEntry.content = ShaderBinding::TextureBinding{
|
||||||
|
currentTextureOverlay, defaultSampler.get()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderBindingPtr drawDataBinding = currentPipeline->GetPipelineInfo().pipelineLayout->AllocateShaderBinding(0);
|
||||||
|
drawDataBinding->Update(m_bindingCache.data(), m_bindingCache.size());
|
||||||
|
|
||||||
|
currentShaderBinding = drawDataBinding.get();
|
||||||
|
|
||||||
data.shaderBindings.emplace_back(std::move(drawDataBinding));
|
data.shaderBindings.emplace_back(std::move(drawDataBinding));
|
||||||
}
|
}
|
||||||
|
|
@ -199,9 +226,7 @@ namespace Nz
|
||||||
data.drawCalls.push_back(SpriteChainRendererData::DrawCall{
|
data.drawCalls.push_back(SpriteChainRendererData::DrawCall{
|
||||||
currentVertexBuffer,
|
currentVertexBuffer,
|
||||||
currentPipeline,
|
currentPipeline,
|
||||||
currentDrawDataBinding,
|
currentShaderBinding,
|
||||||
currentInstanceBinding,
|
|
||||||
currentMaterialBinding,
|
|
||||||
6 * firstQuadIndex,
|
6 * firstQuadIndex,
|
||||||
0,
|
0,
|
||||||
});
|
});
|
||||||
|
|
@ -255,7 +280,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteChainRenderer::Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t /*elementCount*/)
|
void SpriteChainRenderer::Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t /*elementCount*/)
|
||||||
{
|
{
|
||||||
auto& data = static_cast<SpriteChainRendererData&>(rendererData);
|
auto& data = static_cast<SpriteChainRendererData&>(rendererData);
|
||||||
|
|
||||||
|
|
@ -263,9 +288,9 @@ namespace Nz
|
||||||
|
|
||||||
const AbstractBuffer* currentVertexBuffer = nullptr;
|
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||||
const RenderPipeline* currentPipeline = nullptr;
|
const RenderPipeline* currentPipeline = nullptr;
|
||||||
const ShaderBinding* currentDrawDataBinding = nullptr;
|
const ShaderBinding* currentShaderBinding = nullptr;
|
||||||
const ShaderBinding* currentInstanceBinding = nullptr;
|
const ViewerInstance* currentViewerInstance = nullptr;
|
||||||
const ShaderBinding* currentMaterialBinding = nullptr;
|
const WorldInstance* currentWorldInstance = nullptr;
|
||||||
|
|
||||||
const RenderSpriteChain* firstSpriteChain = static_cast<const RenderSpriteChain*>(elements[0]);
|
const RenderSpriteChain* firstSpriteChain = static_cast<const RenderSpriteChain*>(elements[0]);
|
||||||
auto it = data.drawCallPerElement.find(firstSpriteChain);
|
auto it = data.drawCallPerElement.find(firstSpriteChain);
|
||||||
|
|
@ -289,22 +314,10 @@ namespace Nz
|
||||||
currentPipeline = drawCall.renderPipeline;
|
currentPipeline = drawCall.renderPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentDrawDataBinding != drawCall.drawDataBinding)
|
if (currentShaderBinding != drawCall.shaderBinding)
|
||||||
{
|
{
|
||||||
commandBuffer.BindShaderBinding(Graphics::DrawDataBindingSet, *drawCall.drawDataBinding);
|
commandBuffer.BindShaderBinding(0, *drawCall.shaderBinding);
|
||||||
currentDrawDataBinding = drawCall.drawDataBinding;
|
currentShaderBinding = drawCall.shaderBinding;
|
||||||
}
|
|
||||||
|
|
||||||
if (currentMaterialBinding != drawCall.materialBinding)
|
|
||||||
{
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, *drawCall.materialBinding);
|
|
||||||
currentMaterialBinding = drawCall.materialBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentInstanceBinding != drawCall.instanceBinding)
|
|
||||||
{
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::WorldBindingSet, *drawCall.instanceBinding);
|
|
||||||
currentInstanceBinding = drawCall.instanceBinding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuffer.DrawIndexed(drawCall.quadCount * 6, 1U, drawCall.firstIndex);
|
commandBuffer.DrawIndexed(drawCall.quadCount * 6, 1U, drawCall.firstIndex);
|
||||||
|
|
|
||||||
|
|
@ -5,41 +5,48 @@
|
||||||
#include <Nazara/Graphics/SubmeshRenderer.hpp>
|
#include <Nazara/Graphics/SubmeshRenderer.hpp>
|
||||||
#include <Nazara/Graphics/Graphics.hpp>
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/RenderSubmesh.hpp>
|
#include <Nazara/Graphics/RenderSubmesh.hpp>
|
||||||
|
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||||
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
SubmeshRenderer::SubmeshRenderer()
|
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 std::make_unique<SubmeshRendererData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubmeshRenderer::Render(ElementRendererData& /*rendererData*/, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
void SubmeshRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& /*currentFrame*/, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||||
{
|
{
|
||||||
|
Graphics* graphics = Graphics::Instance();
|
||||||
|
|
||||||
|
auto& data = static_cast<SubmeshRendererData&>(rendererData);
|
||||||
|
|
||||||
const AbstractBuffer* currentIndexBuffer = nullptr;
|
const AbstractBuffer* currentIndexBuffer = nullptr;
|
||||||
const AbstractBuffer* currentVertexBuffer = nullptr;
|
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||||
const RenderPipeline* currentPipeline = nullptr;
|
const RenderPipeline* currentPipeline = nullptr;
|
||||||
const ShaderBinding* currentMaterialBinding = nullptr;
|
const ShaderBinding* currentShaderBinding = nullptr;
|
||||||
|
const WorldInstance* currentWorldInstance = nullptr;
|
||||||
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::DrawDataBindingSet, *m_renderDataBinding);
|
auto FlushDrawCall = [&]()
|
||||||
|
{
|
||||||
|
// Does nothing for now (but will serve once instancing is implemented)
|
||||||
|
};
|
||||||
|
|
||||||
|
auto FlushDrawData = [&]()
|
||||||
|
{
|
||||||
|
FlushDrawCall();
|
||||||
|
|
||||||
|
currentShaderBinding = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)];
|
||||||
|
const auto& defaultSampler = graphics->GetSamplerCache().Get({});
|
||||||
|
|
||||||
for (std::size_t i = 0; i < elementCount; ++i)
|
for (std::size_t i = 0; i < elementCount; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -48,34 +55,139 @@ namespace Nz
|
||||||
|
|
||||||
if (const RenderPipeline* pipeline = submesh.GetRenderPipeline(); currentPipeline != pipeline)
|
if (const RenderPipeline* pipeline = submesh.GetRenderPipeline(); currentPipeline != pipeline)
|
||||||
{
|
{
|
||||||
commandBuffer.BindPipeline(*pipeline);
|
FlushDrawCall();
|
||||||
currentPipeline = pipeline;
|
currentPipeline = pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const ShaderBinding* materialBinding = &submesh.GetMaterialBinding(); currentMaterialBinding != materialBinding)
|
|
||||||
{
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, *materialBinding);
|
|
||||||
currentMaterialBinding = materialBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const AbstractBuffer* indexBuffer = submesh.GetIndexBuffer(); currentIndexBuffer != indexBuffer)
|
if (const AbstractBuffer* indexBuffer = submesh.GetIndexBuffer(); currentIndexBuffer != indexBuffer)
|
||||||
{
|
{
|
||||||
commandBuffer.BindIndexBuffer(*indexBuffer);
|
FlushDrawCall();
|
||||||
currentIndexBuffer = indexBuffer;
|
currentIndexBuffer = indexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const AbstractBuffer* vertexBuffer = submesh.GetVertexBuffer(); currentVertexBuffer != vertexBuffer)
|
if (const AbstractBuffer* vertexBuffer = submesh.GetVertexBuffer(); currentVertexBuffer != vertexBuffer)
|
||||||
{
|
{
|
||||||
commandBuffer.BindVertexBuffer(0, *vertexBuffer);
|
FlushDrawCall();
|
||||||
currentVertexBuffer = vertexBuffer;
|
currentVertexBuffer = vertexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuffer.BindShaderBinding(Graphics::WorldBindingSet, submesh.GetInstanceBinding());
|
if (currentWorldInstance != &submesh.GetWorldInstance())
|
||||||
|
{
|
||||||
|
// TODO: Flushing draw calls on instance binding means we can have e.g. 1000 sprites rendered using a draw call for each one
|
||||||
|
// which is far from being efficient, using some bindless could help (or at least instancing?)
|
||||||
|
FlushDrawData();
|
||||||
|
currentWorldInstance = &submesh.GetWorldInstance();
|
||||||
|
}
|
||||||
|
|
||||||
if (currentIndexBuffer)
|
if (!currentShaderBinding)
|
||||||
commandBuffer.DrawIndexed(submesh.GetIndexCount());
|
{
|
||||||
else
|
m_bindingCache.clear();
|
||||||
commandBuffer.Draw(submesh.GetIndexCount());
|
|
||||||
|
const MaterialPass& materialPass = submesh.GetMaterialPass();
|
||||||
|
materialPass.FillShaderBinding(m_bindingCache);
|
||||||
|
|
||||||
|
// Predefined shader bindings
|
||||||
|
const auto& matSettings = materialPass.GetSettings();
|
||||||
|
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::InstanceDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||||
|
{
|
||||||
|
const auto& instanceBuffer = currentWorldInstance->GetInstanceBuffer();
|
||||||
|
|
||||||
|
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||||
|
bindingEntry.bindingIndex = bindingIndex;
|
||||||
|
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||||
|
instanceBuffer.get(),
|
||||||
|
0, instanceBuffer->GetSize()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::ViewerDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||||
|
{
|
||||||
|
const auto& viewerBuffer = viewerInstance.GetViewerBuffer();
|
||||||
|
|
||||||
|
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||||
|
bindingEntry.bindingIndex = bindingIndex;
|
||||||
|
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||||
|
viewerBuffer.get(),
|
||||||
|
0, viewerBuffer->GetSize()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::OverlayTexture); bindingIndex != MaterialSettings::InvalidIndex)
|
||||||
|
{
|
||||||
|
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||||
|
bindingEntry.bindingIndex = bindingIndex;
|
||||||
|
bindingEntry.content = ShaderBinding::TextureBinding{
|
||||||
|
whiteTexture.get(), defaultSampler.get()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderBindingPtr drawDataBinding = currentPipeline->GetPipelineInfo().pipelineLayout->AllocateShaderBinding(0);
|
||||||
|
drawDataBinding->Update(m_bindingCache.data(), m_bindingCache.size());
|
||||||
|
|
||||||
|
currentShaderBinding = drawDataBinding.get();
|
||||||
|
|
||||||
|
data.shaderBindings.emplace_back(std::move(drawDataBinding));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& drawCall = data.drawCalls.emplace_back();
|
||||||
|
drawCall.indexBuffer = currentIndexBuffer;
|
||||||
|
drawCall.indexCount = submesh.GetIndexCount();
|
||||||
|
drawCall.renderPipeline = currentPipeline;
|
||||||
|
drawCall.shaderBinding = currentShaderBinding;
|
||||||
|
drawCall.vertexBuffer = currentVertexBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SubmeshRenderer::Render(const ViewerInstance& /*viewerInstance*/, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* /*elements*/, std::size_t /*elementCount*/)
|
||||||
|
{
|
||||||
|
auto& data = static_cast<SubmeshRendererData&>(rendererData);
|
||||||
|
|
||||||
|
const AbstractBuffer* currentIndexBuffer = nullptr;
|
||||||
|
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||||
|
const RenderPipeline* currentPipeline = nullptr;
|
||||||
|
const ShaderBinding* currentShaderBinding = nullptr;
|
||||||
|
|
||||||
|
for (const auto& drawData : data.drawCalls)
|
||||||
|
{
|
||||||
|
if (currentPipeline != drawData.renderPipeline)
|
||||||
|
{
|
||||||
|
commandBuffer.BindPipeline(*drawData.renderPipeline);
|
||||||
|
currentPipeline = drawData.renderPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentShaderBinding != drawData.shaderBinding)
|
||||||
|
{
|
||||||
|
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding);
|
||||||
|
currentShaderBinding = drawData.shaderBinding;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentIndexBuffer != drawData.indexBuffer)
|
||||||
|
{
|
||||||
|
commandBuffer.BindIndexBuffer(*drawData.indexBuffer);
|
||||||
|
currentIndexBuffer = drawData.indexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentVertexBuffer != drawData.vertexBuffer)
|
||||||
|
{
|
||||||
|
commandBuffer.BindVertexBuffer(0, *drawData.vertexBuffer);
|
||||||
|
currentVertexBuffer = drawData.vertexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentIndexBuffer)
|
||||||
|
commandBuffer.DrawIndexed(drawData.indexCount);
|
||||||
|
else
|
||||||
|
commandBuffer.Draw(drawData.indexCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubmeshRenderer::Reset(ElementRendererData& rendererData, RenderFrame& currentFrame)
|
||||||
|
{
|
||||||
|
auto& data = static_cast<SubmeshRendererData&>(rendererData);
|
||||||
|
|
||||||
|
for (auto& shaderBinding : data.shaderBindings)
|
||||||
|
currentFrame.PushForRelease(std::move(shaderBinding));
|
||||||
|
data.shaderBindings.clear();
|
||||||
|
|
||||||
|
data.drawCalls.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Nz
|
||||||
|
|
||||||
void TextSprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const
|
void TextSprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const
|
||||||
{
|
{
|
||||||
MaterialPass* materialPass = m_material->GetPass(passIndex);
|
const auto& materialPass = m_material->GetPass(passIndex);
|
||||||
if (!materialPass)
|
if (!materialPass)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace Nz
|
||||||
RenderIndices& indices = pair.second;
|
RenderIndices& indices = pair.second;
|
||||||
|
|
||||||
if (indices.count > 0)
|
if (indices.count > 0)
|
||||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(0, renderPipeline, vertexDeclaration, key.texture->shared_from_this(), indices.count, &m_vertices[indices.first * 4], materialPass->GetShaderBinding(), worldInstance, materialPass->GetFlags()));
|
elements.emplace_back(std::make_unique<RenderSpriteChain>(0, materialPass, renderPipeline, worldInstance, vertexDeclaration, key.texture->shared_from_this(), indices.count, &m_vertices[indices.first * 4]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,49 +14,39 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
ViewerInstance::ViewerInstance() :
|
ViewerInstance::ViewerInstance() :
|
||||||
m_invProjectionMatrix(Nz::Matrix4f::Identity()),
|
m_invProjectionMatrix(Matrix4f::Identity()),
|
||||||
m_invViewProjMatrix(Nz::Matrix4f::Identity()),
|
m_invViewProjMatrix(Matrix4f::Identity()),
|
||||||
m_invViewMatrix(Nz::Matrix4f::Identity()),
|
m_invViewMatrix(Matrix4f::Identity()),
|
||||||
m_projectionMatrix(Nz::Matrix4f::Identity()),
|
m_projectionMatrix(Matrix4f::Identity()),
|
||||||
m_viewProjMatrix(Nz::Matrix4f::Identity()),
|
m_viewProjMatrix(Matrix4f::Identity()),
|
||||||
m_viewMatrix(Nz::Matrix4f::Identity()),
|
m_viewMatrix(Matrix4f::Identity()),
|
||||||
m_targetSize(Nz::Vector2f(0.f, 0.f)),
|
m_targetSize(Vector2f(0.f, 0.f)),
|
||||||
m_dataInvalided(true)
|
m_dataInvalided(true)
|
||||||
{
|
{
|
||||||
Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets();
|
PredefinedViewerData viewerUboOffsets = PredefinedViewerData::GetOffsets();
|
||||||
|
|
||||||
m_viewerDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
m_viewerDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||||
if (!m_viewerDataBuffer->Initialize(viewerUboOffsets.totalSize, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic))
|
if (!m_viewerDataBuffer->Initialize(viewerUboOffsets.totalSize, BufferUsage::DeviceLocal | BufferUsage::Dynamic))
|
||||||
throw std::runtime_error("failed to initialize viewer data UBO");
|
throw std::runtime_error("failed to initialize viewer data UBO");
|
||||||
|
|
||||||
m_shaderBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::ViewerBindingSet);
|
|
||||||
m_shaderBinding->Update({
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
ShaderBinding::UniformBufferBinding {
|
|
||||||
m_viewerDataBuffer.get(), 0, m_viewerDataBuffer->GetSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewerInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
void ViewerInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
||||||
{
|
{
|
||||||
if (m_dataInvalided)
|
if (m_dataInvalided)
|
||||||
{
|
{
|
||||||
Nz::PredefinedViewerData viewerDataOffsets = Nz::PredefinedViewerData::GetOffsets();
|
PredefinedViewerData viewerDataOffsets = PredefinedViewerData::GetOffsets();
|
||||||
|
|
||||||
auto& allocation = uploadPool.Allocate(viewerDataOffsets.totalSize);
|
auto& allocation = uploadPool.Allocate(viewerDataOffsets.totalSize);
|
||||||
Nz::AccessByOffset<Nz::Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation();
|
AccessByOffset<Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation();
|
||||||
Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize;
|
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize;
|
||||||
Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize;
|
AccessByOffset<Vector2f&>(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize;
|
||||||
|
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invProjMatrixOffset) = m_invProjectionMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invProjMatrixOffset) = m_invProjectionMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewMatrixOffset) = m_invViewMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewMatrixOffset) = m_invViewMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewProjMatrixOffset) = m_invViewProjMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewProjMatrixOffset) = m_invViewProjMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.projMatrixOffset) = m_projectionMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.projMatrixOffset) = m_projectionMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewProjMatrixOffset) = m_viewProjMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewProjMatrixOffset) = m_viewProjMatrix;
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewMatrixOffset) = m_viewMatrix;
|
AccessByOffset<Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewMatrixOffset) = m_viewMatrix;
|
||||||
|
|
||||||
builder.CopyBuffer(allocation, m_viewerDataBuffer.get());
|
builder.CopyBuffer(allocation, m_viewerDataBuffer.get());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,25 +14,15 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
WorldInstance::WorldInstance() :
|
WorldInstance::WorldInstance() :
|
||||||
m_invWorldMatrix(Nz::Matrix4f::Identity()),
|
m_invWorldMatrix(Matrix4f::Identity()),
|
||||||
m_worldMatrix(Nz::Matrix4f::Identity()),
|
m_worldMatrix(Matrix4f::Identity()),
|
||||||
m_dataInvalided(true)
|
m_dataInvalided(true)
|
||||||
{
|
{
|
||||||
PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets();
|
PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets();
|
||||||
|
|
||||||
m_instanceDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
m_instanceDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||||
if (!m_instanceDataBuffer->Initialize(instanceUboOffsets.totalSize, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic))
|
if (!m_instanceDataBuffer->Initialize(instanceUboOffsets.totalSize, BufferUsage::DeviceLocal | BufferUsage::Dynamic))
|
||||||
throw std::runtime_error("failed to initialize viewer data UBO");
|
throw std::runtime_error("failed to initialize viewer data UBO");
|
||||||
|
|
||||||
m_shaderBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::WorldBindingSet);
|
|
||||||
m_shaderBinding->Update({
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
ShaderBinding::UniformBufferBinding {
|
|
||||||
m_instanceDataBuffer.get(), 0, m_instanceDataBuffer->GetSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
void WorldInstance::UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder)
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,11 @@ namespace Nz
|
||||||
switch (params.type)
|
switch (params.type)
|
||||||
{
|
{
|
||||||
case ImageType::E1D:
|
case ImageType::E1D:
|
||||||
|
m_texture.TexStorage2D(GL::TextureTarget::Target2D, params.mipmapLevel, format->internalFormat, params.width, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E1D_Array:
|
case ImageType::E1D_Array:
|
||||||
|
m_texture.TexStorage2D(GL::TextureTarget::Target2D, params.mipmapLevel, format->internalFormat, params.width, params.height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E2D:
|
case ImageType::E2D:
|
||||||
|
|
@ -36,17 +38,16 @@ namespace Nz
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E2D_Array:
|
case ImageType::E2D_Array:
|
||||||
|
m_texture.TexStorage3D(GL::TextureTarget::Target2D_Array, params.mipmapLevel, format->internalFormat, params.width, params.height, params.depth);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E3D:
|
case ImageType::E3D:
|
||||||
|
m_texture.TexStorage3D(GL::TextureTarget::Target3D, params.mipmapLevel, format->internalFormat, params.width, params.height, params.depth);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::Cubemap:
|
case ImageType::Cubemap:
|
||||||
m_texture.TexStorage2D(GL::TextureTarget::Cubemap, params.mipmapLevel, format->internalFormat, params.width, params.height);
|
m_texture.TexStorage2D(GL::TextureTarget::Cubemap, params.mipmapLevel, format->internalFormat, params.width, params.height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.DidLastCallSucceed())
|
if (!context.DidLastCallSucceed())
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ namespace Nz
|
||||||
std::array<Vector2f, circleVerticesCount> vertices;
|
std::array<Vector2f, circleVerticesCount> vertices;
|
||||||
|
|
||||||
Vector2f origin = FromChipmunk(pos);
|
Vector2f origin = FromChipmunk(pos);
|
||||||
float r = static_cast<float>(radius);
|
float r = SafeCast<float>(radius);
|
||||||
|
|
||||||
RadianAnglef angleBetweenVertices = 2.f * Pi<float> / vertices.size();
|
RadianAnglef angleBetweenVertices = 2.f * Pi<float> / vertices.size();
|
||||||
for (std::size_t i = 0; i < vertices.size(); ++i)
|
for (std::size_t i = 0; i < vertices.size(); ++i)
|
||||||
|
|
@ -91,7 +91,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const auto& callback = *static_cast<const CallbackType*>(userdata);
|
const auto& callback = *static_cast<const CallbackType*>(userdata);
|
||||||
|
|
||||||
static std::pair<float, float> sincos = Nz::DegreeAnglef(90.f).GetSinCos();
|
static std::pair<float, float> sincos = DegreeAnglef(90.f).GetSinCos();
|
||||||
|
|
||||||
Vector2f from = FromChipmunk(a);
|
Vector2f from = FromChipmunk(a);
|
||||||
Vector2f to = FromChipmunk(b);
|
Vector2f to = FromChipmunk(b);
|
||||||
|
|
@ -100,7 +100,7 @@ namespace Nz
|
||||||
Vector2f thicknessNormal(sincos.second * normal.x - sincos.first * normal.y,
|
Vector2f thicknessNormal(sincos.second * normal.x - sincos.first * normal.y,
|
||||||
sincos.first * normal.x + sincos.second * normal.y);
|
sincos.first * normal.x + sincos.second * normal.y);
|
||||||
|
|
||||||
float thickness = static_cast<float>(radius);
|
float thickness = SafeCast<float>(radius);
|
||||||
|
|
||||||
std::array<Vector2f, 4> vertices;
|
std::array<Vector2f, 4> vertices;
|
||||||
vertices[0] = from + thickness * thicknessNormal;
|
vertices[0] = from + thickness * thicknessNormal;
|
||||||
|
|
@ -166,14 +166,14 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::Vector2f BoxCollider2D::ComputeCenterOfMass() const
|
Vector2f BoxCollider2D::ComputeCenterOfMass() const
|
||||||
{
|
{
|
||||||
return m_rect.GetCenter();
|
return m_rect.GetCenter();
|
||||||
}
|
}
|
||||||
|
|
||||||
float BoxCollider2D::ComputeMomentOfInertia(float mass) const
|
float BoxCollider2D::ComputeMomentOfInertia(float mass) const
|
||||||
{
|
{
|
||||||
return static_cast<float>(cpMomentForBox2(mass, cpBBNew(m_rect.x, m_rect.y, m_rect.x + m_rect.width, m_rect.y + m_rect.height)));
|
return SafeCast<float>(cpMomentForBox2(mass, cpBBNew(m_rect.x, m_rect.y, m_rect.x + m_rect.width, m_rect.y + m_rect.height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ColliderType2D BoxCollider2D::GetType() const
|
ColliderType2D BoxCollider2D::GetType() const
|
||||||
|
|
@ -195,14 +195,14 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::Vector2f CircleCollider2D::ComputeCenterOfMass() const
|
Vector2f CircleCollider2D::ComputeCenterOfMass() const
|
||||||
{
|
{
|
||||||
return m_offset;
|
return m_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CircleCollider2D::ComputeMomentOfInertia(float mass) const
|
float CircleCollider2D::ComputeMomentOfInertia(float mass) const
|
||||||
{
|
{
|
||||||
return static_cast<float>(cpMomentForCircle(mass, 0.f, m_radius, cpv(m_offset.x, m_offset.y)));
|
return SafeCast<float>(cpMomentForCircle(mass, 0.f, m_radius, cpv(m_offset.x, m_offset.y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ColliderType2D CircleCollider2D::GetType() const
|
ColliderType2D CircleCollider2D::GetType() const
|
||||||
|
|
@ -224,9 +224,9 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::Vector2f CompoundCollider2D::ComputeCenterOfMass() const
|
Vector2f CompoundCollider2D::ComputeCenterOfMass() const
|
||||||
{
|
{
|
||||||
Nz::Vector2f centerOfMass = Nz::Vector2f::Zero();
|
Vector2f centerOfMass = Vector2f::Zero();
|
||||||
for (const auto& geom : m_geoms)
|
for (const auto& geom : m_geoms)
|
||||||
centerOfMass += geom->ComputeCenterOfMass();
|
centerOfMass += geom->ComputeCenterOfMass();
|
||||||
|
|
||||||
|
|
@ -285,20 +285,20 @@ namespace Nz
|
||||||
m_vertices[i].Set(*vertices++);
|
m_vertices[i].Set(*vertices++);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::Vector2f ConvexCollider2D::ComputeCenterOfMass() const
|
Vector2f ConvexCollider2D::ComputeCenterOfMass() const
|
||||||
{
|
{
|
||||||
static_assert(sizeof(cpVect) == sizeof(Vector2d), "Chipmunk vector is not equivalent to Vector2d");
|
static_assert(sizeof(cpVect) == sizeof(Vector2d), "Chipmunk vector is not equivalent to Vector2d");
|
||||||
|
|
||||||
cpVect center = cpCentroidForPoly(int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()));
|
cpVect center = cpCentroidForPoly(int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()));
|
||||||
|
|
||||||
return Nz::Vector2f(float(center.x), float(center.y));
|
return Vector2f(float(center.x), float(center.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
float ConvexCollider2D::ComputeMomentOfInertia(float mass) const
|
float ConvexCollider2D::ComputeMomentOfInertia(float mass) const
|
||||||
{
|
{
|
||||||
static_assert(sizeof(cpVect) == sizeof(Vector2d), "Chipmunk vector is not equivalent to Vector2d");
|
static_assert(sizeof(cpVect) == sizeof(Vector2d), "Chipmunk vector is not equivalent to Vector2d");
|
||||||
|
|
||||||
return static_cast<float>(cpMomentForPoly(mass, int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()), cpv(0.0, 0.0), m_radius));
|
return SafeCast<float>(cpMomentForPoly(mass, int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()), cpv(0.0, 0.0), m_radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
ColliderType2D ConvexCollider2D::GetType() const
|
ColliderType2D ConvexCollider2D::GetType() const
|
||||||
|
|
@ -319,9 +319,9 @@ namespace Nz
|
||||||
return ColliderType2D::Null;
|
return ColliderType2D::Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::Vector2f NullCollider2D::ComputeCenterOfMass() const
|
Vector2f NullCollider2D::ComputeCenterOfMass() const
|
||||||
{
|
{
|
||||||
return Nz::Vector2f::Zero();
|
return Vector2f::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
float NullCollider2D::ComputeMomentOfInertia(float mass) const
|
float NullCollider2D::ComputeMomentOfInertia(float mass) const
|
||||||
|
|
@ -336,14 +336,14 @@ namespace Nz
|
||||||
|
|
||||||
/******************************** SegmentCollider2D *********************************/
|
/******************************** SegmentCollider2D *********************************/
|
||||||
|
|
||||||
Nz::Vector2f SegmentCollider2D::ComputeCenterOfMass() const
|
Vector2f SegmentCollider2D::ComputeCenterOfMass() const
|
||||||
{
|
{
|
||||||
return (m_first + m_second) / 2.f;
|
return (m_first + m_second) / 2.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SegmentCollider2D::ComputeMomentOfInertia(float mass) const
|
float SegmentCollider2D::ComputeMomentOfInertia(float mass) const
|
||||||
{
|
{
|
||||||
return static_cast<float>(cpMomentForSegment(mass, cpv(m_first.x, m_first.y), cpv(m_second.x, m_second.y), m_thickness));
|
return SafeCast<float>(cpMomentForSegment(mass, cpv(m_first.x, m_first.y), cpv(m_second.x, m_second.y), m_thickness));
|
||||||
}
|
}
|
||||||
|
|
||||||
ColliderType2D SegmentCollider2D::GetType() const
|
ColliderType2D SegmentCollider2D::GetType() const
|
||||||
|
|
|
||||||
|
|
@ -145,38 +145,38 @@ namespace Nz
|
||||||
|
|
||||||
std::shared_ptr<StaticMesh> Collider3D::GenerateMesh() const
|
std::shared_ptr<StaticMesh> Collider3D::GenerateMesh() const
|
||||||
{
|
{
|
||||||
std::vector<Nz::Vector3f> colliderVertices;
|
std::vector<Vector3f> colliderVertices;
|
||||||
std::vector<Nz::UInt16> colliderIndices;
|
std::vector<UInt16> colliderIndices;
|
||||||
|
|
||||||
// Generate a line list
|
// Generate a line list
|
||||||
ForEachPolygon([&](const Nz::Vector3f* vertices, std::size_t vertexCount)
|
ForEachPolygon([&](const Vector3f* vertices, std::size_t vertexCount)
|
||||||
{
|
{
|
||||||
Nz::UInt16 firstIndex = colliderVertices.size();
|
UInt16 firstIndex = SafeCast<UInt16>(colliderVertices.size());
|
||||||
for (std::size_t i = 0; i < vertexCount; ++i)
|
for (std::size_t i = 0; i < vertexCount; ++i)
|
||||||
colliderVertices.push_back(vertices[i]);
|
colliderVertices.push_back(vertices[i]);
|
||||||
|
|
||||||
for (std::size_t i = 1; i < vertexCount; ++i)
|
for (std::size_t i = 1; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
colliderIndices.push_back(firstIndex + i - 1);
|
colliderIndices.push_back(SafeCast<UInt16>(firstIndex + i - 1));
|
||||||
colliderIndices.push_back(firstIndex + i);
|
colliderIndices.push_back(SafeCast<UInt16>(firstIndex + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vertexCount > 2)
|
if (vertexCount > 2)
|
||||||
{
|
{
|
||||||
colliderIndices.push_back(firstIndex + vertexCount - 1);
|
colliderIndices.push_back(SafeCast<UInt16>(firstIndex + vertexCount - 1));
|
||||||
colliderIndices.push_back(firstIndex);
|
colliderIndices.push_back(SafeCast<UInt16>(firstIndex));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
std::shared_ptr<Nz::VertexBuffer> colliderVB = std::make_shared<Nz::VertexBuffer>(Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ), colliderVertices.size(), Nz::DataStorage::Software, 0);
|
std::shared_ptr<VertexBuffer> colliderVB = std::make_shared<VertexBuffer>(VertexDeclaration::Get(VertexLayout::XYZ), colliderVertices.size(), DataStorage::Software, 0);
|
||||||
colliderVB->Fill(colliderVertices.data(), 0, colliderVertices.size());
|
colliderVB->Fill(colliderVertices.data(), 0, colliderVertices.size());
|
||||||
|
|
||||||
std::shared_ptr<Nz::IndexBuffer> colliderIB = std::make_shared<Nz::IndexBuffer>(false, colliderIndices.size(), Nz::DataStorage::Software, 0);
|
std::shared_ptr<IndexBuffer> colliderIB = std::make_shared<IndexBuffer>(false, colliderIndices.size(), DataStorage::Software, 0);
|
||||||
colliderIB->Fill(colliderIndices.data(), 0, colliderIndices.size());
|
colliderIB->Fill(colliderIndices.data(), 0, colliderIndices.size());
|
||||||
|
|
||||||
std::shared_ptr<Nz::StaticMesh> colliderSubMesh = std::make_shared<Nz::StaticMesh>(std::move(colliderVB), std::move(colliderIB));
|
std::shared_ptr<StaticMesh> colliderSubMesh = std::make_shared<StaticMesh>(std::move(colliderVB), std::move(colliderIB));
|
||||||
colliderSubMesh->GenerateAABB();
|
colliderSubMesh->GenerateAABB();
|
||||||
colliderSubMesh->SetPrimitiveMode(Nz::PrimitiveMode::LineList);
|
colliderSubMesh->SetPrimitiveMode(PrimitiveMode::LineList);
|
||||||
|
|
||||||
return colliderSubMesh;
|
return colliderSubMesh;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -325,18 +325,6 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entt::registry& BaseWidget::GetRegistry()
|
|
||||||
{
|
|
||||||
assert(m_registry);
|
|
||||||
return *m_registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const entt::registry& BaseWidget::GetRegistry() const
|
|
||||||
{
|
|
||||||
assert(m_registry);
|
|
||||||
return *m_registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseWidget::ShowChildren(bool show)
|
void BaseWidget::ShowChildren(bool show)
|
||||||
{
|
{
|
||||||
for (const auto& widgetPtr : m_children)
|
for (const auto& widgetPtr : m_children)
|
||||||
|
|
|
||||||
|
|
@ -528,7 +528,6 @@ Nz::ShaderAst::StatementPtr ShaderGraph::ToAst() const
|
||||||
statements.push_back(Nz::ShaderBuilder::DeclareStruct(std::move(structDesc)));
|
statements.push_back(Nz::ShaderBuilder::DeclareStruct(std::move(structDesc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderAst::ExpressionType returnType;
|
|
||||||
if (!m_outputs.empty())
|
if (!m_outputs.empty())
|
||||||
{
|
{
|
||||||
Nz::ShaderAst::StructDescription structDesc;
|
Nz::ShaderAst::StructDescription structDesc;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue