Graphics/Widgets: Add support for scissoring
This commit is contained in:
parent
a483e16e15
commit
61779d1cad
|
|
@ -231,6 +231,8 @@ namespace Nz
|
|||
// Convert it back to int
|
||||
m_viewport.Set(fViewport);
|
||||
|
||||
m_viewerInstance.UpdateTargetSize(fViewport.GetLengths());
|
||||
|
||||
UpdateProjectionMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,10 @@ namespace Nz
|
|||
virtual const std::shared_ptr<Material>& GetMaterial(std::size_t i) const = 0;
|
||||
virtual std::size_t GetMaterialCount() const = 0;
|
||||
inline int GetRenderLayer() const;
|
||||
inline const Recti& GetScissorBox() const;
|
||||
|
||||
inline void UpdateRenderLayer(int renderLayer);
|
||||
inline void UpdateScissorBox(const Recti& scissorBox);
|
||||
|
||||
InstancedRenderable& operator=(const InstancedRenderable&) = delete;
|
||||
InstancedRenderable& operator=(InstancedRenderable&&) noexcept = default;
|
||||
|
|
@ -49,6 +51,7 @@ namespace Nz
|
|||
|
||||
private:
|
||||
Boxf m_aabb;
|
||||
Recti m_scissorBox;
|
||||
int m_renderLayer;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ namespace Nz
|
|||
return m_renderLayer;
|
||||
}
|
||||
|
||||
inline const Recti& InstancedRenderable::GetScissorBox() const
|
||||
{
|
||||
return m_scissorBox;
|
||||
}
|
||||
|
||||
inline void InstancedRenderable::UpdateRenderLayer(int renderLayer)
|
||||
{
|
||||
if (m_renderLayer != renderLayer)
|
||||
|
|
@ -32,6 +37,15 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
inline void InstancedRenderable::UpdateScissorBox(const Recti& scissorBox)
|
||||
{
|
||||
if (m_scissorBox != scissorBox)
|
||||
{
|
||||
m_scissorBox = scissorBox;
|
||||
OnElementInvalidated(this);
|
||||
}
|
||||
}
|
||||
|
||||
inline void InstancedRenderable::UpdateAABB(Boxf aabb)
|
||||
{
|
||||
OnAABBUpdate(this, aabb);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ namespace Nz
|
|||
|
||||
std::shared_ptr<GraphicalMesh> m_graphicalMesh;
|
||||
std::vector<SubMeshData> m_submeshes;
|
||||
Recti m_scissorBox;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#define NAZARA_GRAPHICS_RENDERSPRITECHAIN_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||
|
|
@ -25,13 +24,14 @@ namespace Nz
|
|||
class RenderSpriteChain : public RenderElement
|
||||
{
|
||||
public:
|
||||
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);
|
||||
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, const Recti& scissorBox);
|
||||
~RenderSpriteChain() = default;
|
||||
|
||||
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
||||
|
||||
inline const MaterialPass& GetMaterialPass() const;
|
||||
inline const RenderPipeline& GetRenderPipeline() const;
|
||||
inline const Recti& GetScissorBox() const;
|
||||
inline std::size_t GetSpriteCount() const;
|
||||
inline const void* GetSpriteData() const;
|
||||
inline const Texture* GetTextureOverlay() const;
|
||||
|
|
@ -48,6 +48,7 @@ namespace Nz
|
|||
std::size_t m_spriteCount;
|
||||
const void* m_spriteData;
|
||||
const WorldInstance& m_worldInstance;
|
||||
Recti m_scissorBox;
|
||||
int m_renderLayer;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@
|
|||
|
||||
#include <Nazara/Graphics/RenderSpriteChain.hpp>
|
||||
#include <Nazara/Graphics/Algorithm.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
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) :
|
||||
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, const Recti& scissorBox) :
|
||||
RenderElement(BasicRenderElement::SpriteChain),
|
||||
m_materialPass(std::move(materialPass)),
|
||||
m_renderPipeline(std::move(renderPipeline)),
|
||||
|
|
@ -17,6 +18,7 @@ namespace Nz
|
|||
m_spriteCount(spriteCount),
|
||||
m_spriteData(spriteData),
|
||||
m_worldInstance(worldInstance),
|
||||
m_scissorBox(scissorBox),
|
||||
m_renderLayer(renderLayer)
|
||||
{
|
||||
}
|
||||
|
|
@ -34,8 +36,9 @@ namespace Nz
|
|||
|
||||
// Transparent RQ index:
|
||||
// - Layer (8bits)
|
||||
// - Transparent flag (1bit)
|
||||
// - Distance to near plane (32bits)
|
||||
// - Sorted by distance flag (1bit)
|
||||
// - Distance to near plane (32bits) - could by reduced to 24 or even 16 if required
|
||||
// - ?? (23bits)
|
||||
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(matFlags) << 52 |
|
||||
|
|
@ -53,7 +56,7 @@ namespace Nz
|
|||
|
||||
// Opaque RQ index:
|
||||
// - Layer (8bits)
|
||||
// - Transparent flag (1bit)
|
||||
// - Sorted by distance flag (1bit)
|
||||
// - Element type (4bits)
|
||||
// - Pipeline (16bits)
|
||||
// - MaterialPass (16bits)
|
||||
|
|
@ -79,6 +82,11 @@ namespace Nz
|
|||
return *m_renderPipeline;
|
||||
}
|
||||
|
||||
inline const Recti& RenderSpriteChain::GetScissorBox() const
|
||||
{
|
||||
return m_scissorBox;
|
||||
}
|
||||
|
||||
inline std::size_t RenderSpriteChain::GetSpriteCount() const
|
||||
{
|
||||
return m_spriteCount;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Nz
|
|||
class RenderSubmesh : public RenderElement
|
||||
{
|
||||
public:
|
||||
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);
|
||||
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, const Recti& scissorBox);
|
||||
~RenderSubmesh() = default;
|
||||
|
||||
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
||||
|
|
@ -33,6 +33,7 @@ namespace Nz
|
|||
inline std::size_t GetIndexCount() const;
|
||||
inline const MaterialPass& GetMaterialPass() const;
|
||||
inline const RenderPipeline* GetRenderPipeline() const;
|
||||
inline const Recti& GetScissorBox() const;
|
||||
inline const AbstractBuffer* GetVertexBuffer() const;
|
||||
inline const WorldInstance& GetWorldInstance() const;
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ namespace Nz
|
|||
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
||||
std::size_t m_indexCount;
|
||||
const WorldInstance& m_worldInstance;
|
||||
Recti m_scissorBox;
|
||||
int m_renderLayer;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
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) :
|
||||
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, const Recti& scissorBox) :
|
||||
RenderElement(BasicRenderElement::Submesh),
|
||||
m_indexBuffer(std::move(indexBuffer)),
|
||||
m_vertexBuffer(std::move(vertexBuffer)),
|
||||
|
|
@ -17,6 +17,7 @@ namespace Nz
|
|||
m_renderPipeline(std::move(renderPipeline)),
|
||||
m_indexCount(indexCount),
|
||||
m_worldInstance(worldInstance),
|
||||
m_scissorBox(scissorBox),
|
||||
m_renderLayer(renderLayer)
|
||||
{
|
||||
}
|
||||
|
|
@ -34,8 +35,9 @@ namespace Nz
|
|||
|
||||
// Transparent RQ index:
|
||||
// - Layer (8bits)
|
||||
// - Transparent flag (1bit)
|
||||
// - Distance to near plane (32bits)
|
||||
// - Sorted by distance flag (1bit)
|
||||
// - Distance to near plane (32bits) - could by reduced to 24 or even 16 if required
|
||||
// - ?? (23bits)
|
||||
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(matFlags) << 52 |
|
||||
|
|
@ -52,7 +54,7 @@ namespace Nz
|
|||
|
||||
// Opaque RQ index:
|
||||
// - Layer (8bits)
|
||||
// - Transparent flag (1bit)
|
||||
// - Sorted by distance flag (1bit)
|
||||
// - Element type (4bits)
|
||||
// - Pipeline (16bits)
|
||||
// - MaterialPass (16bits)
|
||||
|
|
@ -88,6 +90,11 @@ namespace Nz
|
|||
return m_renderPipeline.get();
|
||||
}
|
||||
|
||||
inline const Recti& RenderSubmesh::GetScissorBox() const
|
||||
{
|
||||
return m_scissorBox;
|
||||
}
|
||||
|
||||
inline const AbstractBuffer* RenderSubmesh::GetVertexBuffer() const
|
||||
{
|
||||
return m_vertexBuffer.get();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
#include <Nazara/Renderer/UploadPool.hpp>
|
||||
#include <memory>
|
||||
|
|
@ -65,6 +66,7 @@ namespace Nz
|
|||
const ShaderBinding* shaderBinding;
|
||||
std::size_t firstIndex;
|
||||
std::size_t quadCount;
|
||||
Recti scissorBox;
|
||||
};
|
||||
|
||||
struct DrawCallIndices
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -41,6 +42,7 @@ namespace Nz
|
|||
const RenderPipeline* renderPipeline;
|
||||
const ShaderBinding* shaderBinding;
|
||||
std::size_t indexCount;
|
||||
Recti scissorBox;
|
||||
};
|
||||
|
||||
std::vector<DrawCall> drawCalls;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ namespace Nz
|
|||
std::shared_ptr<Material> m_material;
|
||||
std::vector<RenderData> m_data;
|
||||
std::vector<VertexStruct_XYZ_Color_UV> m_vertices;
|
||||
Recti m_scissorBox;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace Nz
|
|||
inline const Matrix4f& GetInvViewMatrix() const;
|
||||
inline const Matrix4f& GetInvViewProjMatrix() const;
|
||||
inline const Matrix4f& GetProjectionMatrix() const;
|
||||
inline const Vector2f& GetTargetSize() const;
|
||||
inline const Matrix4f& GetViewMatrix() const;
|
||||
inline const Matrix4f& GetViewProjMatrix() const;
|
||||
inline std::shared_ptr<AbstractBuffer>& GetViewerBuffer();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ namespace Nz
|
|||
return m_projectionMatrix;
|
||||
}
|
||||
|
||||
inline const Vector2f& ViewerInstance::GetTargetSize() const
|
||||
{
|
||||
return m_targetSize;
|
||||
}
|
||||
|
||||
inline const Matrix4f& ViewerInstance::GetViewMatrix() const
|
||||
{
|
||||
return m_viewMatrix;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace Nz
|
|||
const auto& vertexBuffer = m_graphicalMesh->GetVertexBuffer(i);
|
||||
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(submeshData.vertexBufferData);
|
||||
|
||||
elements.emplace_back(std::make_unique<RenderSubmesh>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, m_graphicalMesh->GetIndexCount(i), indexBuffer, vertexBuffer));
|
||||
elements.emplace_back(std::make_unique<RenderSubmesh>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, m_graphicalMesh->GetIndexCount(i), indexBuffer, vertexBuffer, GetScissorBox()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace Nz
|
|||
|
||||
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)];
|
||||
|
||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, m_spriteCount, m_vertices.data()));
|
||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, m_spriteCount, m_vertices.data(), GetScissorBox()));
|
||||
}
|
||||
|
||||
const std::shared_ptr<Material>& SlicedSprite::GetMaterial(std::size_t i) const
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace Nz
|
|||
|
||||
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)];
|
||||
|
||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, 1, m_vertices.data()));
|
||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, 1, m_vertices.data(), GetScissorBox()));
|
||||
}
|
||||
|
||||
const std::shared_ptr<Material>& Sprite::GetMaterial(std::size_t i) const
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ namespace Nz
|
|||
|
||||
auto& data = static_cast<SpriteChainRendererData&>(rendererData);
|
||||
|
||||
Recti invalidScissorBox(-1, -1, -1, -1);
|
||||
|
||||
std::size_t firstQuadIndex = 0;
|
||||
SpriteChainRendererData::DrawCall* currentDrawCall = nullptr;
|
||||
UploadPool::Allocation* currentAllocation = nullptr;
|
||||
|
|
@ -70,6 +72,7 @@ namespace Nz
|
|||
const ShaderBinding* currentShaderBinding = nullptr;
|
||||
const Texture* currentTextureOverlay = nullptr;
|
||||
const WorldInstance* currentWorldInstance = nullptr;
|
||||
Recti currentScissorBox = invalidScissorBox;
|
||||
|
||||
auto FlushDrawCall = [&]()
|
||||
{
|
||||
|
|
@ -149,6 +152,14 @@ namespace Nz
|
|||
currentTextureOverlay = textureOverlay;
|
||||
}
|
||||
|
||||
const Recti& scissorBox = spriteChain.GetScissorBox();
|
||||
const Recti& targetScissorBox = (scissorBox.width >= 0) ? scissorBox : invalidScissorBox;
|
||||
if (currentScissorBox != targetScissorBox)
|
||||
{
|
||||
FlushDrawData();
|
||||
currentScissorBox = targetScissorBox;
|
||||
}
|
||||
|
||||
std::size_t remainingQuads = spriteChain.GetSpriteCount();
|
||||
const UInt8* spriteData = static_cast<const UInt8*>(spriteChain.GetSpriteData());
|
||||
|
||||
|
|
@ -236,6 +247,7 @@ namespace Nz
|
|||
currentShaderBinding,
|
||||
6 * firstQuadIndex,
|
||||
0,
|
||||
currentScissorBox
|
||||
});
|
||||
|
||||
currentDrawCall = &data.drawCalls.back();
|
||||
|
|
@ -287,15 +299,19 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void SpriteChainRenderer::Render(const ViewerInstance& /*viewerInstance*/, 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);
|
||||
|
||||
commandBuffer.BindIndexBuffer(*m_indexBuffer);
|
||||
|
||||
Vector2f targetSize = viewerInstance.GetTargetSize();
|
||||
Recti fullscreenScissorBox(0, 0, SafeCast<int>(std::floor(targetSize.x)), SafeCast<int>(std::floor(targetSize.y)));
|
||||
|
||||
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||
const RenderPipeline* currentPipeline = nullptr;
|
||||
const ShaderBinding* currentShaderBinding = nullptr;
|
||||
Recti currentScissorBox(-1, -1, -1, -1);
|
||||
|
||||
const RenderSpriteChain* firstSpriteChain = static_cast<const RenderSpriteChain*>(elements[0]);
|
||||
auto it = data.drawCallPerElement.find(firstSpriteChain);
|
||||
|
|
@ -305,27 +321,34 @@ namespace Nz
|
|||
|
||||
for (std::size_t i = 0; i < indices.count; ++i)
|
||||
{
|
||||
const auto& drawCall = data.drawCalls[indices.start + i];
|
||||
const auto& drawData = data.drawCalls[indices.start + i];
|
||||
|
||||
if (currentVertexBuffer != drawCall.vertexBuffer)
|
||||
if (currentVertexBuffer != drawData.vertexBuffer)
|
||||
{
|
||||
commandBuffer.BindVertexBuffer(0, *drawCall.vertexBuffer);
|
||||
currentVertexBuffer = drawCall.vertexBuffer;
|
||||
commandBuffer.BindVertexBuffer(0, *drawData.vertexBuffer);
|
||||
currentVertexBuffer = drawData.vertexBuffer;
|
||||
}
|
||||
|
||||
if (currentPipeline != drawCall.renderPipeline)
|
||||
if (currentPipeline != drawData.renderPipeline)
|
||||
{
|
||||
commandBuffer.BindPipeline(*drawCall.renderPipeline);
|
||||
currentPipeline = drawCall.renderPipeline;
|
||||
commandBuffer.BindPipeline(*drawData.renderPipeline);
|
||||
currentPipeline = drawData.renderPipeline;
|
||||
}
|
||||
|
||||
if (currentShaderBinding != drawCall.shaderBinding)
|
||||
if (currentShaderBinding != drawData.shaderBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(0, *drawCall.shaderBinding);
|
||||
currentShaderBinding = drawCall.shaderBinding;
|
||||
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding);
|
||||
currentShaderBinding = drawData.shaderBinding;
|
||||
}
|
||||
|
||||
commandBuffer.DrawIndexed(drawCall.quadCount * 6, 1U, drawCall.firstIndex);
|
||||
const Recti& targetScissorBox = (drawData.scissorBox.width >= 0) ? drawData.scissorBox : fullscreenScissorBox;
|
||||
if (currentScissorBox != targetScissorBox)
|
||||
{
|
||||
commandBuffer.SetScissor(targetScissorBox);
|
||||
currentScissorBox = targetScissorBox;
|
||||
}
|
||||
|
||||
commandBuffer.DrawIndexed(SafeCast<UInt32>(drawData.quadCount * 6), 1U, SafeCast<UInt32>(drawData.firstIndex));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,15 @@ namespace Nz
|
|||
|
||||
auto& data = static_cast<SubmeshRendererData&>(rendererData);
|
||||
|
||||
Recti invalidScissorBox(-1, -1, -1, -1);
|
||||
|
||||
const AbstractBuffer* currentIndexBuffer = nullptr;
|
||||
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||
const MaterialPass* currentMaterialPass = nullptr;
|
||||
const RenderPipeline* currentPipeline = nullptr;
|
||||
const ShaderBinding* currentShaderBinding = nullptr;
|
||||
const WorldInstance* currentWorldInstance = nullptr;
|
||||
Recti currentScissorBox = invalidScissorBox;
|
||||
|
||||
auto FlushDrawCall = [&]()
|
||||
{
|
||||
|
|
@ -86,6 +89,14 @@ namespace Nz
|
|||
currentWorldInstance = worldInstance;
|
||||
}
|
||||
|
||||
const Recti& scissorBox = submesh.GetScissorBox();
|
||||
const Recti& targetScissorBox = (scissorBox.width >= 0) ? scissorBox : invalidScissorBox;
|
||||
if (currentScissorBox != targetScissorBox)
|
||||
{
|
||||
FlushDrawData();
|
||||
currentScissorBox = targetScissorBox;
|
||||
}
|
||||
|
||||
if (!currentShaderBinding)
|
||||
{
|
||||
m_bindingCache.clear();
|
||||
|
|
@ -140,19 +151,24 @@ namespace Nz
|
|||
drawCall.indexBuffer = currentIndexBuffer;
|
||||
drawCall.indexCount = submesh.GetIndexCount();
|
||||
drawCall.renderPipeline = currentPipeline;
|
||||
drawCall.scissorBox = currentScissorBox;
|
||||
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*/)
|
||||
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);
|
||||
|
||||
Vector2f targetSize = viewerInstance.GetTargetSize();
|
||||
Recti fullscreenScissorBox(0, 0, SafeCast<int>(std::floor(targetSize.x)), SafeCast<int>(std::floor(targetSize.y)));
|
||||
|
||||
const AbstractBuffer* currentIndexBuffer = nullptr;
|
||||
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||
const RenderPipeline* currentPipeline = nullptr;
|
||||
const ShaderBinding* currentShaderBinding = nullptr;
|
||||
Recti currentScissorBox(-1, -1, -1, -1);
|
||||
|
||||
for (const auto& drawData : data.drawCalls)
|
||||
{
|
||||
|
|
@ -180,10 +196,17 @@ namespace Nz
|
|||
currentVertexBuffer = drawData.vertexBuffer;
|
||||
}
|
||||
|
||||
const Recti& targetScissorBox = (drawData.scissorBox.width >= 0) ? drawData.scissorBox : fullscreenScissorBox;
|
||||
if (currentScissorBox != targetScissorBox)
|
||||
{
|
||||
commandBuffer.SetScissor(targetScissorBox);
|
||||
currentScissorBox = targetScissorBox;
|
||||
}
|
||||
|
||||
if (currentIndexBuffer)
|
||||
commandBuffer.DrawIndexed(drawData.indexCount);
|
||||
commandBuffer.DrawIndexed(SafeCast<UInt32>(drawData.indexCount));
|
||||
else
|
||||
commandBuffer.Draw(drawData.indexCount);
|
||||
commandBuffer.Draw(SafeCast<UInt32>(drawData.indexCount));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace Nz
|
|||
RenderIndices& indices = pair.second;
|
||||
|
||||
if (indices.count > 0)
|
||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, key.texture->shared_from_this(), indices.count, &m_vertices[indices.first * 4]));
|
||||
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, key.texture->shared_from_this(), indices.count, &m_vertices[indices.first * 4], GetScissorBox()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -382,12 +382,18 @@ namespace Nz
|
|||
scissorRect = parentScissorRect;
|
||||
}
|
||||
|
||||
/*Recti fullBounds(scissorRect);
|
||||
scissorRect.y = GetCanvas()->GetSize().y - scissorRect.height - scissorRect.y; //< scissor rect is in screen coordinates
|
||||
|
||||
Recti fullBounds(scissorRect);
|
||||
|
||||
auto& registry = GetRegistry();
|
||||
for (WidgetEntity& widgetEntity : m_entities)
|
||||
{
|
||||
const Ndk::EntityHandle& entity = widgetEntity.handle;
|
||||
if (entity->HasComponent<GraphicsComponent>())
|
||||
entity->GetComponent<GraphicsComponent>().SetScissorRect(fullBounds);
|
||||
}*/
|
||||
if (GraphicsComponent* gfx = registry.try_get<GraphicsComponent>(widgetEntity.handle))
|
||||
{
|
||||
for (const auto& renderable : gfx->GetRenderables())
|
||||
renderable.renderable->UpdateScissorBox(fullBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace Nz
|
|||
m_cursorController(cursorController)
|
||||
{
|
||||
m_canvas = this;
|
||||
BaseWidget::m_registry = &m_registry;
|
||||
m_widgetParent = nullptr;
|
||||
|
||||
SetBaseRenderLayer(initialRenderLayer);
|
||||
|
|
|
|||
Loading…
Reference in New Issue