Els shaders ja respeten el escalat sencer

This commit is contained in:
2025-03-16 09:00:19 +01:00
parent dc7b3bf7e0
commit 96680dae0f

View File

@@ -1,5 +1,5 @@
#include "jail_shader.h" #include "jail_shader.h"
#include <SDL2/SDL_rect.h> // para SDL_Point #include <SDL2/SDL.h> // para SDL_Point
#include <stdlib.h> // para NULL, free, malloc, exit #include <stdlib.h> // para NULL, free, malloc, exit
#include <string.h> // para strncmp #include <string.h> // para strncmp
#include <iostream> // para basic_ostream, char_traits, operator<< #include <iostream> // para basic_ostream, char_traits, operator<<
@@ -212,48 +212,62 @@ namespace shader
logicalH = win_size.y; logicalH = win_size.y;
} }
// Calcula el viewport para preservar la relación de aspecto (letterboxing) // Cálculo del viewport
float windowAspect = static_cast<float>(win_size.x) / win_size.y;
float logicalAspect = static_cast<float>(logicalW) / logicalH;
int viewportX = 0, viewportY = 0, viewportW = win_size.x, viewportH = win_size.y; int viewportX = 0, viewportY = 0, viewportW = win_size.x, viewportH = win_size.y;
SDL_bool useIntegerScale = SDL_RenderGetIntegerScale(renderer);
if (windowAspect > logicalAspect) if (useIntegerScale)
{ {
// La ventana es más ancha que el espacio lógico: // Calcula el factor de escalado entero máximo que se puede aplicar
viewportW = static_cast<int>(logicalAspect * win_size.y); int scaleX = win_size.x / logicalW;
int scaleY = win_size.y / logicalH;
int scale = (scaleX < scaleY ? scaleX : scaleY);
if (scale < 1)
scale = 1;
viewportW = logicalW * scale;
viewportH = logicalH * scale;
viewportX = (win_size.x - viewportW) / 2; viewportX = (win_size.x - viewportW) / 2;
viewportY = (win_size.y - viewportH) / 2;
} }
else else
{ {
// La ventana es más alta que el espacio lógico: // Letterboxing: preserva la relación de aspecto usando una escala flotante
viewportH = static_cast<int>(win_size.x / logicalAspect); float windowAspect = static_cast<float>(win_size.x) / win_size.y;
viewportY = (win_size.y - viewportH) / 2; float logicalAspect = static_cast<float>(logicalW) / logicalH;
if (windowAspect > logicalAspect)
{
viewportW = static_cast<int>(logicalAspect * win_size.y);
viewportX = (win_size.x - viewportW) / 2;
}
else
{
viewportH = static_cast<int>(win_size.x / logicalAspect);
viewportY = (win_size.y - viewportH) / 2;
}
} }
glViewport(viewportX, viewportY, viewportW, viewportH); glViewport(viewportX, viewportY, viewportW, viewportH);
// Configura la proyección ortográfica usando el espacio lógico // Configurar la proyección ortográfica usando el espacio lógico
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
// Se usa glOrtho para definir el espacio lógico: // Queremos que el origen esté en la esquina superior izquierda del espacio lógico.
// el 0 está en la esquina superior izquierda y logicalH en la inferior.
glOrtho(0, static_cast<GLdouble>(logicalW), static_cast<GLdouble>(logicalH), 0, -1, 1); glOrtho(0, static_cast<GLdouble>(logicalW), static_cast<GLdouble>(logicalH), 0, -1, 1);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
// Dibuja el quad usando las nuevas coordenadas de textura: // Dibuja el quad con las coordenadas ajustadas.
// Se corrigen la inversión vertical y la espejada horizontal. // Se asignan las coordenadas de textura "normales" para que no quede espejado horizontalmente,
// y se mantiene el flip vertical para que la imagen no aparezca volteada.
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
// Vértice superior izquierdo: posición (0, 0) // Vértice superior izquierdo
glTexCoord2f(0.0f, 1.0f); glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
// Vértice superior derecho: posición (logicalW, 0) // Vértice superior derecho
glTexCoord2f(1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f);
glVertex2f(static_cast<GLfloat>(logicalW), 0.0f); glVertex2f(static_cast<GLfloat>(logicalW), 0.0f);
// Vértice inferior izquierdo: posición (0, logicalH) // Vértice inferior izquierdo
glTexCoord2f(0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, static_cast<GLfloat>(logicalH)); glVertex2f(0.0f, static_cast<GLfloat>(logicalH));
// Vértice inferior derecho: posición (logicalW, logicalH) // Vértice inferior derecho
glTexCoord2f(1.0f, 0.0f); glTexCoord2f(1.0f, 0.0f);
glVertex2f(static_cast<GLfloat>(logicalW), static_cast<GLfloat>(logicalH)); glVertex2f(static_cast<GLfloat>(logicalW), static_cast<GLfloat>(logicalH));
glEnd(); glEnd();