rescale the fbo so it’s always rendered pixel perfectly
This commit is contained in:
parent
587246e528
commit
8ea9cff499
4 changed files with 30 additions and 17 deletions
|
@ -10,8 +10,7 @@
|
|||
|
||||
static float sanitize_scale(float scale) {
|
||||
// return ftopow2(clamp(scale, 0.25, 4.0));
|
||||
scale = max(0.1, scale);
|
||||
return ((int)(scale*VIEWPORT_W*VIEWPORT_H+0.9999))/(float)VIEWPORT_W/VIEWPORT_H;
|
||||
return max(0.1, scale);
|
||||
}
|
||||
|
||||
void init_fbo(FBO *fbo, float scale) {
|
||||
|
@ -70,15 +69,15 @@ void delete_fbo(FBO *fbo) {
|
|||
}
|
||||
|
||||
void draw_fbo(FBO *fbo) {
|
||||
float wq = (fbo->scale*VIEWPORT_W)/(float)fbo->nw;
|
||||
float hq = (fbo->scale*VIEWPORT_H)/(float)fbo->nh;
|
||||
float wq = floor(fbo->scale*VIEWPORT_W)/(float)fbo->nw;
|
||||
float hq = floor(fbo->scale*VIEWPORT_H)/(float)fbo->nh;
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glScalef(wq, hq, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(VIEWPORT_W/2, VIEWPORT_H/2, 0);
|
||||
glTranslatef(VIEWPORT_W/2., VIEWPORT_H/2., 0);
|
||||
glScalef(VIEWPORT_W, VIEWPORT_H, 1);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->tex);
|
||||
|
|
|
@ -264,9 +264,19 @@ static void postprocess_prepare(FBO *fbo, Shader *s) {
|
|||
}
|
||||
|
||||
void stage_draw_foreground(void) {
|
||||
int vw, vh;
|
||||
video_get_viewport_size(&vw,&vh);
|
||||
|
||||
// CAUTION: Very intricate pixel perfect scaling that will ruin your day.
|
||||
float facw = (float)vw/SCREEN_W;
|
||||
float fach = (float)vh/SCREEN_H;
|
||||
float scale = resources.fbo.fg[0].scale;
|
||||
|
||||
// draw the foreground FBO
|
||||
glPushMatrix();
|
||||
glTranslatef(VIEWPORT_X, VIEWPORT_Y, 0);
|
||||
glScalef(1/facw,1/fach,1);
|
||||
glTranslatef(floorf(facw*VIEWPORT_X), floorf(fach*VIEWPORT_Y), 0);
|
||||
glScalef(floorf(scale*VIEWPORT_W)/VIEWPORT_W,floorf(scale*VIEWPORT_H)/VIEWPORT_H,1);
|
||||
// apply the screenshake effect
|
||||
if(global.shake_view) {
|
||||
glTranslatef(global.shake_view*sin(global.frames),global.shake_view*sin(global.frames*1.1+3),0);
|
||||
|
@ -279,9 +289,9 @@ void stage_draw_foreground(void) {
|
|||
global.shake_view = global.shake_view_fade = 0;
|
||||
}
|
||||
}
|
||||
|
||||
draw_fbo(&resources.fbo.fg[0]);
|
||||
glPopMatrix();
|
||||
set_ortho();
|
||||
}
|
||||
|
||||
void stage_draw_scene(StageInfo *stage) {
|
||||
|
|
23
src/video.c
23
src/video.c
|
@ -49,7 +49,7 @@ static int video_compare_modes(const void *a, const void *b) {
|
|||
return va->width * va->height - vb->width * vb->height;
|
||||
}
|
||||
|
||||
void video_set_viewport(void) {
|
||||
void video_get_viewport_size(int *width, int *height) {
|
||||
float w = video.current.width;
|
||||
float h = video.current.height;
|
||||
float r = w / h;
|
||||
|
@ -59,9 +59,17 @@ void video_set_viewport(void) {
|
|||
} else if(r < VIDEO_ASPECT_RATIO) {
|
||||
h = w / VIDEO_ASPECT_RATIO;
|
||||
}
|
||||
*width = w;
|
||||
*height = h;
|
||||
}
|
||||
|
||||
|
||||
void video_set_viewport(void) {
|
||||
int w, h;
|
||||
video_get_viewport_size(&w,&h);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport((video.current.width - w) / 2, (video.current.height - h) / 2, (int)w, (int)h);
|
||||
glViewport((video.current.width - w) / 2, (video.current.height - h) / 2, w, h);
|
||||
}
|
||||
|
||||
void video_update_vsync(void) {
|
||||
|
@ -153,14 +161,9 @@ static void video_init_gl(void) {
|
|||
}
|
||||
|
||||
static void video_update_quality(void) {
|
||||
float q;
|
||||
float r = (float)video.current.width / video.current.height;
|
||||
|
||||
if(r >= VIDEO_ASPECT_RATIO) {
|
||||
q = (float)video.current.height / SCREEN_H;
|
||||
} else {
|
||||
q = (float)video.current.width / SCREEN_W;
|
||||
}
|
||||
int vw, vh;
|
||||
video_get_viewport_size(&vw,&vh);
|
||||
float q = (float)vh / SCREEN_H;
|
||||
|
||||
float fg = q * config_get_float(CONFIG_FG_QUALITY);
|
||||
float bg = q * config_get_float(CONFIG_BG_QUALITY);
|
||||
|
|
|
@ -35,6 +35,7 @@ extern Video video;
|
|||
void video_init(void);
|
||||
void video_shutdown(void);
|
||||
void video_setmode(int w, int h, bool fs, bool resizable);
|
||||
void video_get_viewport_size(int *width, int *height);
|
||||
void video_set_viewport(void);
|
||||
bool video_isfullscreen(void);
|
||||
bool video_isresizable(void);
|
||||
|
|
Loading…
Reference in a new issue