Skip to content

Commit

Permalink
gl: flip Y coord when drawing framebuffer to avoid rounding issues
Browse files Browse the repository at this point in the history
Flip Y again when drawing to final framebuffer
Fixes HUD characters truncated vertically in Test Drive V-Rally
Issue #1088
  • Loading branch information
flyinghead committed Sep 23, 2023
1 parent 79bbd86 commit 5ffcdb5
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 53 deletions.
4 changes: 1 addition & 3 deletions core/rend/gl4/gldraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include <memory>

static gl4PipelineShader* CurrentShader;
extern u32 gcflip;
GLuint geom_fbo;
GLuint stencilTexId;
GLuint opaqueTexId;
Expand Down Expand Up @@ -265,8 +264,7 @@ static void SetGPState(const PolyParam* gp)
glActiveTexture(GL_TEXTURE0);
}

//gcflip is global clip flip, needed for when rendering to texture due to mirrored Y direction
SetCull(gp->isp.CullMode ^ gcflip);
SetCull(gp->isp.CullMode ^ 1);

//set Z mode, only if required
if (Type == ListType_Punch_Through || (pass == Pass::Depth && SortingEnabled))
Expand Down
11 changes: 2 additions & 9 deletions core/rend/gl4/gles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -791,11 +791,6 @@ bool OpenGL4Renderer::renderFrame(int width, int height)
gl4ShaderUniforms.ndcMat = matrices.GetNormalMatrix();
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
ViewportMatrix = matrices.GetViewportMatrix();

if (!is_rtt && !config::EmulateFramebuffer)
gcflip = 0;
else
gcflip = 1;

/*
Handle Dc to screen scaling
Expand Down Expand Up @@ -852,10 +847,8 @@ bool OpenGL4Renderer::renderFrame(int width, int height)
#ifdef LIBRETRO
if (config::EmulateFramebuffer)
output_fbo = init_output_framebuffer(width, height);
else if (config::PowerVR2Filter || gl.ofbo.shiftX != 0 || gl.ofbo.shiftY != 0)
output_fbo = postProcessor.getFramebuffer(width, height);
else
output_fbo = glsm_get_current_framebuffer();
output_fbo = postProcessor.getFramebuffer(width, height);
glViewport(0, 0, width, height);
#else
output_fbo = init_output_framebuffer(rendering_width, rendering_height);
Expand Down Expand Up @@ -973,7 +966,7 @@ bool OpenGL4Renderer::renderFrame(int width, int height)

gl4DrawStrips(output_fbo, rendering_width, rendering_height);
#ifdef LIBRETRO
if ((config::PowerVR2Filter || gl.ofbo.shiftX != 0 || gl.ofbo.shiftY != 0) && !is_rtt && !config::EmulateFramebuffer)
if (!is_rtt && !config::EmulateFramebuffer)
postProcessor.render(glsm_get_current_framebuffer());
#endif
}
Expand Down
22 changes: 8 additions & 14 deletions core/rend/gles/gldraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ const u32 SrcBlendGL[] =
};

PipelineShader* CurrentShader;
u32 gcflip;

void SetCull(u32 CullMode)
{
Expand Down Expand Up @@ -235,8 +234,7 @@ void SetGPState(const PolyParam* gp,u32 cflip=0)

//set cull mode !
//cflip is required when exploding triangles for triangle sorting
//gcflip is global clip flip, needed for when rendering to texture due to mirrored Y direction
SetCull(gp->isp.CullMode^cflip^gcflip);
SetCull(gp->isp.CullMode ^ cflip ^ 1);

//set Z mode, only if required
if (Type == ListType_Punch_Through || (Type == ListType_Translucent && SortingEnabled))
Expand Down Expand Up @@ -328,7 +326,7 @@ static void drawSorted(int first, int count, bool multipass)
// FIXME no clipping in modvol shader
//SetTileClip(gp->tileclip,true);

SetCull(params->isp.CullMode ^ gcflip);
SetCull(params->isp.CullMode ^ 1);

glDrawElements(GL_TRIANGLES, pvrrc.sortedTriangles[p].count, gl.index_type,
(GLvoid*)(gl.get_index_size() * pvrrc.sortedTriangles[p].first));
Expand Down Expand Up @@ -623,11 +621,8 @@ void OpenGLRenderer::RenderFramebuffer(const FramebufferInfo& info)
saveCurrentFramebuffer();
getVideoShift(gl.ofbo.shiftX, gl.ofbo.shiftY);
#ifdef LIBRETRO
if (config::PowerVR2Filter || gl.ofbo.shiftX != 0 || gl.ofbo.shiftY != 0)
{
glBindFramebuffer(GL_FRAMEBUFFER, postProcessor.getFramebuffer(gl.dcfb.width, gl.dcfb.height));
glcache.BindTexture(GL_TEXTURE_2D, gl.dcfb.tex);
}
glBindFramebuffer(GL_FRAMEBUFFER, postProcessor.getFramebuffer(gl.dcfb.width, gl.dcfb.height));
glcache.BindTexture(GL_TEXTURE_2D, gl.dcfb.tex);
#else
if (gl.ofbo2.framebuffer != nullptr
&& (gl.dcfb.width != gl.ofbo2.framebuffer->getWidth() || gl.dcfb.height != gl.ofbo2.framebuffer->getHeight()))
Expand Down Expand Up @@ -656,11 +651,10 @@ void OpenGLRenderer::RenderFramebuffer(const FramebufferInfo& info)
else
{
glcache.Disable(GL_BLEND);
drawQuad(gl.dcfb.tex, false, true);
drawQuad(gl.dcfb.tex, false, false);
}
#ifdef LIBRETRO
if (config::PowerVR2Filter || gl.ofbo.shiftX != 0 || gl.ofbo.shiftY != 0)
postProcessor.render(glsm_get_current_framebuffer());
postProcessor.render(glsm_get_current_framebuffer());
#else
renderLastFrame();
#endif
Expand Down Expand Up @@ -789,7 +783,7 @@ bool OpenGLRenderer::renderLastFrame()
vertices = sverts;
}
glcache.Disable(GL_BLEND);
drawQuad(framebuffer->getTexture(), config::Rotate90, false, vertices);
drawQuad(framebuffer->getTexture(), config::Rotate90, true, vertices);
}
else
{
Expand All @@ -799,7 +793,7 @@ bool OpenGLRenderer::renderLastFrame()
glcache.ClearColor(VO_BORDER_COL.red(), VO_BORDER_COL.green(), VO_BORDER_COL.blue(), 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glBlitFramebuffer(-gl.ofbo.shiftX, gl.ofbo.shiftY, framebuffer->getWidth() - gl.ofbo.shiftX, framebuffer->getHeight() + gl.ofbo.shiftY,
dx, dy, settings.display.width - dx, settings.display.height - dy,
dx, settings.display.height - dy, settings.display.width - dx, dy,
GL_COLOR_BUFFER_BIT, config::TextureFiltering == 1 ? GL_NEAREST : GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, gl.ofbo.origFbo);
#endif
Expand Down
13 changes: 2 additions & 11 deletions core/rend/gles/gles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1195,11 +1195,6 @@ bool OpenGLRenderer::renderFrame(int width, int height)
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
ViewportMatrix = matrices.GetViewportMatrix();

if (!is_rtt && !config::EmulateFramebuffer)
gcflip = 0;
else
gcflip = 1;

ShaderUniforms.depth_coefs[0] = 2 / (vtx_max_fZ - vtx_min_fZ);
ShaderUniforms.depth_coefs[1] = -vtx_min_fZ - 1;
ShaderUniforms.depth_coefs[2] = 0;
Expand Down Expand Up @@ -1294,13 +1289,9 @@ bool OpenGLRenderer::renderFrame(int width, int height)
if (init_output_framebuffer(width, height) == 0)
return false;
}
else if (config::PowerVR2Filter || gl.ofbo.shiftX != 0 || gl.ofbo.shiftY != 0)
{
glBindFramebuffer(GL_FRAMEBUFFER, postProcessor.getFramebuffer(width, height));
}
else
{
glBindFramebuffer(GL_FRAMEBUFFER, glsm_get_current_framebuffer());
glBindFramebuffer(GL_FRAMEBUFFER, postProcessor.getFramebuffer(width, height));
}
glViewport(0, 0, width, height);
#else
Expand Down Expand Up @@ -1410,7 +1401,7 @@ bool OpenGLRenderer::renderFrame(int width, int height)

DrawStrips();
#ifdef LIBRETRO
if ((config::PowerVR2Filter || gl.ofbo.shiftX != 0 || gl.ofbo.shiftY != 0) && !is_rtt && !config::EmulateFramebuffer)
if (!is_rtt && !config::EmulateFramebuffer)
postProcessor.render(glsm_get_current_framebuffer());
#endif
}
Expand Down
3 changes: 0 additions & 3 deletions core/rend/gles/gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@
// Naomi2
#define VERTEX_NORM_ARRAY 7

//vertex types
extern u32 gcflip;

extern glm::mat4 ViewportMatrix;

void DrawStrips();
Expand Down
10 changes: 7 additions & 3 deletions core/rend/gles/postprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ float dithertable[16] = float[](
void main()
{
vec2 texcoord = vTexCoord;
texcoord.y = 1. - texcoord.y;
vec2 texcoord2 = vTexCoord;
texcoord2.y = 1. - texcoord2.y;
texcoord2.x *= float(TextureSize.x);
texcoord2.y *= float(TextureSize.y);
vec4 color = texture(Source, texcoord);
Expand All @@ -78,6 +80,7 @@ void main()
int taps = int(3);
float tap = (2.666f/float(taps)) / float(min(TextureSize.y, 720));
vec2 texcoord4 = vTexCoord;
texcoord4.y = 1. - texcoord4.y;
texcoord4.y -= tap * 2.f;
int bl;
vec4 ble = vec4(0.0);
Expand Down Expand Up @@ -136,6 +139,7 @@ void main()
int taps = 32;
float tap = 12.0/taps;
vec2 texcoord4 = vTexCoord;
texcoord4.y = 1. - texcoord4.y;
texcoord4.x = texcoord4.x + (2.0/640.0);
texcoord4.y = texcoord4.y;
vec4 blur1 = texture(Source, texcoord4);
Expand Down Expand Up @@ -281,7 +285,7 @@ void PostProcessor::render(GLuint output_fbo)

if (!config::PowerVR2Filter)
{
// Just handle shifting
// Just handle shifting and Y flipping
if (gl.gl_major < 3)
{
glBindFramebuffer(GL_FRAMEBUFFER, output_fbo);
Expand All @@ -301,7 +305,7 @@ void PostProcessor::render(GLuint output_fbo)
vertices[1] = vertices[11] = 1.f - gl.ofbo.shiftY * 2.f / framebuffer->getHeight();
vertices[6] = vertices[16] = vertices[1] - 2;
glcache.Disable(GL_BLEND);
drawQuad(framebuffer->getTexture(), false, false, vertices);
drawQuad(framebuffer->getTexture(), false, true, vertices);
}
else
{
Expand All @@ -311,7 +315,7 @@ void PostProcessor::render(GLuint output_fbo)
glcache.ClearColor(VO_BORDER_COL.red(), VO_BORDER_COL.green(), VO_BORDER_COL.blue(), 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glBlitFramebuffer(-gl.ofbo.shiftX, gl.ofbo.shiftY, framebuffer->getWidth() - gl.ofbo.shiftX, framebuffer->getHeight() + gl.ofbo.shiftY,
0, 0, framebuffer->getWidth(), framebuffer->getHeight(),
0, framebuffer->getHeight(), framebuffer->getWidth(), 0,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, output_fbo);
#endif
Expand Down
18 changes: 8 additions & 10 deletions core/rend/transform_matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ class TransformMatrix

void CalcMatrices(const rend_context *renderingContext, int width = 0, int height = 0)
{
const int screenFlipY = (System == COORD_OPENGL && !config::EmulateFramebuffer) || System == COORD_DIRECTX ? -1 : 1;
constexpr int rttFlipY = System == COORD_DIRECTX ? -1 : 1;
constexpr int framebufferFlipY = System == COORD_DIRECTX ? -1 : 1;
constexpr int flipY = System == COORD_DIRECTX ? -1 : 1;

renderViewport = { width == 0 ? settings.display.width : width, height == 0 ? settings.display.height : height };
this->renderingContext = renderingContext;
Expand All @@ -114,8 +112,8 @@ class TransformMatrix
if (renderingContext->scaler_ctl.hscale)
dcViewport.x *= 2;
dcViewport.y = (float)(renderingContext->fb_Y_CLIP.max - renderingContext->fb_Y_CLIP.min + 1);
normalMatrix = glm::translate(glm::vec3(-1, -rttFlipY, 0))
* glm::scale(glm::vec3(2.0f / dcViewport.x, 2.0f / dcViewport.y * rttFlipY, 1.f));
normalMatrix = glm::translate(glm::vec3(-1, -flipY, 0))
* glm::scale(glm::vec3(2.0f / dcViewport.x, 2.0f / dcViewport.y * flipY, 1.f));
scissorMatrix = normalMatrix;
sidebarWidth = 0;
}
Expand All @@ -140,9 +138,9 @@ class TransformMatrix
else
sidebarWidth = 0;
float x_coef = 2.0f / dcViewport.x;
float y_coef = 2.0f / dcViewport.y * screenFlipY;
float y_coef = 2.0f / dcViewport.y * flipY;

glm::mat4 trans = glm::translate(glm::vec3(-1 + 2 * sidebarWidth, -screenFlipY, 0));
glm::mat4 trans = glm::translate(glm::vec3(-1 + 2 * sidebarWidth, -flipY, 0));

normalMatrix = trans
* glm::scale(glm::vec3(x_coef, y_coef, 1.f));
Expand All @@ -152,15 +150,15 @@ class TransformMatrix
normalMatrix = glm::scale(glm::vec3(1, 1, 1 / config::ExtraDepthScale))
* normalMatrix;

glm::mat4 vp_trans = glm::translate(glm::vec3(1, framebufferFlipY, 0));
glm::mat4 vp_trans = glm::translate(glm::vec3(1, flipY, 0));
if (renderingContext->isRTT)
{
vp_trans = glm::scale(glm::vec3(dcViewport.x / 2, dcViewport.y / 2 * framebufferFlipY, 1.f))
vp_trans = glm::scale(glm::vec3(dcViewport.x / 2, dcViewport.y / 2 * flipY, 1.f))
* vp_trans;
}
else
{
vp_trans = glm::scale(glm::vec3(renderViewport.x / 2, renderViewport.y / 2 * framebufferFlipY, 1.f))
vp_trans = glm::scale(glm::vec3(renderViewport.x / 2, renderViewport.y / 2 * flipY, 1.f))
* vp_trans;
}
viewportMatrix = vp_trans * normalMatrix;
Expand Down

0 comments on commit 5ffcdb5

Please sign in to comment.