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

Frame buffer related fixes. Zelda OOT pause screen works!

This commit is contained in:
Sergey Lipskiy 2013-06-02 22:20:44 +07:00
parent 3d2083d6a4
commit 797dfad57e
4 changed files with 79 additions and 24 deletions

View File

@ -136,6 +136,13 @@ void DepthBuffer_Destroy()
void DepthBuffer_SetBuffer( u32 address )
{
const FrameBuffer * pFrameBuffer = FrameBuffer_FindBuffer(address);
bool bNeedClear = false;
if (pFrameBuffer != NULL) {
bNeedClear = pFrameBuffer->changed > 0;
// FrameBuffer_RemoveBuffer(address);
}
DepthBuffer *current = depthBuffer.top;
// Search through saved depth buffers
@ -150,6 +157,8 @@ void DepthBuffer_SetBuffer( u32 address )
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, current->renderbuf);
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, frameBuffer.top->texture->glName);
if (bNeedClear)
OGL_ClearDepthBuffer();
}
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "DepthBuffer_SetBuffer( 0x%08X ); color buffer is 0x%08X\n",
@ -176,6 +185,8 @@ void DepthBuffer_SetBuffer( u32 address )
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, current->renderbuf);
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, frameBuffer.top->texture->glName);
if (bNeedClear)
OGL_ClearDepthBuffer();
}
#ifdef DEBUG

View File

@ -156,16 +156,18 @@ void FrameBuffer_Destroy()
void FrameBuffer_SaveBuffer( u32 address, u16 size, u16 width, u16 height )
{
frameBuffer.drawBuffer = GL_DRAW_FRAMEBUFFER;
FrameBuffer *current = frameBuffer.top;
//DepthBuffer_RemoveBuffer( address );
FrameBuffer *current = frameBuffer.top;
// Search through saved frame buffers
while (current != NULL)
{
if ((current->startAddress <= address) &&
(current->endAddress >= address))
{
if ((current->width != width) ||
(current->height != height) ||
if ((current->startAddress != address) ||
(current->width != width) ||
//(current->height != height) ||
(current->size != size) || // TODO FIX ME
(current->scaleX != OGL.scaleX) ||
(current->scaleY != OGL.scaleY))
@ -174,11 +176,9 @@ void FrameBuffer_SaveBuffer( u32 address, u16 size, u16 width, u16 height )
break;
}
current->startAddress = address;
current->endAddress = address + ((width * height << size >> 1) - 1);
current->texture->address = current->startAddress;
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo);
if (depthBuffer.top != NULL && depthBuffer.top->renderbuf > 0) {
ogl_glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer.top->renderbuf);
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer.top->renderbuf);
@ -229,8 +229,8 @@ void FrameBuffer_SaveBuffer( u32 address, u16 size, u16 width, u16 height )
current->texture->maskT = 0;
current->texture->mirrorS = 0;
current->texture->mirrorT = 0;
current->texture->realWidth = (u32)pow2( current->width * OGL.scaleX );
current->texture->realHeight = (u32)pow2( current->height * OGL.scaleY );
current->texture->realWidth = (u32)pow2( current->texture->width );
current->texture->realHeight = (u32)pow2( current->texture->height );
current->texture->textureBytes = current->texture->realWidth * current->texture->realHeight * 4;
cache.cachedBytes += current->texture->textureBytes;
@ -281,12 +281,23 @@ void FrameBuffer_RenderBuffer( u32 address )
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer( GL_FRONT );
ogl_glBlitFramebuffer(
0, 0, min(OGL.width, current->texture->realWidth), min(OGL.height, current->texture->realHeight),
// 0, 0, current->texture->realWidth, current->texture->realHeight,
0, 0, OGL.width, OGL.height,
0, OGL.heightOffset, OGL.width, OGL.height+OGL.heightOffset,
GL_COLOR_BUFFER_BIT, GL_LINEAR
);
glDrawBuffer( GL_BACK );
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
/*
current = current->lower;
while (current != NULL)
{
if ((current->startAddress <= address) &&
(current->endAddress >= address))
assert(false);
current = current->lower;
}
*/
return;
}
current = current->lower;
@ -303,6 +314,19 @@ void FrameBuffer_RenderBuffer( u32 address )
if ((current->startAddress <= address) &&
(current->endAddress >= address))
{
/*
float fill_color[4] = {1.0f, 0.0f, 0.0f, 1.0f};
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo);
ogl_glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer.top->renderbuf);
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer.top->renderbuf);
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, current->texture->glName);
assert(checkFBO());
OGL_ClearDepthBuffer();
OGL_ClearColorBuffer(fill_color);
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
*/
glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT );
Combiner_BeginTextureUpdate();
@ -509,6 +533,6 @@ void FrameBuffer_ActivateBufferTexture( s16 t, FrameBuffer *buffer )
buffer->texture->offsetT = (float)buffer->height - (gDP.textureImage.address - buffer->startAddress) / (buffer->width << buffer->size >> 1);
}
FrameBuffer_MoveToTop( buffer );
// FrameBuffer_RenderBuffer(buffer->startAddress);
TextureCache_ActivateTexture( t, buffer->texture );
}

View File

@ -579,8 +579,13 @@ void OGL_UpdateCullFace()
void OGL_UpdateViewport()
{
glViewport( gSP.viewport.x * OGL.scaleX, (VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0),
if (frameBuffer.drawBuffer == GL_BACK)
glViewport( gSP.viewport.x * OGL.scaleX, (VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset,
gSP.viewport.width * OGL.scaleX, gSP.viewport.height * OGL.scaleY );
else
glViewport( gSP.viewport.x * OGL.scaleX, (frameBuffer.top->height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY,
gSP.viewport.width * OGL.scaleX, gSP.viewport.height * OGL.scaleY );
glDepthRange( 0.0f, 1.0f );//gSP.viewport.nearz, gSP.viewport.farz );
}
@ -657,7 +662,8 @@ void OGL_UpdateStates()
if (gDP.changed & CHANGED_SCISSOR)
{
glScissor( gDP.scissor.ulx * OGL.scaleX, (VI.height - gDP.scissor.lry) * OGL.scaleY + (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0),
const u32 screenHeight = (frameBuffer.top == NULL || frameBuffer.drawBuffer == GL_BACK) ? VI.height : frameBuffer.top->height;
glScissor( gDP.scissor.ulx * OGL.scaleX, (screenHeight - gDP.scissor.lry) * OGL.scaleY + (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0),
(gDP.scissor.lrx - gDP.scissor.ulx) * OGL.scaleX, (gDP.scissor.lry - gDP.scissor.uly) * OGL.scaleY );
}
@ -929,6 +935,11 @@ void OGL_DrawRect( int ulx, int uly, int lrx, int lry, float *color )
glDisable( GL_CULL_FACE );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
u32 width = VI.width, height = VI.height;
if (frameBuffer.top != NULL && frameBuffer.drawBuffer != GL_BACK) {
width = frameBuffer.top->width;
height = frameBuffer.top->height;
}
glOrtho( 0, VI.width, VI.height, 0, 1.0f, -1.0f );
glViewport( 0, (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), OGL.width, OGL.height );
glDepthRange( 0.0f, 1.0f );
@ -960,10 +971,14 @@ void OGL_DrawTexturedRect( float ulx, float uly, float lrx, float lry, float uls
glDisable( GL_CULL_FACE );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, VI.width, VI.height, 0, 1.0f, -1.0f );
glViewport( 0, (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), OGL.width, OGL.height );
glLoadIdentity();
if (frameBuffer.drawBuffer != GL_DRAW_FRAMEBUFFER) {
glOrtho( 0, VI.width, VI.height, 0, 1.0f, -1.0f );
glViewport( 0, (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), OGL.width, OGL.height );
} else {
glOrtho( 0, frameBuffer.top->width, frameBuffer.top->height, 0, 1.0f, -1.0f );
glViewport( 0, 0, frameBuffer.top->width*frameBuffer.top->scaleX, frameBuffer.top->height*frameBuffer.top->scaleY );
}
if (combiner.usesT0)
{
rect[0].s0 = rect[0].s0 * cache.current[0]->shiftScaleS - gSP.textureTile[0]->fuls;

21
gDP.cpp
View File

@ -346,12 +346,17 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
}*/
address = RSP_SegmentToPhysical( address );
if (gDP.colorImage.address != address)
if (gDP.colorImage.address != address || gDP.colorImage.width != width)
{
if (OGL.frameBufferTextures && address != gDP.depthImageAddress)
if (width >= gDP.scissor.lrx-1 && width <= gDP.scissor.lrx+1)
gDP.colorImage.height = gDP.scissor.lry;
else if (width >= gSP.viewport.width-1 && width <= gSP.viewport.width+1)
gDP.colorImage.height = gSP.viewport.height;
if (OGL.frameBufferTextures)// && address != gDP.depthImageAddress)
{
//if (gDP.colorImage.changed)
FrameBuffer_SaveBuffer( address, (u16)size, (u16)width, width == VI.width ? (u16)VI.height : 1 );
FrameBuffer_SaveBuffer( address, (u16)size, (u16)width, gDP.colorImage.height );
//if (address != gDP.depthImageAddress)
//FrameBuffer_RestoreBuffer( address, (u16)size, (u16)width );
@ -361,10 +366,10 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
gDP.colorImage.changed = FALSE;
if (width == VI.width)
gDP.colorImage.height = VI.height;
else
gDP.colorImage.height = 1;
// if (width == VI.width)
// gDP.colorImage.height = VI.height;
// else
// gDP.colorImage.height = 1;
}
gDP.colorImage.format = format;
@ -871,7 +876,7 @@ void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f
gSP.textureTile[0] = &gDP.tiles[gSP.texture.tile];
gSP.textureTile[1] = &gDP.tiles[gSP.texture.tile < 7 ? gSP.texture.tile + 1 : gSP.texture.tile];
if (depthBuffer.current) depthBuffer.current->cleared = FALSE;
if (depthBuffer.top) depthBuffer.top->cleared = FALSE;
gDP.colorImage.changed = TRUE;
gDP.colorImage.height = max( gDP.colorImage.height, (u32)gDP.scissor.lry );