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

Switch to depth texture

This commit is contained in:
Sergey Lipskiy 2015-01-27 22:00:06 +06:00
parent 0197bfa104
commit afe91d47d9
8 changed files with 166 additions and 87 deletions

View File

@ -16,72 +16,138 @@ const GLuint ZlutImageUnit = 0;
const GLuint TlutImageUnit = 1;
const GLuint depthImageUnit = 2;
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_renderbuf(0), m_FBO(0), m_pDepthTexture(NULL)
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_FBO(0), m_pDepthImageTexture(NULL), m_pDepthBufferTexture(NULL)
{
glGenRenderbuffers(1, &m_renderbuf);
glGenFramebuffers(1, &m_FBO);
}
DepthBuffer::DepthBuffer(DepthBuffer && _other) :
m_address(_other.m_address), m_width(_other.m_width),
m_renderbuf(_other.m_renderbuf), m_FBO(_other.m_FBO), m_pDepthTexture(_other.m_pDepthTexture)
m_FBO(_other.m_FBO), m_pDepthImageTexture(_other.m_pDepthImageTexture), m_pDepthBufferTexture(_other.m_pDepthBufferTexture)
{
_other.m_renderbuf = 0;
_other.m_FBO = 0;
_other.m_pDepthTexture = NULL;
_other.m_pDepthImageTexture = NULL;
_other.m_pDepthBufferTexture = NULL;
}
DepthBuffer::~DepthBuffer()
{
if (m_renderbuf != 0)
glDeleteRenderbuffers(1, &m_renderbuf);
if (m_FBO != 0)
glDeleteFramebuffers(1, &m_FBO);
if (m_pDepthTexture != NULL)
textureCache().removeFrameBufferTexture(m_pDepthTexture);
if (m_pDepthImageTexture != NULL)
textureCache().removeFrameBufferTexture(m_pDepthImageTexture);
if (m_pDepthBufferTexture != NULL)
textureCache().removeFrameBufferTexture(m_pDepthBufferTexture);
}
void DepthBuffer::initDepthTexture(FrameBuffer * _pBuffer)
void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
{
#ifdef GL_IMAGE_TEXTURES_SUPPORT
if (m_pDepthTexture != NULL)
textureCache().removeFrameBufferTexture(m_pDepthTexture);
m_pDepthTexture = textureCache().addFrameBufferTexture();
if (m_pDepthImageTexture != NULL)
return;
m_pDepthTexture->width = (u32)(_pBuffer->m_pTexture->width);
m_pDepthTexture->height = (u32)(_pBuffer->m_pTexture->height);
m_pDepthTexture->format = 0;
m_pDepthTexture->size = 2;
m_pDepthTexture->clampS = 1;
m_pDepthTexture->clampT = 1;
m_pDepthTexture->address = _pBuffer->m_startAddress;
m_pDepthTexture->clampWidth = _pBuffer->m_width;
m_pDepthTexture->clampHeight = _pBuffer->m_height;
m_pDepthTexture->frameBufferTexture = TRUE;
m_pDepthTexture->maskS = 0;
m_pDepthTexture->maskT = 0;
m_pDepthTexture->mirrorS = 0;
m_pDepthTexture->mirrorT = 0;
m_pDepthTexture->realWidth = m_pDepthTexture->width;
m_pDepthTexture->realHeight = m_pDepthTexture->height;
m_pDepthTexture->textureBytes = m_pDepthTexture->realWidth * m_pDepthTexture->realHeight * 4 * 4; // Width*Height*RGBA*sizeof(GL_RGBA32F)
textureCache().addFrameBufferTextureSize(m_pDepthTexture->textureBytes);
m_pDepthImageTexture = textureCache().addFrameBufferTexture();
glBindTexture( GL_TEXTURE_2D, m_pDepthTexture->glName );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_pDepthTexture->realWidth, m_pDepthTexture->realHeight, 0, GL_RGBA, GL_FLOAT, NULL);
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);
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);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pDepthTexture->glName, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pDepthImageTexture->glName, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
_pBuffer->m_pDepthBuffer = this;
depthBufferList().clearBuffer();
#endif // GL_IMAGE_TEXTURES_SUPPORT
}
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
}
void DepthBufferList::init()
{
m_pCurrent = NULL;
@ -133,17 +199,8 @@ void DepthBufferList::saveBuffer(u32 _address)
buffer.m_address = _address;
buffer.m_width = pFrameBuffer != NULL ? pFrameBuffer->m_width : VI.width;
buffer.m_pDepthTexture = NULL;
glBindRenderbuffer(GL_RENDERBUFFER, buffer.m_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, video().getWidth(), video().getHeight());
buffer.initDepthBufferTexture(pFrameBuffer);
m_pCurrent = &buffer;
}
@ -172,7 +229,7 @@ void DepthBufferList::clearBuffer()
gDP.otherMode.cycleType = G_CYC_FILL;
video().getRender().drawRect(0,0,VI.width, VI.height, color);
gDP.otherMode.cycleType = cycleType;
glBindImageTexture(depthImageUnit, m_pCurrent->m_pDepthTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
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
}

View File

@ -9,12 +9,18 @@ struct DepthBuffer
DepthBuffer();
DepthBuffer(DepthBuffer && _other);
~DepthBuffer();
void initDepthTexture(FrameBuffer * _pBuffer);
void initDepthImageTexture(FrameBuffer * _pBuffer);
void initDepthBufferTexture(FrameBuffer * _pBuffer);
void setDepthAttachment();
void activateDepthBufferTexture();
void bindDepthImageTexture();
u32 m_address, m_width;
GLuint m_renderbuf;
GLuint m_FBO;
CachedTexture *m_pDepthTexture;
CachedTexture *m_pDepthImageTexture;
CachedTexture *m_pDepthBufferTexture;
};
class DepthBufferList

View File

@ -302,27 +302,25 @@ void FrameBufferList::removeBuffer(u32 _address )
void FrameBufferList::attachDepthBuffer()
{
if (m_pCurrent == NULL)
return;
DepthBuffer * pDepthBuffer = depthBufferList().getCurrent();
if (m_pCurrent != NULL && m_pCurrent->m_FBO > 0 && pDepthBuffer != NULL && pDepthBuffer->m_renderbuf > 0) {
if (pDepthBuffer->m_pDepthTexture == NULL || pDepthBuffer->m_pDepthTexture->width != m_pCurrent->m_pTexture->width)
pDepthBuffer->initDepthTexture(m_pCurrent);
if (m_pCurrent->m_FBO > 0 && pDepthBuffer != NULL) {
pDepthBuffer->initDepthImageTexture(m_pCurrent);
pDepthBuffer->initDepthBufferTexture(m_pCurrent);
m_pCurrent->m_pDepthBuffer = pDepthBuffer;
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pDepthBuffer->m_renderbuf);
#ifdef GL_IMAGE_TEXTURES_SUPPORT
GLuint attachments[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, attachments);
pDepthBuffer->setDepthAttachment();
if (video().getRender().isImageTexturesSupported())
glBindImageTexture(depthImageUnit, pDepthBuffer->m_pDepthTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
#endif
assert(checkFBO());
} else if (m_pCurrent != NULL) {
pDepthBuffer->bindDepthImageTexture();
} else
m_pCurrent->m_pDepthBuffer = NULL;
#ifndef GLES2
GLuint attachments[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, attachments);
GLuint attachments[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, attachments);
#endif
assert(checkFBO());
}
assert(checkFBO());
}
void FrameBuffer_Init()

View File

@ -21,9 +21,9 @@ static GLuint g_calc_noise_shader_object;
static GLuint g_calc_depth_shader_object;
static GLuint g_test_alpha_shader_object;
GLuint g_monochrome_image_program = 0;
#ifdef GL_IMAGE_TEXTURES_SUPPORT
GLuint g_draw_shadow_map_program = 0;
GLuint g_monochrome_image_program = 0;
static GLuint g_zlut_tex = 0;
GLuint g_tlut_tex = 0;
static u32 g_paletteCRC256 = 0;
@ -876,9 +876,8 @@ void ShaderCombiner::updateAlphaTestInfo(bool _bForce) {
}
#ifdef GL_IMAGE_TEXTURES_SUPPORT
void SetMonochromeCombiner(GLuint _program)
void SetDepthFogCombiner()
{
if (!video().getRender().isImageTexturesSupported())
return;
@ -895,11 +894,19 @@ void SetMonochromeCombiner(GLuint _program)
glBindImageTexture(TlutImageUnit, g_tlut_tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R16UI);
}
glUseProgram(_program);
int loc = glGetUniformLocation(_program, "uFogColor");
if (loc >=0)
glUseProgram(g_draw_shadow_map_program);
int loc = glGetUniformLocation(g_draw_shadow_map_program, "uFogColor");
if (loc >= 0)
glUniform4fv(loc, 1, &gDP.fogColor.r);
loc = glGetUniformLocation(g_draw_shadow_map_program, "uDepthScale");
if (loc >= 0)
glUniform2f(loc, gSP.viewport.vscale[2] * 32768.0f, gSP.viewport.vtrans[2] * 32768.0f);
gDP.changed |= CHANGED_COMBINE;
}
#endif // GL_IMAGE_TEXTURES_SUPPORT
void SetMonochromeCombiner() {
glUseProgram(g_monochrome_image_program);
gDP.changed |= CHANGED_COMBINE;
}

View File

@ -117,9 +117,8 @@ void InitShaderCombiner();
void DestroyShaderCombiner();
#ifdef GL_IMAGE_TEXTURES_SUPPORT
extern GLuint g_draw_shadow_map_program;
extern GLuint g_monochrome_image_program;
void SetMonochromeCombiner(GLuint _program);
void SetDepthFogCombiner();
void SetMonochromeCombiner();
#endif // GL_IMAGE_TEXTURES_SUPPORT
GLuint createShaderProgram(const char * _strVertex, const char * _strFragment);

View File

@ -909,11 +909,13 @@ void OGLRender::drawRect(int _ulx, int _uly, int _lrx, int _lry, float *_pColor)
static
bool texturedRectShadowMap(const OGLRender::TexturedRectParams &)
{
#ifdef GL_IMAGE_TEXTURES_SUPPORT
// if ((gDP.otherMode.l >> 16) == 0x3c18 && gDP.combine.muxs0 == 0x00ffffff && gDP.combine.muxs1 == 0xfffff238) //depth image based fog
if (gDP.textureImage.size == 2 && gDP.textureImage.address >= gDP.depthImageAddress && gDP.textureImage.address < (gDP.depthImageAddress + gDP.colorImage.width*gDP.colorImage.width*6/4))
SetMonochromeCombiner(g_draw_shadow_map_program);
#endif // GL_IMAGE_TEXTURES_SUPPORT
FrameBufferList & fb = frameBufferList();
if (fb.isFboMode()) {
if (gDP.textureImage.size == 2 && gDP.textureImage.address >= gDP.depthImageAddress && gDP.textureImage.address < (gDP.depthImageAddress + gDP.colorImage.width*gDP.colorImage.width * 6 / 4)) {
fb.getCurrent()->m_pDepthBuffer->activateDepthBufferTexture();
SetDepthFogCombiner();
}
}
return false;
}
@ -1001,7 +1003,7 @@ bool texturedRectMonochromeBackground(const OGLRender::TexturedRectParams & _par
FrameBufferList & fb = frameBufferList();
if (fb.isFboMode()) {
FrameBuffer_ActivateBufferTexture(0, fb.getCurrent());
SetMonochromeCombiner(g_monochrome_image_program);
SetMonochromeCombiner();
return false;
} else
#endif

View File

@ -621,17 +621,25 @@ static const char* default_vertex_shader =
static const char* shadow_map_fragment_shader_float =
"#version 420 core \n"
"layout(binding = 0) uniform sampler2D uDepthImage; \n"
"layout(binding = 0, r16ui) uniform readonly uimage2D uZlutImage;\n"
"layout(binding = 1, r16ui) uniform readonly uimage1D uTlutImage;\n"
"layout(binding = 2, rgba32f) uniform readonly image2D uDepthImage;\n"
"uniform lowp vec4 uFogColor; \n"
"uniform mediump vec2 uDepthScale; \n"
"out lowp vec4 fragColor; \n"
"lowp float get_alpha() \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" mediump float bufZ = imageLoad(uDepthImage,coord).r; \n"
" int index = min(255, int(bufZ*255.0)); \n"
" highp float bufZ = texelFetch(uDepthImage,coord, 0).r; \n"
" highp float fZ = 2.0*bufZ - 1.0; \n"
" fZ = (uDepthScale.x*fZ + uDepthScale.y)*8.0; \n"
" const highp int iZ = int(floor(fZ + 0.5)); \n"
" int y0 = clamp(iZ/512, 0, 511); \n"
" int x0 = iZ - 512*y0; \n"
" unsigned int iN64z = imageLoad(uZlutImage,ivec2(x0,y0)).r;\n"
" highp float n64z = clamp(float(iN64z)/65532.0, 0.0, 1.0);\n"
" int index = min(255, int(n64z*255.0)); \n"
" unsigned int iAlpha = imageLoad(uTlutImage,index).r; \n"
" memoryBarrier(); \n"
" return float(iAlpha/256)/255.0; \n"
"} \n"
"void main() \n"
@ -639,8 +647,10 @@ static const char* shadow_map_fragment_shader_float =
" fragColor = vec4(uFogColor.rgb, get_alpha()); \n"
"} \n"
;
#endif // GL_IMAGE_TEXTURES_SUPPORT
#if 0 // Do palette based monochrome image. Exactly as N64 does
#ifdef GL_IMAGE_TEXTURES_SUPPORT
static const char* zelda_monochrome_fragment_shader =
"#version 420 core \n"
"layout(binding = 0) uniform sampler2D uColorImage; \n"
@ -664,6 +674,7 @@ static const char* zelda_monochrome_fragment_shader =
" fragColor = vec4(vec3(get_color()), 1.0); \n"
"} \n"
;
#endif // GL_IMAGE_TEXTURES_SUPPORT
#else // Cheat it
static const char* zelda_monochrome_fragment_shader =
"#version 420 core \n"
@ -679,4 +690,3 @@ static const char* zelda_monochrome_fragment_shader =
"} \n"
;
#endif
#endif // GL_IMAGE_TEXTURES_SUPPORT

View File

@ -2143,7 +2143,7 @@ void _copyDepthBuffer()
DepthBuffer * pTmpBufferDepth = pTmpBuffer->m_pDepthBuffer;
pTmpBuffer->m_pDepthBuffer = depthBufferList().findBuffer(gSP.bgImage.address);
glBindFramebuffer(GL_READ_FRAMEBUFFER, pTmpBuffer->m_FBO);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pTmpBuffer->m_pDepthBuffer->m_renderbuf);
pTmpBuffer->m_pDepthBuffer->setDepthAttachment();
GLuint attachment = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, &attachment);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO);
@ -2154,7 +2154,7 @@ void _copyDepthBuffer()
GL_DEPTH_BUFFER_BIT, GL_NEAREST
);
// Restore objects
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pTmpBufferDepth->m_renderbuf);
pTmpBufferDepth->setDepthAttachment();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// Set back current depth buffer
depthBufferList().saveBuffer(gDP.depthImageAddress);