feat(service-menu): esquelet amb F12, brackets sci-fi i highlight animat
This commit is contained in:
1 parent
cc16908b86
commit
443b461974
12 files changed
+722
-1
No files matched your search
@@ -5,6 +5,7 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_gpu.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -390,6 +391,10 @@ namespace Rendering::GPU {
|
||||
color_target.store_op = SDL_GPU_STOREOP_STORE;
|
||||
render_pass_ = SDL_BeginGPURenderPass(cmd_buffer_, &color_target, 1, nullptr);
|
||||
|
||||
// L'scissor és per render pass: en reobrir cal restaurar-lo des del top
|
||||
// de la pila si pushClip/popClip s'han usat mid-frame.
|
||||
applyCurrentScissor();
|
||||
|
||||
SDL_BindGPUGraphicsPipeline(render_pass_, line_pipeline_.get());
|
||||
|
||||
// UBO de líneas usa el tamaño lógico (también del offscreen).
|
||||
@@ -415,6 +420,11 @@ namespace Rendering::GPU {
|
||||
SDL_ReleaseGPUBuffer(dev, vbo);
|
||||
SDL_ReleaseGPUBuffer(dev, ibo);
|
||||
SDL_ReleaseGPUTransferBuffer(dev, tbo);
|
||||
|
||||
// Buidem el batch perquè pushClip/popClip puguin emetre seccions
|
||||
// separades dins el mateix frame sense re-enviar geometria.
|
||||
vertices_.clear();
|
||||
indices_.clear();
|
||||
}
|
||||
|
||||
void GpuFrameRenderer::bloomPass() {
|
||||
@@ -603,6 +613,51 @@ namespace Rendering::GPU {
|
||||
SDL_DrawGPUPrimitives(render_pass_, 3, 1, 0, 0);
|
||||
}
|
||||
|
||||
void GpuFrameRenderer::pushClip(int logical_x, int logical_y, int logical_w, int logical_h) {
|
||||
// Convertim coordenades lògiques (espai del joc, 1280×720) a píxels
|
||||
// físics del offscreen (render_w_ × render_h_). Si l'usuari hi treballa
|
||||
// amb upscale (p.ex. 1920×1080), l'scissor escala proporcionalment.
|
||||
const float SX = render_w_ / logical_w_;
|
||||
const float SY = render_h_ / logical_h_;
|
||||
SDL_Rect rect{
|
||||
.x = static_cast<int>(static_cast<float>(logical_x) * SX),
|
||||
.y = static_cast<int>(static_cast<float>(logical_y) * SY),
|
||||
.w = std::max(0, static_cast<int>(static_cast<float>(logical_w) * SX)),
|
||||
.h = std::max(0, static_cast<int>(static_cast<float>(logical_h) * SY)),
|
||||
};
|
||||
// Emetem tot el batch acumulat *abans* d'activar l'scissor perquè quedi
|
||||
// dibuixat sense retallar.
|
||||
flushBatch();
|
||||
clip_stack_.push_back(rect);
|
||||
applyCurrentScissor();
|
||||
}
|
||||
|
||||
void GpuFrameRenderer::popClip() {
|
||||
// Emetem el batch que s'ha acumulat *dins* del clip actiu.
|
||||
flushBatch();
|
||||
if (!clip_stack_.empty()) {
|
||||
clip_stack_.pop_back();
|
||||
}
|
||||
applyCurrentScissor();
|
||||
}
|
||||
|
||||
void GpuFrameRenderer::applyCurrentScissor() {
|
||||
if (render_pass_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
SDL_Rect rect{};
|
||||
if (clip_stack_.empty()) {
|
||||
// Sense clips: scissor cobreix tot el offscreen.
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = static_cast<int>(render_w_);
|
||||
rect.h = static_cast<int>(render_h_);
|
||||
} else {
|
||||
rect = clip_stack_.back();
|
||||
}
|
||||
SDL_SetGPUScissor(render_pass_, &rect);
|
||||
}
|
||||
|
||||
void GpuFrameRenderer::endFrame() {
|
||||
if (cmd_buffer_ == nullptr) {
|
||||
return;
|
||||
|
||||
@@ -94,6 +94,15 @@ namespace Rendering::GPU {
|
||||
// d'UI (notificacions, panels).
|
||||
void pushRect(float x, float y, float w, float h, float r, float g, float b, float a);
|
||||
|
||||
// Clipping rectangular per a UI (scissor a SDL_GPU). pushClip/popClip
|
||||
// forcen un flush intermedi del batch i activen/restauren l'scissor del
|
||||
// pase actiu. Coordenades en píxels lògics del joc (1280×720); es
|
||||
// converteixen a píxels físics del offscreen automàticament. Stack
|
||||
// d'scissors per a clips niats. Quan la pila queda buida, l'scissor
|
||||
// torna a cobrir el target sencer.
|
||||
void pushClip(int logical_x, int logical_y, int logical_w, int logical_h);
|
||||
void popClip();
|
||||
|
||||
// endFrame: flush del batch de líneas → composite postpro → submit + presenta.
|
||||
void endFrame();
|
||||
|
||||
@@ -168,6 +177,10 @@ namespace Rendering::GPU {
|
||||
std::vector<LineVertex> vertices_;
|
||||
std::vector<uint16_t> indices_;
|
||||
|
||||
// Pila d'scissors actius en píxels físics del offscreen. Buida = sense
|
||||
// clip (full target). Cada push/pop fa un flushBatch i reaplica scissor.
|
||||
std::vector<SDL_Rect> clip_stack_;
|
||||
|
||||
// Estado del frame en curso.
|
||||
SDL_GPUCommandBuffer* cmd_buffer_{nullptr};
|
||||
SDL_GPUTexture* swapchain_texture_{nullptr};
|
||||
@@ -190,6 +203,7 @@ namespace Rendering::GPU {
|
||||
void bloomPass(); // pre-composite: H + V passes sobre les bloom textures
|
||||
void compositePass();
|
||||
void applyFinalViewport();
|
||||
void applyCurrentScissor(); // re-aplica el top de clip_stack_ al render_pass_
|
||||
};
|
||||
|
||||
} // namespace Rendering::GPU
|
||||
Reference in new issue
Block a user