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:
parent
066ebc8b47
commit
467cc44185
41
gSP.cpp
41
gSP.cpp
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user