internal resolution
This commit is contained in:
@@ -172,24 +172,27 @@ void Screen::present(Uint32* pixel_data) {
|
|||||||
shader_backend_->setActiveShader(prev_shader);
|
shader_backend_->setActiveShader(prev_shader);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback SDL_Renderer
|
// Fallback SDL_Renderer. A mult=1, flux directe original: logical
|
||||||
|
// presentation (setada per applyFallbackPresentation) + scale mode de
|
||||||
|
// texture_ segons l'opció. A mult>1, la còpia intermèdia crea la
|
||||||
|
// font ampliada (NN via GPU), i es presenta via logical presentation
|
||||||
|
// a la mida de la font intermèdia.
|
||||||
SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32));
|
SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32));
|
||||||
|
|
||||||
const int mult = Options::video.internal_resolution;
|
const int mult = Options::video.internal_resolution;
|
||||||
if (mult > 1) {
|
if (mult > 1) {
|
||||||
// Resolució interna: còpia NN de texture_ → internal_texture_sdl_
|
|
||||||
// (la fa SDL/GPU, no CPU). Tota la presentació downstream llegirà
|
|
||||||
// d'aquesta textura més gran — el filtre LINEAR final parteix d'una
|
|
||||||
// font més fina i l'estirament a finestra queda menys difús.
|
|
||||||
ensureFallbackInternalTexture();
|
ensureFallbackInternalTexture();
|
||||||
if (internal_texture_sdl_ != nullptr) {
|
if (internal_texture_sdl_ != nullptr) {
|
||||||
|
// Còpia NN a la textura intermèdia (mult·game). Sampler NN
|
||||||
|
// per construcció: volem píxels grans i nets.
|
||||||
SDL_SetTextureScaleMode(texture_, SDL_SCALEMODE_NEAREST);
|
SDL_SetTextureScaleMode(texture_, SDL_SCALEMODE_NEAREST);
|
||||||
SDL_SetRenderTarget(renderer_, internal_texture_sdl_);
|
SDL_SetRenderTarget(renderer_, internal_texture_sdl_);
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
SDL_RenderTexture(renderer_, texture_, nullptr, nullptr);
|
SDL_RenderTexture(renderer_, texture_, nullptr, nullptr);
|
||||||
SDL_SetRenderTarget(renderer_, nullptr);
|
SDL_SetRenderTarget(renderer_, nullptr);
|
||||||
// El filtre global (LINEAR/NEAREST) s'aplica a l'estirament final
|
|
||||||
// cap a la finestra; per això l'aplicam a la textura intermèdia.
|
// Filtre global al pas final → finestra (via logical presentation
|
||||||
|
// que applyFallbackPresentation ja configura amb mida game·mult).
|
||||||
SDL_ScaleMode final_scale = (Options::video.texture_filter == Options::TextureFilter::LINEAR)
|
SDL_ScaleMode final_scale = (Options::video.texture_filter == Options::TextureFilter::LINEAR)
|
||||||
? SDL_SCALEMODE_LINEAR
|
? SDL_SCALEMODE_LINEAR
|
||||||
: SDL_SCALEMODE_NEAREST;
|
: SDL_SCALEMODE_NEAREST;
|
||||||
@@ -199,8 +202,15 @@ void Screen::present(Uint32* pixel_data) {
|
|||||||
SDL_RenderPresent(renderer_);
|
SDL_RenderPresent(renderer_);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Si la creació de la textura ha fallat, caiem al path normal.
|
// Si la creació de la textura intermèdia ha fallat, caiem al path normal.
|
||||||
}
|
}
|
||||||
|
// mult=1 (o fallback-del-fallback): texture_ directament. El scale mode
|
||||||
|
// el manté applyFallbackPresentation — però el re-apliquem per si la
|
||||||
|
// ruta mult>1 el va sobreescriure anteriorment.
|
||||||
|
SDL_ScaleMode direct_scale = (Options::video.texture_filter == Options::TextureFilter::LINEAR)
|
||||||
|
? SDL_SCALEMODE_LINEAR
|
||||||
|
: SDL_SCALEMODE_NEAREST;
|
||||||
|
SDL_SetTextureScaleMode(texture_, direct_scale);
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
SDL_RenderTexture(renderer_, texture_, nullptr, nullptr);
|
SDL_RenderTexture(renderer_, texture_, nullptr, nullptr);
|
||||||
SDL_RenderPresent(renderer_);
|
SDL_RenderPresent(renderer_);
|
||||||
@@ -502,9 +512,10 @@ void Screen::applyFallbackPresentation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Screen::ensureFallbackInternalTexture() {
|
void Screen::ensureFallbackInternalTexture() {
|
||||||
|
if (renderer_ == nullptr) return;
|
||||||
const int mult = Options::video.internal_resolution;
|
const int mult = Options::video.internal_resolution;
|
||||||
if (mult <= 1 || renderer_ == nullptr) {
|
if (mult <= 1) {
|
||||||
// No cal textura intermèdia. Si la teníem, la reciclem.
|
// No cal textura intermèdia — recicla si la teníem.
|
||||||
if (internal_texture_sdl_ != nullptr) {
|
if (internal_texture_sdl_ != nullptr) {
|
||||||
SDL_DestroyTexture(internal_texture_sdl_);
|
SDL_DestroyTexture(internal_texture_sdl_);
|
||||||
internal_texture_sdl_ = nullptr;
|
internal_texture_sdl_ = nullptr;
|
||||||
|
|||||||
@@ -977,9 +977,14 @@ namespace Rendering {
|
|||||||
SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F};
|
SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F};
|
||||||
SDL_SetGPUViewport(pass, &vp);
|
SDL_SetGPUViewport(pass, &vp);
|
||||||
|
|
||||||
|
// El shader CrtPi tradicionalment usa NEAREST per a fer el seu
|
||||||
|
// propi filtrat analític. Si l'usuari tria LINEAR explícitament,
|
||||||
|
// respectem la preferència (la mostra arribarà pre-suavitzada).
|
||||||
SDL_GPUTextureSamplerBinding binding = {};
|
SDL_GPUTextureSamplerBinding binding = {};
|
||||||
binding.texture = effective_scene;
|
binding.texture = effective_scene;
|
||||||
binding.sampler = sampler_; // NEAREST: el shader CrtPi fa el seu propi filtrat analític
|
binding.sampler = (texture_filter_linear_ && linear_sampler_ != nullptr)
|
||||||
|
? linear_sampler_
|
||||||
|
: sampler_;
|
||||||
SDL_BindGPUFragmentSamplers(pass, 0, &binding, 1);
|
SDL_BindGPUFragmentSamplers(pass, 0, &binding, 1);
|
||||||
|
|
||||||
// Injectar texture_width/height abans del push
|
// Injectar texture_width/height abans del push
|
||||||
@@ -1054,11 +1059,15 @@ namespace Rendering {
|
|||||||
SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F};
|
SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F};
|
||||||
SDL_SetGPUViewport(pass, &vp);
|
SDL_SetGPUViewport(pass, &vp);
|
||||||
|
|
||||||
// Amb SS: llegir de scaled_texture_ amb LINEAR; sense SS: effective_scene amb NEAREST.
|
// Font: amb SS scaled_texture_; sense SS, effective_scene (que ja
|
||||||
|
// és internal_texture_ si internal_res_>1, o scene_texture_ si no).
|
||||||
|
// Sampler: honora el filtre global que l'usuari tria al menú
|
||||||
|
// (texture_filter_linear_). Abans estava hardcoded a NEAREST
|
||||||
|
// quan SS era off — el menú no tenia efecte visible en aquest path.
|
||||||
SDL_GPUTexture* input_texture = (oversample_ > 1 && scaled_texture_ != nullptr)
|
SDL_GPUTexture* input_texture = (oversample_ > 1 && scaled_texture_ != nullptr)
|
||||||
? scaled_texture_
|
? scaled_texture_
|
||||||
: effective_scene;
|
: effective_scene;
|
||||||
SDL_GPUSampler* active_sampler = (oversample_ > 1 && linear_sampler_ != nullptr)
|
SDL_GPUSampler* active_sampler = (texture_filter_linear_ && linear_sampler_ != nullptr)
|
||||||
? linear_sampler_
|
? linear_sampler_
|
||||||
: sampler_;
|
: sampler_;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user