Files
vibe3_physics/source/gpu/gpu_sprite_batch.hpp
Sergio Valor badf92420b feat(engine): PostFX cycle + fixes de reinicialització i overflow
- Afegir handlePostFXCycle() amb 5 presets (vinyeta/scanlines/cromàtica/complet/off)
  i tecla X per ciclar-los (input_handler + engine.hpp)
- Augmentar MAX_SPRITES de 65536 a 200000 i afegir guard d'overflow a pushQuad()
- Netejar textures/objectes UI abans de reinicialitzar (AppLogo::initialize,
  UIManager::initialize) per evitar leaks en toggleRealFullscreen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:53:13 +01:00

87 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <SDL3/SDL_gpu.h>
#include <vector>
#include <cstdint>
// ---------------------------------------------------------------------------
// GpuVertex — 8-float vertex layout sent to the GPU.
// Position is in NDC (pre-transformed on CPU), UV in [0,1], color in [0,1].
// ---------------------------------------------------------------------------
struct GpuVertex {
float x, y; // NDC position (1..1)
float u, v; // Texture coords (0..1)
float r, g, b, a; // RGBA color (0..1)
};
// ============================================================================
// GpuSpriteBatch — Accumulates sprite quads, uploads them in one copy pass.
//
// Usage per frame:
// batch.beginFrame();
// batch.addBackground(...); // Must be first (bg indices = [0..5])
// batch.addSprite(...) × N;
// batch.uploadBatch(device, cmd); // Copy pass
// // Then in render pass: bind buffers, draw bg with white tex, draw sprites.
// ============================================================================
class GpuSpriteBatch {
public:
// Maximum sprites (background + UI overlay each count as one sprite)
static constexpr int MAX_SPRITES = 200000;
bool init(SDL_GPUDevice* device);
void destroy(SDL_GPUDevice* device);
void beginFrame();
// Add the full-screen background gradient quad.
// top_* and bot_* are RGB in [0,1].
void addBackground(float screen_w, float screen_h,
float top_r, float top_g, float top_b,
float bot_r, float bot_g, float bot_b);
// Add a sprite quad (pixel coordinates).
// scale: uniform scale around the quad centre.
void addSprite(float x, float y, float w, float h,
float r, float g, float b, float a,
float scale,
float screen_w, float screen_h);
// Add a full-screen overlay quad (e.g. UI surface, NDC 1..1).
void addFullscreenOverlay();
// Upload CPU vectors to GPU buffers via a copy pass.
// Returns false if the batch is empty.
bool uploadBatch(SDL_GPUDevice* device, SDL_GPUCommandBuffer* cmd_buf);
SDL_GPUBuffer* vertexBuffer() const { return vertex_buf_; }
SDL_GPUBuffer* indexBuffer() const { return index_buf_; }
int bgIndexCount() const { return bg_index_count_; }
int overlayIndexOffset() const { return overlay_index_offset_; }
int overlayIndexCount() const { return overlay_index_count_; }
int spriteIndexOffset() const { return sprite_index_offset_; }
int spriteIndexCount() const { return sprite_index_count_; }
bool isEmpty() const { return vertices_.empty(); }
private:
void toNDC(float px, float py, float screen_w, float screen_h,
float& ndx, float& ndy) const;
void 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);
std::vector<GpuVertex> vertices_;
std::vector<uint32_t> indices_;
SDL_GPUBuffer* vertex_buf_ = nullptr;
SDL_GPUBuffer* index_buf_ = nullptr;
SDL_GPUTransferBuffer* vertex_transfer_ = nullptr;
SDL_GPUTransferBuffer* index_transfer_ = nullptr;
int bg_index_count_ = 0;
int sprite_index_offset_ = 0;
int sprite_index_count_ = 0;
int overlay_index_offset_ = 0;
int overlay_index_count_ = 0;
};