1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-07 03:13:49 +00:00

Rewrite FrameBufferList::renderBuffer

Use new method for destination coordinates calculation.
This commit is contained in:
Sergey Lipskiy 2014-10-10 17:22:10 +07:00
parent 0d35f461df
commit 17479ccbe4

View File

@ -330,7 +330,7 @@ void FrameBuffer_Destroy()
#ifndef GLES2 #ifndef GLES2
void FrameBufferList::renderBuffer(u32 _address) void FrameBufferList::renderBuffer(u32 _address)
{ {
static u32 vStartPrev = 0; static s32 vStartPrev = 0;
if (VI.width == 0) // H width is zero. Don't draw if (VI.width == 0) // H width is zero. Don't draw
return; return;
@ -341,8 +341,25 @@ void FrameBufferList::renderBuffer(u32 _address)
OGLVideo & ogl = video(); OGLVideo & ogl = video();
GLint srcY0, srcY1, dstY0, dstY1; GLint srcY0, srcY1, dstY0, dstY1;
GLint partHeight = 0; GLint srcPartHeight = 0;
const u32 vStart = _SHIFTR( *REG.VI_V_START, 17, 9 ); GLint dstPartHeight = 0;
const f32 yScale = _FIXED2FLOAT(_SHIFTR(*REG.VI_Y_SCALE, 0, 12), 10);
s32 vEnd = _SHIFTR(*REG.VI_V_START, 0, 10);
s32 vStart = _SHIFTR(*REG.VI_V_START, 16, 10);
const s32 vSync = (*REG.VI_V_SYNC) & 0x03FF;
const bool interlaced = (*REG.VI_STATUS & 0x40) != 0;
const bool isPAL = vSync > 550;
const s32 vShift = (isPAL ? 47 : 37);
dstY0 = vStart - vShift;
dstY0 >>= 1;
dstY0 &= -(dstY0 >= 0);
vStart >>= 1;
vEnd >>= 1;
const u32 vFullHeight = isPAL ? 288 : 240;
const u32 vCurrentHeight = vEnd - vStart;
const float dstScaleY = (float)ogl.getHeight() / float(vFullHeight);
bool isLowerField = false; bool isLowerField = false;
if ((*REG.VI_STATUS & 0x40) != 0) if ((*REG.VI_STATUS & 0x40) != 0)
isLowerField = vStart > vStartPrev; isLowerField = vStart > vStartPrev;
@ -352,15 +369,17 @@ void FrameBufferList::renderBuffer(u32 _address)
if (isLowerField) if (isLowerField)
--srcY0; --srcY0;
srcY1 = srcY0 + VI.real_height; if (srcY0 + vCurrentHeight > vFullHeight) {
if (srcY1 > VI.height) { dstPartHeight = srcY0;
partHeight = srcY1 - VI.height; srcY0 = (GLint)(srcY0*yScale);
srcY1 = VI.height; srcPartHeight = srcY0;
dstY0 = 1; srcY1 = VI.real_height;
dstY1 = dstY0 + VI.real_height - partHeight; dstY1 = dstY0 + vCurrentHeight - dstPartHeight;
} else { } else {
dstY0 = srcY0; dstY0 += srcY0;
dstY1 = srcY1; dstY1 = dstY0 + vCurrentHeight;
srcY0 = (GLint)(srcY0*yScale);
srcY1 = srcY0 + VI.real_height;
} }
// glDisable(GL_SCISSOR_TEST) does not affect glBlitFramebuffer, at least on AMD // glDisable(GL_SCISSOR_TEST) does not affect glBlitFramebuffer, at least on AMD
@ -371,27 +390,29 @@ void FrameBufferList::renderBuffer(u32 _address)
//glDrawBuffer( GL_BACK ); //glDrawBuffer( GL_BACK );
float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
ogl.getRender().clearColorBuffer(clearColor); ogl.getRender().clearColorBuffer(clearColor);
const float scaleY = ogl.getScaleY(); const float srcScaleY = ogl.getScaleY();
const float hOffset = (ogl.getScreenWidth() - ogl.getWidth()) / 2.0f; const GLint hOffset = (ogl.getScreenWidth() - ogl.getWidth()) / 2;
const float vOffset = (ogl.getScreenHeight() - ogl.getHeight()) / 2.0f; GLint vOffset = (ogl.getScreenHeight() - ogl.getHeight()) / 2;
if (!ogl.isFullscreen())
vOffset += ogl.getHeightOffset();
glBlitFramebuffer( glBlitFramebuffer(
0, (GLint)(srcY0*scaleY), ogl.getWidth(), (GLint)(srcY1*scaleY), 0, (GLint)(srcY0*srcScaleY), ogl.getWidth(), (GLint)(srcY1*srcScaleY),
hOffset, vOffset + ogl.getHeightOffset() + (GLint)(dstY0*scaleY), hOffset + ogl.getWidth(), vOffset + ogl.getHeightOffset() + (GLint)(dstY1*scaleY), hOffset, vOffset + (GLint)(dstY0*dstScaleY), hOffset + ogl.getWidth(), vOffset + (GLint)(dstY1*dstScaleY),
GL_COLOR_BUFFER_BIT, GL_LINEAR GL_COLOR_BUFFER_BIT, GL_LINEAR
); );
if (partHeight > 0) { if (dstPartHeight > 0) {
const u32 size = *REG.VI_STATUS & 3; const u32 size = *REG.VI_STATUS & 3;
pBuffer = findBuffer(_address + (((*REG.VI_WIDTH)*VI.height)<<size>>1)); pBuffer = findBuffer(_address + (((*REG.VI_WIDTH)*VI.height)<<size>>1));
if (pBuffer != NULL) { if (pBuffer != NULL) {
srcY0 = 0; srcY0 = 0;
srcY1 = partHeight; srcY1 = srcPartHeight;
dstY0 = dstY1; dstY0 = dstY1;
dstY1 = dstY0 + partHeight; dstY1 = dstY0 + dstPartHeight;
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO);
glBlitFramebuffer( glBlitFramebuffer(
0, (GLint)(srcY0*scaleY), ogl.getWidth(), (GLint)(srcY1*scaleY), 0, (GLint)(srcY0*srcScaleY), ogl.getWidth(), (GLint)(srcY1*srcScaleY),
hOffset, vOffset + ogl.getHeightOffset() + (GLint)(dstY0*scaleY), hOffset + ogl.getWidth(), vOffset + ogl.getHeightOffset() + (GLint)(dstY1*scaleY), hOffset, vOffset + (GLint)(dstY0*dstScaleY), hOffset + ogl.getWidth(), vOffset + (GLint)(dstY1*dstScaleY),
GL_COLOR_BUFFER_BIT, GL_LINEAR GL_COLOR_BUFFER_BIT, GL_LINEAR
); );
} }