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

246 lines
8.0 KiB
C++
Raw Normal View History

2014-10-13 12:38:51 +00:00
#ifdef OS_MAC_OS_X
#include <malloc/malloc.h>
#else
#include <malloc.h>
2014-10-13 12:38:51 +00:00
#endif
#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;
2015-01-27 16:00:06 +00:00
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_FBO(0), m_pDepthImageTexture(NULL), m_pDepthBufferTexture(NULL)
{
2014-09-08 11:00:13 +00:00
glGenFramebuffers(1, &m_FBO);
}
2014-09-08 11:00:13 +00:00
DepthBuffer::DepthBuffer(DepthBuffer && _other) :
m_address(_other.m_address), m_width(_other.m_width),
2015-01-27 16:00:06 +00:00
m_FBO(_other.m_FBO), m_pDepthImageTexture(_other.m_pDepthImageTexture), m_pDepthBufferTexture(_other.m_pDepthBufferTexture)
{
2014-09-08 11:00:13 +00:00
_other.m_FBO = 0;
2015-01-27 16:00:06 +00:00
_other.m_pDepthImageTexture = NULL;
_other.m_pDepthBufferTexture = NULL;
}
2014-09-08 11:00:13 +00:00
DepthBuffer::~DepthBuffer()
{
2014-09-08 11:00:13 +00:00
if (m_FBO != 0)
glDeleteFramebuffers(1, &m_FBO);
2015-01-27 16:00:06 +00:00
if (m_pDepthImageTexture != NULL)
textureCache().removeFrameBufferTexture(m_pDepthImageTexture);
if (m_pDepthBufferTexture != NULL)
textureCache().removeFrameBufferTexture(m_pDepthBufferTexture);
}
2015-01-27 16:00:06 +00:00
void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
{
#ifdef GL_IMAGE_TEXTURES_SUPPORT
2015-01-27 16:00:06 +00:00
if (m_pDepthImageTexture != NULL)
return;
m_pDepthImageTexture = textureCache().addFrameBufferTexture();
m_pDepthImageTexture->width = (u32)(_pBuffer->m_pTexture->width);
m_pDepthImageTexture->height = (u32)(_pBuffer->m_pTexture->height);
m_pDepthImageTexture->format = 0;
m_pDepthImageTexture->size = 2;
m_pDepthImageTexture->clampS = 1;
m_pDepthImageTexture->clampT = 1;
m_pDepthImageTexture->address = _pBuffer->m_startAddress;
m_pDepthImageTexture->clampWidth = _pBuffer->m_width;
m_pDepthImageTexture->clampHeight = _pBuffer->m_height;
m_pDepthImageTexture->frameBufferTexture = TRUE;
m_pDepthImageTexture->maskS = 0;
m_pDepthImageTexture->maskT = 0;
m_pDepthImageTexture->mirrorS = 0;
m_pDepthImageTexture->mirrorT = 0;
m_pDepthImageTexture->realWidth = m_pDepthImageTexture->width;
m_pDepthImageTexture->realHeight = m_pDepthImageTexture->height;
m_pDepthImageTexture->textureBytes = m_pDepthImageTexture->realWidth * m_pDepthImageTexture->realHeight * 4 * 4; // Width*Height*RGBA*sizeof(GL_RGBA32F)
textureCache().addFrameBufferTextureSize(m_pDepthImageTexture->textureBytes);
glBindTexture( GL_TEXTURE_2D, m_pDepthImageTexture->glName );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_pDepthImageTexture->realWidth, m_pDepthImageTexture->realHeight, 0, GL_RGBA, GL_FLOAT, NULL);
2015-01-18 13:43:06 +00:00
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2014-09-08 11:00:13 +00:00
glBindTexture( GL_TEXTURE_2D, 0);
2015-01-27 16:00:06 +00:00
2014-09-08 11:00:13 +00:00
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
2015-01-27 16:00:06 +00:00
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pDepthImageTexture->glName, 0);
2014-09-08 11:00:13 +00:00
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
2015-01-27 16:00:06 +00:00
2014-09-08 11:00:13 +00:00
depthBufferList().clearBuffer();
#endif // GL_IMAGE_TEXTURES_SUPPORT
}
2015-01-27 16:00:06 +00:00
void DepthBuffer::initDepthBufferTexture(FrameBuffer * _pBuffer)
{
if (m_pDepthBufferTexture != NULL)
return;
m_pDepthBufferTexture = textureCache().addFrameBufferTexture();
if (_pBuffer != NULL) {
m_pDepthBufferTexture->width = (u32)(_pBuffer->m_pTexture->width);
m_pDepthBufferTexture->height = (u32)(_pBuffer->m_pTexture->height);
m_pDepthBufferTexture->address = _pBuffer->m_startAddress;
m_pDepthBufferTexture->clampWidth = _pBuffer->m_width;
m_pDepthBufferTexture->clampHeight = _pBuffer->m_height;
}
else {
m_pDepthBufferTexture->width = video().getWidth();
m_pDepthBufferTexture->height = video().getHeight();
m_pDepthBufferTexture->address = VI.lastOrigin;
m_pDepthBufferTexture->clampWidth = VI.width;
m_pDepthBufferTexture->clampHeight = VI.height;
}
m_pDepthBufferTexture->format = 0;
m_pDepthBufferTexture->size = 2;
m_pDepthBufferTexture->clampS = 1;
m_pDepthBufferTexture->clampT = 1;
m_pDepthBufferTexture->frameBufferTexture = TRUE;
m_pDepthBufferTexture->maskS = 0;
m_pDepthBufferTexture->maskT = 0;
m_pDepthBufferTexture->mirrorS = 0;
m_pDepthBufferTexture->mirrorT = 0;
m_pDepthBufferTexture->realWidth = m_pDepthBufferTexture->width;
m_pDepthBufferTexture->realHeight = m_pDepthBufferTexture->height;
m_pDepthBufferTexture->textureBytes = m_pDepthBufferTexture->realWidth * m_pDepthBufferTexture->realHeight * sizeof(float);
textureCache().addFrameBufferTextureSize(m_pDepthBufferTexture->textureBytes);
#ifndef GLES2
const GLenum format = GL_DEPTH_COMPONENT;
#else
const GLenum format = GL_DEPTH_COMPONENT24_OES;
#endif
glBindTexture( GL_TEXTURE_2D, m_pDepthBufferTexture->glName );
if (_pBuffer != NULL)
glTexImage2D(GL_TEXTURE_2D, 0, format, _pBuffer->m_pTexture->realWidth, _pBuffer->m_pTexture->realHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
else
glTexImage2D(GL_TEXTURE_2D, 0, format, video().getWidth(), video().getHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glBindTexture( GL_TEXTURE_2D, 0);
}
void DepthBuffer::setDepthAttachment() {
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_pDepthBufferTexture->glName, 0);
}
void DepthBuffer::activateDepthBufferTexture() {
textureCache().activateTexture(0, m_pDepthBufferTexture);
}
void DepthBuffer::bindDepthImageTexture() {
#ifdef GL_IMAGE_TEXTURES_SUPPORT
glBindImageTexture(depthImageUnit, m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
#endif
}
2014-09-08 11:00:13 +00:00
void DepthBufferList::init()
{
2014-09-08 11:00:13 +00:00
m_pCurrent = NULL;
}
2014-09-08 11:00:13 +00:00
void DepthBufferList::destroy()
{
2014-09-08 11:00:13 +00:00
m_pCurrent = NULL;
m_list.clear();
}
2014-09-08 11:00:13 +00:00
DepthBuffer * DepthBufferList::findBuffer(u32 _address)
{
2014-09-08 11:00:13 +00:00
for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
if (iter->m_address == _address)
return &(*iter);
return NULL;
}
2014-09-08 11:00:13 +00:00
void DepthBufferList::removeBuffer(u32 _address )
{
for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
if (iter->m_address == _address) {
m_list.erase(iter);
return;
}
}
2014-09-08 11:00:13 +00:00
void DepthBufferList::saveBuffer(u32 _address)
{
2014-09-08 11:00:13 +00:00
if (!config.frameBufferEmulation.enable)
return;
FrameBuffer * pFrameBuffer = frameBufferList().findBuffer(_address);
if (pFrameBuffer == NULL)
pFrameBuffer = frameBufferList().getCurrent();
2014-09-08 11:00:13 +00:00
if (m_pCurrent == NULL || m_pCurrent->m_address != _address)
m_pCurrent = findBuffer(_address);
if (m_pCurrent != NULL && pFrameBuffer != NULL && m_pCurrent->m_width != pFrameBuffer->m_width) {
removeBuffer(_address);
m_pCurrent = NULL;
}
2014-09-08 11:00:13 +00:00
if (m_pCurrent == NULL) {
m_list.emplace_front();
DepthBuffer & buffer = m_list.front();
2014-09-08 11:00:13 +00:00
buffer.m_address = _address;
buffer.m_width = pFrameBuffer != NULL ? pFrameBuffer->m_width : VI.width;
2015-01-27 16:00:06 +00:00
buffer.initDepthBufferTexture(pFrameBuffer);
2014-09-08 11:00:13 +00:00
m_pCurrent = &buffer;
}
2014-09-08 11:00:13 +00:00
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
}
2014-09-08 11:00:13 +00:00
void DepthBufferList::clearBuffer()
{
#ifdef GL_IMAGE_TEXTURES_SUPPORT
if (!video().getRender().isImageTexturesSupported())
2013-12-15 17:20:12 +00:00
return;
2014-09-08 11:00:13 +00:00
if (m_pCurrent == NULL || m_pCurrent->m_FBO == 0)
2013-12-14 14:30:20 +00:00
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-09-08 11:00:13 +00:00
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO);
const u32 cycleType = gDP.otherMode.cycleType;
gDP.otherMode.cycleType = G_CYC_FILL;
video().getRender().drawRect(0,0,VI.width, VI.height, color);
gDP.otherMode.cycleType = cycleType;
2015-01-27 16:00:06 +00:00
glBindImageTexture(depthImageUnit, m_pCurrent->m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO);
#endif // GL_IMAGE_TEXTURES_SUPPORT
2013-12-14 14:30:20 +00:00
}
2014-09-08 11:00:13 +00:00
void DepthBuffer_Init()
{
depthBufferList().init();
}
void DepthBuffer_Destroy()
{
depthBufferList().destroy();
}