mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-02 09:03:37 +00:00
Implement render to depth buffer.
Fixed shadows in Pilot Wings. Removed special texrect for NFL Quaterback 98 monitor: it is now supported by general code
This commit is contained in:
parent
8ab1ca7468
commit
ccff245f85
|
@ -17,34 +17,44 @@ const GLuint TlutImageUnit = 1;
|
|||
const GLuint depthImageUnit = 2;
|
||||
|
||||
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_uly(0), m_lry(0),
|
||||
m_FBO(0), m_pDepthImageTexture(NULL), m_pDepthBufferTexture(NULL),
|
||||
m_cleared(false), m_pResolveDepthBufferTexture(NULL), m_resolved(false)
|
||||
m_depthImageFBO(0), m_pDepthImageTexture(NULL), m_pDepthBufferTexture(NULL),
|
||||
m_cleared(false), m_pResolveDepthBufferTexture(NULL), m_resolved(false),
|
||||
m_pDepthBufferCopyTexture(NULL), m_copied(false)
|
||||
{
|
||||
glGenFramebuffers(1, &m_FBO);
|
||||
glGenFramebuffers(1, &m_copyFBO);
|
||||
if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0)
|
||||
glGenFramebuffers(1, &m_depthImageFBO);
|
||||
}
|
||||
|
||||
DepthBuffer::DepthBuffer(DepthBuffer && _other) :
|
||||
m_address(_other.m_address), m_width(_other.m_width), m_uly(_other.m_uly), m_lry(_other.m_lry),
|
||||
m_FBO(_other.m_FBO), m_pDepthImageTexture(_other.m_pDepthImageTexture), m_pDepthBufferTexture(_other.m_pDepthBufferTexture),
|
||||
m_cleared(_other.m_cleared), m_pResolveDepthBufferTexture(_other.m_pResolveDepthBufferTexture), m_resolved(_other.m_resolved)
|
||||
m_depthImageFBO(_other.m_depthImageFBO), m_pDepthImageTexture(_other.m_pDepthImageTexture), m_pDepthBufferTexture(_other.m_pDepthBufferTexture),
|
||||
m_cleared(_other.m_cleared), m_pResolveDepthBufferTexture(_other.m_pResolveDepthBufferTexture), m_resolved(_other.m_resolved),
|
||||
m_pDepthBufferCopyTexture(_other.m_pDepthBufferCopyTexture), m_copied(m_copied)
|
||||
{
|
||||
_other.m_FBO = 0;
|
||||
_other.m_depthImageFBO = 0;
|
||||
_other.m_pDepthImageTexture = NULL;
|
||||
_other.m_pDepthBufferTexture = NULL;
|
||||
_other.m_pResolveDepthBufferTexture = NULL;
|
||||
_other.m_resolved = false;
|
||||
_other.m_pDepthBufferCopyTexture = NULL;
|
||||
_other.m_copied = false;
|
||||
}
|
||||
|
||||
DepthBuffer::~DepthBuffer()
|
||||
{
|
||||
if (m_FBO != 0)
|
||||
glDeleteFramebuffers(1, &m_FBO);
|
||||
if (m_depthImageFBO != 0)
|
||||
glDeleteFramebuffers(1, &m_depthImageFBO);
|
||||
if (m_pDepthImageTexture != NULL)
|
||||
textureCache().removeFrameBufferTexture(m_pDepthImageTexture);
|
||||
if (m_pDepthBufferTexture != NULL)
|
||||
textureCache().removeFrameBufferTexture(m_pDepthBufferTexture);
|
||||
if (m_pResolveDepthBufferTexture != NULL)
|
||||
textureCache().removeFrameBufferTexture(m_pResolveDepthBufferTexture);
|
||||
if (m_copyFBO != 0)
|
||||
glDeleteFramebuffers(1, &m_copyFBO);
|
||||
if (m_pDepthBufferCopyTexture != NULL)
|
||||
textureCache().removeFrameBufferTexture(m_pDepthBufferCopyTexture);
|
||||
}
|
||||
|
||||
void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
|
||||
|
@ -81,7 +91,7 @@ void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
|
|||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_depthImageFBO);
|
||||
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);
|
||||
|
@ -163,6 +173,7 @@ void DepthBuffer::setDepthAttachment(GLenum _target)
|
|||
else
|
||||
#endif
|
||||
glFramebufferTexture2D(_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_pDepthBufferTexture->glName, 0);
|
||||
m_copied = false;
|
||||
m_resolved = false;
|
||||
}
|
||||
|
||||
|
@ -212,6 +223,47 @@ CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef GLES2
|
||||
CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
|
||||
{
|
||||
if (m_copied)
|
||||
return m_pDepthBufferCopyTexture;
|
||||
|
||||
if (m_pDepthBufferCopyTexture == NULL) {
|
||||
m_pDepthBufferCopyTexture = textureCache().addFrameBufferTexture();
|
||||
_initDepthBufferTexture(_pBuffer, m_pDepthBufferCopyTexture, false);
|
||||
}
|
||||
|
||||
glScissor(0, 0, m_pDepthBufferTexture->realWidth, m_pDepthBufferTexture->realHeight);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, _pBuffer->m_FBO);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
assert(checkFBO());
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_copyFBO);
|
||||
#ifdef GL_MULTISAMPLING_SUPPORT
|
||||
GLenum textarget = config.video.multisampling != 0 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
||||
#else
|
||||
GLenum textarget = GL_TEXTURE_2D;
|
||||
#endif
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
textarget,
|
||||
_pBuffer->m_pTexture->glName,
|
||||
0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_pDepthBufferCopyTexture->glName, 0);
|
||||
assert(checkFBO());
|
||||
glBlitFramebuffer(
|
||||
0, 0, m_pDepthBufferTexture->realWidth, m_pDepthBufferTexture->realHeight,
|
||||
0, 0, m_pDepthBufferTexture->realWidth, m_pDepthBufferTexture->realHeight,
|
||||
GL_DEPTH_BUFFER_BIT, GL_NEAREST
|
||||
);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
|
||||
m_copied = true;
|
||||
gDP.changed |= CHANGED_SCISSOR;
|
||||
return m_pDepthBufferCopyTexture;
|
||||
}
|
||||
#endif
|
||||
|
||||
void DepthBuffer::activateDepthBufferTexture(FrameBuffer * _pBuffer)
|
||||
{
|
||||
textureCache().activateTexture(0, resolveDepthBufferTexture(_pBuffer));
|
||||
|
@ -335,11 +387,11 @@ void DepthBufferList::clearBuffer(u32 _uly, u32 _lry)
|
|||
m_pCurrent->m_uly = _uly;
|
||||
m_pCurrent->m_lry = _lry;
|
||||
#ifdef GL_IMAGE_TEXTURES_SUPPORT
|
||||
if (m_pCurrent->m_FBO == 0 || !video().getRender().isImageTexturesSupported() || config.frameBufferEmulation.N64DepthCompare == 0)
|
||||
if (m_pCurrent->m_depthImageFBO == 0 || !video().getRender().isImageTexturesSupported() || config.frameBufferEmulation.N64DepthCompare == 0)
|
||||
return;
|
||||
float color[4] = {1.0f, 1.0f, 0.0f, 1.0f};
|
||||
glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_depthImageFBO);
|
||||
const u32 cycleType = gDP.otherMode.cycleType;
|
||||
gDP.otherMode.cycleType = G_CYC_FILL;
|
||||
video().getRender().drawRect(0,0,VI.width, VI.height, color);
|
||||
|
|
|
@ -13,6 +13,7 @@ struct DepthBuffer
|
|||
void initDepthImageTexture(FrameBuffer * _pBuffer);
|
||||
void initDepthBufferTexture(FrameBuffer * _pBuffer);
|
||||
CachedTexture * resolveDepthBufferTexture(FrameBuffer * _pBuffer);
|
||||
CachedTexture * copyDepthBufferTexture(FrameBuffer * _pBuffer);
|
||||
|
||||
void setDepthAttachment(GLenum _target);
|
||||
void activateDepthBufferTexture(FrameBuffer * _pBuffer);
|
||||
|
@ -21,16 +22,21 @@ struct DepthBuffer
|
|||
|
||||
u32 m_address, m_width;
|
||||
u32 m_uly, m_lry; // Top and bottom bounds of fillrect command.
|
||||
GLuint m_FBO;
|
||||
GLuint m_depthImageFBO;
|
||||
CachedTexture *m_pDepthImageTexture;
|
||||
CachedTexture *m_pDepthBufferTexture;
|
||||
bool m_cleared;
|
||||
// multisampling
|
||||
CachedTexture *m_pResolveDepthBufferTexture;
|
||||
bool m_resolved;
|
||||
// render to depth buffer
|
||||
GLuint m_copyFBO;
|
||||
CachedTexture *m_pDepthBufferCopyTexture;
|
||||
bool m_copied;
|
||||
|
||||
private:
|
||||
void _initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture *_pTexture, bool _multisample);
|
||||
void _DepthBufferTexture(FrameBuffer * _pBuffer);
|
||||
};
|
||||
|
||||
class DepthBufferList
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
void updateAlphaTestInfo(bool _bForce = false);
|
||||
void updateTextureInfo(bool _bForce = false);
|
||||
void updateRenderState(bool _bForce = false);
|
||||
void updateRenderTarget(bool _bForce = false);
|
||||
void updateScreenCoordsScale(bool _bForce = false);
|
||||
void updateBlendMode(bool _bForce = false);
|
||||
void disableBlending();
|
||||
|
@ -110,13 +111,14 @@ private:
|
|||
|
||||
struct UniformLocation
|
||||
{
|
||||
iUniform uTex0, uTex1, uMSTex0, uMSTex1, uTexNoise, uTlutImage, uZlutImage, uDepthImage,
|
||||
iUniform uTex0, uTex1, uMSTex0, uMSTex1, uDepthTex,
|
||||
uTexNoise, uTlutImage, uZlutImage, uDepthImage,
|
||||
uFogUsage, uEnableLod, uEnableAlphaTest,
|
||||
uEnableDepth, uEnableDepthCompare, uEnableDepthUpdate,
|
||||
uDepthMode, uDepthSource, uRenderState,
|
||||
uMaxTile, uTextureDetail, uTexturePersp, uTextureFilterMode, uMSAASamples,
|
||||
uAlphaCompareMode, uAlphaDitherMode, uColorDitherMode,
|
||||
uCvgXAlpha, uAlphaCvgSel,
|
||||
uCvgXAlpha, uAlphaCvgSel, uRenderTarget,
|
||||
uForceBlendCycle1, uForceBlendCycle2;
|
||||
|
||||
fUniform uMinLod, uDeltaZ, uAlphaTestValue, uMSAAScale;
|
||||
|
|
|
@ -398,6 +398,22 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
|
|||
if (video().getRender().isImageTexturesSupported() && config.frameBufferEmulation.N64DepthCompare != 0)
|
||||
strFragmentShader.append(" if (!depth_compare()) discard; \n");
|
||||
|
||||
strFragmentShader.append(
|
||||
#ifdef GLESX
|
||||
"#ifdef GL_NV_fragdepth \n"
|
||||
#endif
|
||||
" if (uRenderTarget != 0) { \n"
|
||||
" if (uRenderTarget > 1) { \n"
|
||||
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
|
||||
" if (gl_FragDepth >= texelFetch(uDepthTex, coord, 0).r) discard; \n"
|
||||
" } \n"
|
||||
" gl_FragDepth = fragColor.r; \n"
|
||||
" } \n"
|
||||
#ifdef GLESX
|
||||
"#endif \n"
|
||||
#endif
|
||||
);
|
||||
|
||||
strFragmentShader.append(fragment_shader_end);
|
||||
|
||||
if (config.generalEmulation.enableNoise == 0)
|
||||
|
@ -480,6 +496,7 @@ ShaderCombiner::~ShaderCombiner() {
|
|||
void ShaderCombiner::_locateUniforms() {
|
||||
LocateUniform(uTex0);
|
||||
LocateUniform(uTex1);
|
||||
LocateUniform(uDepthTex);
|
||||
LocateUniform(uTexNoise);
|
||||
LocateUniform(uTlutImage);
|
||||
LocateUniform(uZlutImage);
|
||||
|
@ -490,6 +507,7 @@ void ShaderCombiner::_locateUniforms() {
|
|||
LocateUniform(uColorDitherMode);
|
||||
LocateUniform(uCvgXAlpha);
|
||||
LocateUniform(uAlphaCvgSel);
|
||||
LocateUniform(uRenderTarget);
|
||||
LocateUniform(uEnableLod);
|
||||
LocateUniform(uEnableAlphaTest);
|
||||
LocateUniform(uEnableDepth);
|
||||
|
@ -545,6 +563,7 @@ void ShaderCombiner::update(bool _bForce) {
|
|||
|
||||
if (_bForce) {
|
||||
m_uniforms.uTexNoise.set(g_noiseTexIndex, true);
|
||||
m_uniforms.uDepthTex.set(g_depthTexIndex, true);
|
||||
if (usesTexture()) {
|
||||
m_uniforms.uTex0.set(0, true);
|
||||
m_uniforms.uTex1.set(1, true);
|
||||
|
@ -568,6 +587,7 @@ void ShaderCombiner::update(bool _bForce) {
|
|||
updateTextureInfo(_bForce);
|
||||
updateAlphaTestInfo(_bForce);
|
||||
updateDepthInfo(_bForce);
|
||||
updateRenderTarget(_bForce);
|
||||
updateScreenCoordsScale(_bForce);
|
||||
}
|
||||
|
||||
|
@ -576,6 +596,20 @@ void ShaderCombiner::updateRenderState(bool _bForce)
|
|||
m_uniforms.uRenderState.set(video().getRender().getRenderState(), _bForce);
|
||||
}
|
||||
|
||||
void ShaderCombiner::updateRenderTarget(bool _bForce)
|
||||
{
|
||||
int renderTarget = 0;
|
||||
if (gDP.colorImage.address == gDP.depthImageAddress &&
|
||||
gDP.otherMode.cycleType != G_CYC_FILL &&
|
||||
(config.generalEmulation.hacks & hack_ZeldaMM) == 0
|
||||
) {
|
||||
FrameBuffer * pCurBuf = frameBufferList().getCurrent();
|
||||
if (pCurBuf != nullptr && pCurBuf->m_pDepthBuffer != nullptr)
|
||||
renderTarget = gDP.otherMode.depthCompare + 1;
|
||||
}
|
||||
m_uniforms.uRenderTarget.set(renderTarget, _bForce);
|
||||
}
|
||||
|
||||
void ShaderCombiner::updateScreenCoordsScale(bool _bForce)
|
||||
{
|
||||
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
|
||||
|
|
|
@ -142,6 +142,7 @@ static const char* fragment_shader_header_common_variables =
|
|||
MAIN_SHADER_VERSION
|
||||
"uniform sampler2D uTex0; \n"
|
||||
"uniform sampler2D uTex1; \n"
|
||||
"uniform sampler2D uDepthTex; \n"
|
||||
"layout (std140) uniform ColorsBlock {\n"
|
||||
" lowp vec4 uFogColor; \n"
|
||||
" lowp vec4 uCenterColor; \n"
|
||||
|
@ -164,6 +165,7 @@ MAIN_SHADER_VERSION
|
|||
"uniform lowp int uEnableAlphaTest; \n"
|
||||
"uniform lowp int uCvgXAlpha; \n"
|
||||
"uniform lowp int uAlphaCvgSel; \n"
|
||||
"uniform lowp int uRenderTarget; \n"
|
||||
"uniform lowp float uAlphaTestValue;\n"
|
||||
"uniform mediump vec2 uDepthScale; \n"
|
||||
"uniform lowp ivec4 uBlendMux1; \n"
|
||||
|
@ -189,6 +191,7 @@ static const char* fragment_shader_header_common_variables_ms_tex1 =
|
|||
|
||||
static const char* fragment_shader_header_common_variables_notex =
|
||||
MAIN_SHADER_VERSION
|
||||
"uniform sampler2D uDepthTex; \n"
|
||||
"layout (std140) uniform ColorsBlock {\n"
|
||||
" lowp vec4 uFogColor; \n"
|
||||
" lowp vec4 uCenterColor; \n"
|
||||
|
@ -209,6 +212,7 @@ MAIN_SHADER_VERSION
|
|||
"uniform lowp int uEnableAlphaTest; \n"
|
||||
"uniform lowp int uCvgXAlpha; \n"
|
||||
"uniform lowp int uAlphaCvgSel; \n"
|
||||
"uniform lowp int uRenderTarget; \n"
|
||||
"uniform lowp float uAlphaTestValue;\n"
|
||||
"uniform mediump vec2 uDepthScale; \n"
|
||||
"uniform lowp ivec4 uBlendMux1; \n"
|
||||
|
|
|
@ -685,6 +685,31 @@ void OGLRender::_updateStates(RENDER_STATE _renderState) const
|
|||
}
|
||||
|
||||
cmbInfo.updateParameters(_renderState);
|
||||
|
||||
#ifndef GLES2
|
||||
if (gDP.colorImage.address == gDP.depthImageAddress &&
|
||||
gDP.otherMode.cycleType != G_CYC_FILL &&
|
||||
(config.generalEmulation.hacks & hack_ZeldaMM) == 0
|
||||
) {
|
||||
FrameBuffer * pCurBuf = frameBufferList().getCurrent();
|
||||
if (pCurBuf != nullptr && pCurBuf->m_pDepthBuffer != nullptr) {
|
||||
if (gDP.otherMode.depthCompare != 0) {
|
||||
CachedTexture * pDepthTexture = pCurBuf->m_pDepthBuffer->copyDepthBufferTexture(pCurBuf);
|
||||
if (pDepthTexture == nullptr)
|
||||
return;
|
||||
glActiveTexture(GL_TEXTURE0 + g_depthTexIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, pDepthTexture->glName);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glDepthMask(TRUE);
|
||||
gDP.changed |= CHANGED_RENDERMODE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OGLRender::_setColorArray() const
|
||||
|
@ -818,6 +843,7 @@ void OGLRender::drawTriangles()
|
|||
|
||||
_prepareDrawTriangle(false);
|
||||
glDrawElements(GL_TRIANGLES, triangles.num, GL_UNSIGNED_BYTE, triangles.elements);
|
||||
// glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
|
||||
triangles.num = 0;
|
||||
}
|
||||
|
||||
|
@ -978,18 +1004,6 @@ bool texturedRectDepthBufferCopy(const OGLRender::TexturedRectParams & _params)
|
|||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
bool texturedRectDepthBufferRender(const OGLRender::TexturedRectParams & _params)
|
||||
{
|
||||
if (gDP.colorImage.address == gDP.depthImageAddress) {
|
||||
FrameBuffer * pCurBuf = frameBufferList().getCurrent();
|
||||
if (pCurBuf == nullptr || pCurBuf->m_pDepthBuffer == nullptr)
|
||||
return true;
|
||||
return !SetDepthTextureCombiner();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
bool texturedRectCopyToItself(const OGLRender::TexturedRectParams & _params)
|
||||
{
|
||||
|
@ -1537,8 +1551,6 @@ void OGLRender::_setSpecialTexrect() const
|
|||
texturedRectSpecial = texturedRectPaletteMod;
|
||||
else if (strstr(name, (const char *)"ZELDA"))
|
||||
texturedRectSpecial = texturedRectMonochromeBackground;
|
||||
else if (strstr(name, (const char *)"quarterback_club_98"))
|
||||
texturedRectSpecial = texturedRectDepthBufferRender;
|
||||
else
|
||||
texturedRectSpecial = NULL;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
using namespace std;
|
||||
|
||||
const GLuint g_noiseTexIndex = 2;
|
||||
const GLuint g_MSTex0Index = g_noiseTexIndex + 1;
|
||||
const GLuint g_depthTexIndex = g_noiseTexIndex + 1;
|
||||
const GLuint g_MSTex0Index = g_depthTexIndex + 1;
|
||||
|
||||
inline u32 GetNone( u64 *src, u16 x, u16 i, u8 palette )
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "convert.h"
|
||||
|
||||
extern const GLuint g_noiseTexIndex;
|
||||
extern const GLuint g_depthTexIndex;
|
||||
extern const GLuint g_MSTex0Index;
|
||||
|
||||
typedef u32 (*GetTexelFunc)( u64 *src, u16 x, u16 i, u8 palette );
|
||||
|
|
Loading…
Reference in New Issue
Block a user