treballant en postfx
This commit is contained in:
@@ -10,7 +10,10 @@
|
||||
#include <string> // Para char_traits, string, operator+, operator==
|
||||
|
||||
#include "core/input/mouse.hpp" // Para updateCursorVisibility
|
||||
#ifndef __APPLE__
|
||||
#include "core/rendering/opengl/opengl_shader.hpp" // Para OpenGLShader
|
||||
#endif
|
||||
#include "core/rendering/sdl3gpu/sdl3gpu_shader.hpp" // Para SDL3GPUShader
|
||||
#include "core/rendering/surface.hpp" // Para Surface, readPalFile
|
||||
#include "core/rendering/text.hpp" // Para Text
|
||||
#include "core/resources/resource_cache.hpp" // Para Resource
|
||||
@@ -124,13 +127,16 @@ void Screen::start() { setRendererSurface(nullptr); }
|
||||
void Screen::render() {
|
||||
fps_.increment();
|
||||
|
||||
// Renderiza todos los overlays
|
||||
// Renderiza todos los overlays (escribe en game_surface_ CPU-side)
|
||||
renderOverlays();
|
||||
|
||||
// Copia la surface a la textura
|
||||
surfaceToTexture();
|
||||
// En el path SDL3GPU, los píxeles se suben directamente desde la Surface.
|
||||
// En el path SDL_Renderer, primero copiamos la surface a la SDL_Texture.
|
||||
if (!(Options::video.shaders && shader_backend_ && shader_backend_->isHardwareAccelerated())) {
|
||||
surfaceToTexture();
|
||||
}
|
||||
|
||||
// Copia la textura al renderizador
|
||||
// Copia la textura al renderizador (o hace el present GPU)
|
||||
textureToRenderer();
|
||||
}
|
||||
|
||||
@@ -206,7 +212,12 @@ void Screen::renderNotifications() const {
|
||||
// Cambia el estado de los shaders
|
||||
void Screen::toggleShaders() {
|
||||
Options::video.shaders = !Options::video.shaders;
|
||||
initShaders();
|
||||
if (!Options::video.shaders && shader_backend_) {
|
||||
// Al desactivar shaders, limpiar el backend para liberar el swapchain de GPU
|
||||
shader_backend_->cleanup();
|
||||
} else {
|
||||
initShaders();
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza la lógica de la clase (versión nueva con delta_time para escenas migradas)
|
||||
@@ -304,13 +315,42 @@ void Screen::surfaceToTexture() {
|
||||
}
|
||||
}
|
||||
|
||||
// Copia la textura al renderizador
|
||||
// Copia la textura al renderizador (o hace el present GPU)
|
||||
void Screen::textureToRenderer() {
|
||||
SDL_Texture* texture_to_render = Options::video.border.enabled ? border_texture_ : game_texture_;
|
||||
|
||||
if (Options::video.shaders && shader_backend_) {
|
||||
if (Options::video.shaders && shader_backend_ && shader_backend_->isHardwareAccelerated()) {
|
||||
// ---- SDL3 GPU path: convertir Surface → ARGB → upload → PostFX → present ----
|
||||
if (Options::video.border.enabled) {
|
||||
// El border_surface_ solo tiene el color de borde; hay que componer encima el game_surface_
|
||||
const int BORDER_W = static_cast<int>(border_surface_->getWidth());
|
||||
const int BORDER_H = static_cast<int>(border_surface_->getHeight());
|
||||
pixel_buffer_.resize(static_cast<size_t>(BORDER_W * BORDER_H));
|
||||
border_surface_->toARGBBuffer(pixel_buffer_.data());
|
||||
|
||||
// Compositar game_surface_ en la posición correcta dentro del buffer
|
||||
const int GAME_W = static_cast<int>(game_surface_->getWidth());
|
||||
const int GAME_H = static_cast<int>(game_surface_->getHeight());
|
||||
const int OFF_X = static_cast<int>(game_surface_dstrect_.x);
|
||||
const int OFF_Y = static_cast<int>(game_surface_dstrect_.y);
|
||||
std::vector<Uint32> game_pixels(static_cast<size_t>(GAME_W * GAME_H));
|
||||
game_surface_->toARGBBuffer(game_pixels.data());
|
||||
for (int y = 0; y < GAME_H; ++y) {
|
||||
for (int x = 0; x < GAME_W; ++x) {
|
||||
pixel_buffer_[static_cast<size_t>(((OFF_Y + y) * BORDER_W) + (OFF_X + x))] = game_pixels[static_cast<size_t>((y * GAME_W) + x)];
|
||||
}
|
||||
}
|
||||
shader_backend_->uploadPixels(pixel_buffer_.data(), BORDER_W, BORDER_H);
|
||||
} else {
|
||||
const int GAME_W = static_cast<int>(game_surface_->getWidth());
|
||||
const int GAME_H = static_cast<int>(game_surface_->getHeight());
|
||||
pixel_buffer_.resize(static_cast<size_t>(GAME_W * GAME_H));
|
||||
game_surface_->toARGBBuffer(pixel_buffer_.data());
|
||||
shader_backend_->uploadPixels(pixel_buffer_.data(), GAME_W, GAME_H);
|
||||
}
|
||||
shader_backend_->render();
|
||||
} else {
|
||||
// ---- SDL_Renderer path (fallback / no-shader) ----
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
@@ -437,19 +477,25 @@ void Screen::loadShaders() {
|
||||
|
||||
// Inicializa los shaders
|
||||
void Screen::initShaders() {
|
||||
#ifndef __APPLE__
|
||||
if (Options::video.shaders) {
|
||||
loadShaders();
|
||||
if (!shader_backend_) {
|
||||
shader_backend_ = std::make_unique<Rendering::OpenGLShader>();
|
||||
}
|
||||
shader_backend_->init(window_, Options::video.border.enabled ? border_texture_ : game_texture_, vertex_shader_source_, fragment_shader_source_);
|
||||
// shader_backend_->init(window_, shaders_texture_, vertex_shader_source_, fragment_shader_source_);
|
||||
if (!Options::video.shaders) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Texture* tex = Options::video.border.enabled ? border_texture_ : game_texture_;
|
||||
|
||||
#ifdef __APPLE__
|
||||
// macOS: usar SDL3 GPU API (Metal) via SDL3GPUShader
|
||||
if (!shader_backend_) {
|
||||
shader_backend_ = std::make_unique<Rendering::SDL3GPUShader>();
|
||||
}
|
||||
shader_backend_->init(window_, tex, "", "");
|
||||
#else
|
||||
// En macOS, OpenGL está deprecated y rinde mal
|
||||
// TODO: Implementar backend de Metal para shaders en macOS
|
||||
std::cout << "WARNING: Shaders no disponibles en macOS (OpenGL deprecated). Usa Metal backend.\n";
|
||||
// Win/Linux: usar OpenGL + GLSL
|
||||
loadShaders();
|
||||
if (!shader_backend_) {
|
||||
shader_backend_ = std::make_unique<Rendering::OpenGLShader>();
|
||||
}
|
||||
shader_backend_->init(window_, tex, vertex_shader_source_, fragment_shader_source_);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -537,7 +583,9 @@ auto Screen::initSDLVideo() -> bool {
|
||||
const auto WINDOW_WIDTH = Options::video.border.enabled ? Options::game.width + (Options::video.border.width * 2) : Options::game.width;
|
||||
const auto WINDOW_HEIGHT = Options::video.border.enabled ? Options::game.height + (Options::video.border.height * 2) : Options::game.height;
|
||||
#ifdef __APPLE__
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_METAL;
|
||||
// SDL_WINDOW_METAL no es necesario: SDL3GPU autodetecta Metal via SDL_CreateGPUDevice.
|
||||
// SDL_Renderer también usará Metal si está disponible (via hint o autoselección).
|
||||
SDL_WindowFlags window_flags = 0;
|
||||
#elif defined(LINUX_BUILD)
|
||||
// En Linux, SDL_WINDOW_OPENGL puede entrar en conflicto con el backend del renderer;
|
||||
// el hint SDL_HINT_RENDER_DRIVER="opengl" es suficiente para seleccionar OpenGL.
|
||||
|
||||
Reference in New Issue
Block a user