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

245 lines
5.6 KiB
C++
Raw Normal View History

#include <malloc.h>
#include <assert.h>
2013-06-01 13:10:30 +00:00
#include "OpenGL.h"
2013-12-14 14:30:20 +00:00
#include "Combiner.h"
2013-06-01 13:10:30 +00:00
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "VI.h"
#include "Config.h"
2013-06-01 13:10:30 +00:00
#include "Debug.h"
2013-12-14 14:30:20 +00:00
const GLuint ZlutImageUnit = 0;
const GLuint TlutImageUnit = 1;
const GLuint depthImageUnit = 2;
void DepthBuffer_Init()
{
DepthBufferList & dbList = depthBufferList();
dbList.current = NULL;
dbList.top = NULL;
dbList.bottom = NULL;
dbList.numBuffers = 0;
}
void DepthBuffer_RemoveBottom()
{
DepthBufferList & dbList = depthBufferList();
DepthBuffer *newBottom = dbList.bottom->higher;
if (dbList.bottom == dbList.top)
dbList.top = NULL;
if (dbList.bottom->renderbuf != 0)
glDeleteRenderbuffers(1, &dbList.bottom->renderbuf);
if (dbList.bottom->depth_texture != NULL)
textureCache().removeFrameBufferTexture(dbList.bottom->depth_texture);
free( dbList.bottom );
dbList.bottom = newBottom;
if (dbList.bottom != NULL)
dbList.bottom->lower = NULL;
dbList.numBuffers--;
}
void DepthBuffer_Remove( DepthBuffer *buffer )
{
DepthBufferList & dbList = depthBufferList();
if ((buffer == dbList.bottom) &&
(buffer == dbList.top))
{
dbList.top = NULL;
dbList.bottom = NULL;
}
else if (buffer == dbList.bottom)
{
dbList.bottom = buffer->higher;
if (dbList.bottom)
dbList.bottom->lower = NULL;
}
else if (buffer == dbList.top)
{
dbList.top = buffer->lower;
if (dbList.top)
dbList.top->higher = NULL;
}
else
{
buffer->higher->lower = buffer->lower;
buffer->lower->higher = buffer->higher;
}
2013-06-01 13:10:30 +00:00
if (buffer->renderbuf != 0)
2014-03-21 09:38:39 +00:00
glDeleteRenderbuffers(1, &buffer->renderbuf);
2013-11-12 07:35:26 +00:00
if (buffer->fbo != 0)
2014-03-21 09:38:39 +00:00
glDeleteFramebuffers(1, &buffer->fbo);
2013-10-30 06:07:24 +00:00
if (buffer->depth_texture != NULL)
textureCache().removeFrameBufferTexture(buffer->depth_texture);
free( buffer );
dbList.numBuffers--;
}
void DepthBuffer_RemoveBuffer( u32 address )
{
DepthBuffer *current = depthBufferList().bottom;
while (current != NULL)
{
if (current->address == address)
{
DepthBuffer_Remove( current );
return;
}
current = current->higher;
}
}
DepthBuffer *DepthBuffer_AddTop()
{
DepthBufferList & dbList = depthBufferList();
DepthBuffer *newtop = (DepthBuffer*)malloc( sizeof( DepthBuffer ) );
newtop->lower = dbList.top;
newtop->higher = NULL;
2013-06-01 13:10:30 +00:00
newtop->renderbuf = 0;
2013-11-12 07:35:26 +00:00
newtop->fbo = 0;
if (dbList.top)
dbList.top->higher = newtop;
if (!dbList.bottom)
dbList.bottom = newtop;
dbList.top = newtop;
dbList.numBuffers++;
return newtop;
}
void DepthBuffer_MoveToTop( DepthBuffer *newtop )
{
DepthBufferList & dbList = depthBufferList();
if (newtop == dbList.top)
return;
if (newtop == dbList.bottom)
{
dbList.bottom = newtop->higher;
dbList.bottom->lower = NULL;
}
else
{
newtop->higher->lower = newtop->lower;
newtop->lower->higher = newtop->higher;
}
newtop->higher = NULL;
newtop->lower = dbList.top;
dbList.top->higher = newtop;
dbList.top = newtop;
}
void DepthBuffer_Destroy()
{
DepthBufferList & dbList = depthBufferList();
while (dbList.bottom)
DepthBuffer_RemoveBottom();
dbList.top = dbList.bottom = dbList.current = NULL;
}
void DepthBuffer_SetBuffer( u32 address )
{
DepthBufferList & dbList = depthBufferList();
FrameBuffer * pFrameBuffer = frameBufferList().findBuffer(address);
if (pFrameBuffer == NULL)
pFrameBuffer = frameBufferList().getCurrent();
DepthBuffer *current = dbList.top;
// Search through saved depth buffers
while (current != NULL)
{
if (current->address == address)
{
if (pFrameBuffer != NULL && current->width != pFrameBuffer->m_width) {
DepthBuffer_Remove( current );
current = NULL;
break;
}
DepthBuffer_MoveToTop( current );
break;
}
current = current->lower;
}
if (current == NULL) {
current = DepthBuffer_AddTop();
current->address = address;
current->width = pFrameBuffer != NULL ? pFrameBuffer->m_width : VI.width;
2013-10-30 06:07:24 +00:00
current->depth_texture = NULL;
if (config.frameBufferEmulation.enable) {
2014-03-21 09:38:39 +00:00
glGenRenderbuffers(1, &current->renderbuf);
glBindRenderbuffer(GL_RENDERBUFFER, current->renderbuf);
#ifndef GLES2
const GLenum format = GL_DEPTH_COMPONENT;
#else
const GLenum format = GL_DEPTH_COMPONENT24_OES;
#endif
if (pFrameBuffer != NULL)
glRenderbufferStorage(GL_RENDERBUFFER, format, pFrameBuffer->m_pTexture->realWidth, pFrameBuffer->m_pTexture->realHeight);
else
glRenderbufferStorage(GL_RENDERBUFFER, format, (u32)pow2(OGL.width), (u32)pow2(OGL.height));
}
}
if (config.frameBufferEmulation.enable) {
frameBufferList().attachDepthBuffer();
2013-06-01 13:10:30 +00:00
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "DepthBuffer_SetBuffer( 0x%08X ); color buffer is 0x%08X\n",
address, ( pFrameBuffer != NULL && pFrameBuffer->m_FBO > 0) ? pFrameBuffer->m_startAddress : 0
2013-06-01 13:10:30 +00:00
);
#endif
2013-06-01 13:10:30 +00:00
}
dbList.current = current;
}
DepthBuffer *DepthBuffer_FindBuffer( u32 address )
{
DepthBufferList & dbList = depthBufferList();
DepthBuffer *current = dbList.top;
while (current)
{
if (current->address == address)
return current;
current = current->lower;
}
return NULL;
}
2013-12-14 14:30:20 +00:00
void DepthBuffer_ClearBuffer() {
#ifndef GLES2
2013-12-15 17:20:12 +00:00
if (!OGL.bImageTexture)
return;
DepthBuffer *current = depthBufferList().top;
2013-12-14 14:30:20 +00:00
if (current == NULL || current->fbo == 0)
return;
float color[4] = {1.0f, 1.0f, 0.0f, 1.0f};
2013-12-14 14:30:20 +00:00
glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
2014-03-21 09:38:39 +00:00
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo);
2013-12-14 14:30:20 +00:00
OGL_DrawRect(0,0,VI.width, VI.height, color);
2013-12-15 17:20:12 +00:00
glBindImageTexture(depthImageUnit, current->depth_texture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO);
#endif // GLES2
2013-12-14 14:30:20 +00:00
}