fix: corregir límite de sprites en SHAPE mode con muchas bolas

GpuSpriteBatch::init() ahora acepta capacidad dinámica para soportar
--custom-balls N con N > 200000. El buffer se dimensiona a (N+1) quads,
reservando siempre un slot para el overlay. addFullscreenOverlay() calcula
overlay_index_count_ desde el delta real de indices_ en lugar de fijarlo
a 6 incondicionalmente. Engine calcula la capacidad correcta al init.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 00:14:28 +01:00
parent 46b24bf075
commit 74d954df1e
3 changed files with 23 additions and 12 deletions

View File

@@ -7,10 +7,12 @@
// Public interface
// ---------------------------------------------------------------------------
bool GpuSpriteBatch::init(SDL_GPUDevice* device) {
// Pre-allocate GPU buffers large enough for MAX_SPRITES quads.
Uint32 max_verts = static_cast<Uint32>(MAX_SPRITES) * 4;
Uint32 max_indices = static_cast<Uint32>(MAX_SPRITES) * 6;
bool GpuSpriteBatch::init(SDL_GPUDevice* device, int max_sprites) {
max_sprites_ = max_sprites;
// Pre-allocate GPU buffers large enough for (max_sprites_ + 1) quads.
// The +1 reserves a guaranteed slot for the fullscreen overlay.
Uint32 max_verts = static_cast<Uint32>(max_sprites_ + 1) * 4;
Uint32 max_indices = static_cast<Uint32>(max_sprites_ + 1) * 6;
Uint32 vb_size = max_verts * sizeof(GpuVertex);
Uint32 ib_size = max_indices * sizeof(uint32_t);
@@ -53,8 +55,8 @@ bool GpuSpriteBatch::init(SDL_GPUDevice* device) {
return false;
}
vertices_.reserve(MAX_SPRITES * 4);
indices_.reserve(MAX_SPRITES * 6);
vertices_.reserve(static_cast<size_t>(max_sprites_ + 1) * 4);
indices_.reserve(static_cast<size_t>(max_sprites_ + 1) * 6);
return true;
}
@@ -129,8 +131,9 @@ void GpuSpriteBatch::addSprite(float x, float y, float w, float h,
void GpuSpriteBatch::addFullscreenOverlay() {
overlay_index_offset_ = static_cast<int>(indices_.size());
size_t before = indices_.size();
pushQuad(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
overlay_index_count_ = 6;
overlay_index_count_ = static_cast<int>(indices_.size() - before); // 0 si pushQuad falló, 6 si ok
}
bool GpuSpriteBatch::uploadBatch(SDL_GPUDevice* device, SDL_GPUCommandBuffer* cmd_buf) {
@@ -179,7 +182,7 @@ void GpuSpriteBatch::toNDC(float px, float py,
void GpuSpriteBatch::pushQuad(float ndx0, float ndy0, float ndx1, float ndy1,
float u0, float v0, float u1, float v1,
float r, float g, float b, float a) {
if (vertices_.size() + 4 > static_cast<size_t>(MAX_SPRITES) * 4) return;
if (vertices_.size() + 4 > static_cast<size_t>(max_sprites_) * 4) return;
uint32_t vi = static_cast<uint32_t>(vertices_.size());
// TL, TR, BR, BL