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

Implement depth buffer copy to correctly emulate LoT in Zelda MM.

OpenGL depth and color buffers have different format, so
direct copy is impossible. Thus, special function for that special case
has been implemented.
This commit is contained in:
Sergey Lipskiy 2014-01-08 23:25:45 +07:00
parent 066ebc8b47
commit 467cc44185

41
gSP.cpp
View File

@ -1444,6 +1444,37 @@ void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag )
#endif
}
static
void _copyDepthBuffer()
{
if (!OGL.frameBufferTextures)
return;
// The game copies content of depth buffer into current color buffer
// OpenGL has different format for color and depth buffers, so this trick can't be performed directly
// To do that, depth buffer with address of current color buffer created and attached to the current FBO
// It will be copy depth buffer
DepthBuffer_SetBuffer(gDP.colorImage.address);
// Take any frame buffer and attach source depth buffer to it, to blit it into copy depth buffer
FrameBuffer * pTmpBuffer = frameBuffer.top->lower;
DepthBuffer * pTmpBufferDepth = pTmpBuffer->pDepthBuffer;
pTmpBuffer->pDepthBuffer = DepthBuffer_FindBuffer(gSP.bgImage.address);
ogl_glBindFramebuffer(GL_READ_FRAMEBUFFER, pTmpBuffer->fbo);
ogl_glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pTmpBuffer->pDepthBuffer->renderbuf);
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, pTmpBuffer->texture->glName);
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
ogl_glBlitFramebuffer(
0, 0, OGL.width, OGL.height,
0, 0, OGL.width, OGL.height,
GL_DEPTH_BUFFER_BIT, GL_NEAREST
);
// Restore objects
ogl_glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pTmpBufferDepth->renderbuf);
ogl_glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// Set back current depth buffer
DepthBuffer_SetBuffer(gDP.depthImageAddress);
}
static
void loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale)
{
@ -1483,6 +1514,11 @@ void gSPBgRect1Cyc( u32 bg )
uObjScaleBg *objScaleBg = (uObjScaleBg*)&RDRAM[address];
loadBGImage(objScaleBg, true);
if (gSP.bgImage.address == gDP.depthImageAddress || DepthBuffer_FindBuffer(gSP.bgImage.address) != NULL) {
_copyDepthBuffer();
return;
}
f32 imageX = gSP.bgImage.imageX;
f32 imageY = gSP.bgImage.imageY;
f32 imageW = _FIXED2FLOAT( objScaleBg->imageW, 2);
@ -1561,6 +1597,11 @@ void gSPBgRectCopy( u32 bg )
uObjScaleBg *objBg = (uObjScaleBg*)&RDRAM[address];
loadBGImage(objBg, false);
if (gSP.bgImage.address == gDP.depthImageAddress || DepthBuffer_FindBuffer(gSP.bgImage.address) != NULL) {
_copyDepthBuffer();
return;
}
f32 frameX = objBg->frameX / 4.0f;
f32 frameY = objBg->frameY / 4.0f;
u16 frameW = objBg->frameW >> 2;