feat(BgfxRenderer): Add layer sorting for correct sprite Z-order
Sprites are now sorted by layer (ascending) then by textureId for batching. Batches are flushed when layer OR texture changes to maintain correct draw order. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
613283d75c
commit
5795bbb37e
@ -101,32 +101,40 @@ void SpritePass::execute(const FramePacket& frame, rhi::IRHIDevice& device, rhi:
|
|||||||
state.depthWrite = false;
|
state.depthWrite = false;
|
||||||
cmd.setState(state);
|
cmd.setState(state);
|
||||||
|
|
||||||
// Build sorted indices by textureId for batching
|
// Build sorted indices by layer (primary) and textureId (secondary) for batching
|
||||||
m_sortedIndices.clear();
|
m_sortedIndices.clear();
|
||||||
m_sortedIndices.reserve(frame.spriteCount);
|
m_sortedIndices.reserve(frame.spriteCount);
|
||||||
for (size_t i = 0; i < frame.spriteCount; ++i) {
|
for (size_t i = 0; i < frame.spriteCount; ++i) {
|
||||||
m_sortedIndices.push_back(static_cast<uint32_t>(i));
|
m_sortedIndices.push_back(static_cast<uint32_t>(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort by textureId (stable sort to preserve layer order within same texture)
|
// Sort by layer first (ascending: layer 0 = background, rendered first)
|
||||||
std::stable_sort(m_sortedIndices.begin(), m_sortedIndices.end(),
|
// Then by textureId to batch sprites on the same layer
|
||||||
|
std::sort(m_sortedIndices.begin(), m_sortedIndices.end(),
|
||||||
[&frame](uint32_t a, uint32_t b) {
|
[&frame](uint32_t a, uint32_t b) {
|
||||||
return frame.sprites[a].textureId < frame.sprites[b].textureId;
|
const SpriteInstance& sa = frame.sprites[a];
|
||||||
|
const SpriteInstance& sb = frame.sprites[b];
|
||||||
|
if (sa.layer != sb.layer) {
|
||||||
|
return sa.layer < sb.layer;
|
||||||
|
}
|
||||||
|
return sa.textureId < sb.textureId;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Process sprites in batches by texture
|
// Process sprites in batches by layer and texture
|
||||||
|
// Flush batch when layer OR texture changes to maintain correct draw order
|
||||||
std::vector<SpriteInstance> batchData;
|
std::vector<SpriteInstance> batchData;
|
||||||
batchData.reserve(MAX_SPRITES_PER_BATCH);
|
batchData.reserve(MAX_SPRITES_PER_BATCH);
|
||||||
|
|
||||||
uint16_t currentTextureId = UINT16_MAX;
|
uint16_t currentTextureId = UINT16_MAX;
|
||||||
|
float currentLayer = -1e9f; // Use a value that won't match any real layer
|
||||||
rhi::TextureHandle currentTexture;
|
rhi::TextureHandle currentTexture;
|
||||||
|
|
||||||
for (uint32_t idx : m_sortedIndices) {
|
for (uint32_t idx : m_sortedIndices) {
|
||||||
const SpriteInstance& sprite = frame.sprites[idx];
|
const SpriteInstance& sprite = frame.sprites[idx];
|
||||||
uint16_t texId = static_cast<uint16_t>(sprite.textureId);
|
uint16_t texId = static_cast<uint16_t>(sprite.textureId);
|
||||||
|
|
||||||
// Check if texture changed
|
// Check if texture OR layer changed (must flush to maintain layer order)
|
||||||
if (texId != currentTextureId) {
|
if (texId != currentTextureId || sprite.layer != currentLayer) {
|
||||||
// Flush previous batch
|
// Flush previous batch
|
||||||
if (!batchData.empty()) {
|
if (!batchData.empty()) {
|
||||||
device.updateBuffer(m_instanceBuffer, batchData.data(),
|
device.updateBuffer(m_instanceBuffer, batchData.data(),
|
||||||
@ -135,8 +143,9 @@ void SpritePass::execute(const FramePacket& frame, rhi::IRHIDevice& device, rhi:
|
|||||||
batchData.clear();
|
batchData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current texture
|
// Update current state
|
||||||
currentTextureId = texId;
|
currentTextureId = texId;
|
||||||
|
currentLayer = sprite.layer;
|
||||||
if (texId == 0 || !m_resourceCache) {
|
if (texId == 0 || !m_resourceCache) {
|
||||||
// Use default/active texture for textureId=0
|
// Use default/active texture for textureId=0
|
||||||
currentTexture = m_activeTexture.isValid() ? m_activeTexture : m_defaultTexture;
|
currentTexture = m_activeTexture.isValid() ? m_activeTexture : m_defaultTexture;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user