1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

Implement N64 depth compare.

Removed integer-based variant of depth texture.
This commit is contained in:
Sergey Lipskiy 2013-12-15 22:32:17 +07:00
parent bf99ef2079
commit 314b9098f4
5 changed files with 70 additions and 118 deletions

View File

@ -15,10 +15,7 @@
bool g_bCopyToRDRAM = false;
bool g_bCopyFromRDRAM = false;
bool g_bCopyDepthToRDRAM = false;
bool g_bUseFloatDepthTexture = true;
bool g_bIgnoreCFB = true;
static const GLint depthTextureInternalFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16;
static const GLenum depthTextureType = g_bUseFloatDepthTexture ? GL_FLOAT : GL_UNSIGNED_INT;
FrameBufferList frameBuffer;
@ -367,7 +364,7 @@ void _initDepthTexture()
cache.cachedBytes += depthBuffer.top->depth_texture->textureBytes;
glBindTexture( GL_TEXTURE_2D, depthBuffer.top->depth_texture->glName );
glTexImage2D(GL_TEXTURE_2D, 0, depthTextureInternalFormat, depthBuffer.top->depth_texture->realWidth, depthBuffer.top->depth_texture->realHeight, 0, GL_RED, depthTextureType, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, depthBuffer.top->depth_texture->realWidth, depthBuffer.top->depth_texture->realHeight, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glBindTexture( GL_TEXTURE_2D, 0);

View File

@ -32,7 +32,6 @@ extern FrameBufferList frameBuffer;
extern bool g_bCopyToRDRAM;
extern bool g_bCopyDepthToRDRAM;
extern bool g_bCopyFromRDRAM;
extern bool g_bUseFloatDepthTexture;
extern bool g_bIgnoreCFB;
void FrameBuffer_Init();

View File

@ -134,10 +134,7 @@ void InitShadowMapShader()
assert(check_shader_compile_status(g_shadow_map_vertex_shader_object));
g_shadow_map_fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
if (g_bUseFloatDepthTexture)
glShaderSource(g_shadow_map_fragment_shader_object, 1, &shadow_map_fragment_shader_float, NULL);
else
glShaderSource(g_shadow_map_fragment_shader_object, 1, &shadow_map_fragment_shader_int, NULL);
glShaderSource(g_shadow_map_fragment_shader_object, 1, &shadow_map_fragment_shader_float, NULL);
glCompileShader(g_shadow_map_fragment_shader_object);
assert(check_shader_compile_status(g_shadow_map_fragment_shader_object));
@ -197,10 +194,7 @@ void InitGLSLCombiner()
if (OGL.bImageTexture) {
g_calc_depth_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
if (g_bUseFloatDepthTexture)
glShaderSource(g_calc_depth_shader_object, 1, &depth_compare_shader_float, NULL);
else
glShaderSource(g_calc_depth_shader_object, 1, &depth_compare_shader_int, NULL);
glShaderSource(g_calc_depth_shader_object, 1, &depth_compare_shader_float, NULL);
glCompileShader(g_calc_depth_shader_object);
assert(check_shader_compile_status(g_calc_depth_shader_object));
}
@ -412,8 +406,8 @@ GLSLCombiner::GLSLCombiner(Combiner *_color, Combiner *_alpha) {
strcat(fragment_shader, " if (!alpha_test(gl_FragColor.a)) discard; \n");
if (OGL.bImageTexture)
strcat(fragment_shader, " bool bDC = depth_compare(); \n");
// strcat(fragment_shader, " if (!depth_compare()) discard; \n");
// strcat(fragment_shader, " bool bDC = depth_compare(); \n");
strcat(fragment_shader, " if (!depth_compare()) discard; \n");
#ifdef USE_TOONIFY
strcat(fragment_shader, " toonify(intensity); \n");
@ -572,8 +566,7 @@ static
void _unbindImageTextures() {
glBindImageTexture(TlutImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI);
glBindImageTexture(ZlutImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI);
const GLenum depthTexFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16UI;
glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, depthTexFormat);
glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
}
void GLSLCombiner::UpdateDepthInfo() {
@ -591,18 +584,12 @@ void GLSLCombiner::UpdateDepthInfo() {
if (nDepthEnabled == 0)
return;
const int depth_mode_location = glGetUniformLocation(m_program, "depthMode");
glUniform1i(depth_mode_location, gDP.otherMode.depthMode);
const int depth_compare_location = glGetUniformLocation(m_program, "depthCompareEnabled");
glUniform1i(depth_compare_location, gDP.otherMode.depthCompare);
const int depth_update_location = glGetUniformLocation(m_program, "depthUpdateEnabled");
glUniform1i(depth_update_location, gDP.otherMode.depthUpdate);
const int depth_polygon_offset = glGetUniformLocation(m_program, "depthPolygonOffset");
if (g_bUseFloatDepthTexture) {
float fPlygonOffset = gDP.otherMode.depthMode == ZMODE_DEC ? 0.005f : 0.0f;
glUniform1f(depth_polygon_offset, fPlygonOffset);
} else {
int iPlygonOffset = gDP.otherMode.depthMode == ZMODE_DEC ? 5 : 0;
glUniform1i(depth_polygon_offset, iPlygonOffset);
}
const int depth_scale_location = glGetUniformLocation(m_program, "depthScale");
glUniform1f(depth_scale_location, gSP.viewport.vscale[2]*32768);
const int depth_trans_location = glGetUniformLocation(m_program, "depthTrans");
@ -610,8 +597,7 @@ void GLSLCombiner::UpdateDepthInfo() {
GLuint texture = frameBuffer.top->pDepthBuffer->depth_texture->glName;
glBindImageTexture(ZlutImageUnit, g_zlut_tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R16UI);
GLenum depthTexFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16UI;
glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_WRITE, depthTexFormat);
glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
}
void GLSL_ClearDepthBuffer() {
@ -621,29 +607,25 @@ void GLSL_ClearDepthBuffer() {
if (frameBuffer.top == NULL || frameBuffer.top->pDepthBuffer == NULL)
return;
_unbindImageTextures();
CachedTexture * pDepthTexture = frameBuffer.top->pDepthBuffer->depth_texture;
const u32 numTexels = pDepthTexture->width*pDepthTexture->height;
const u32 numTexels = pDepthTexture->width*pDepthTexture->height*4;
GLenum type = GL_UNSIGNED_SHORT;
int dataSize = g_bUseFloatDepthTexture ? sizeof(float) : sizeof(unsigned short);
char * pData = (char*)malloc(numTexels * dataSize);;
if (g_bUseFloatDepthTexture) {
type = GL_FLOAT;
f32 * pDepth = (f32*)pData;
for (int i = 0; i < numTexels; i++)
pDepth[i] = 1.0f;
} else {
u16 * pDepth = (u16*)pData;
for (int i = 0; i < numTexels; i++)
pDepth[i] = 0xfffc;
char * pData = (char*)malloc(numTexels * sizeof(float));
f32 * pDepth = (f32*)pData;
for (int i = 0; i < numTexels; i+=4) {
pDepth[i] = 1.0f;
pDepth[i+1] = 1.0f;
pDepth[i+2] = 0.0f;
pDepth[i+3] = 0.0f;
}
glBindTexture(GL_TEXTURE_2D, pDepthTexture->glName);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
pDepthTexture->width, pDepthTexture->height,
GL_RED, type, pData);
GL_RGBA, GL_FLOAT, pData
);
free(pData);
gSP.changed |= CHANGED_TEXTURE;
@ -683,6 +665,8 @@ void GLSL_RenderDepth() {
#else
if (frameBuffer.top == NULL || frameBuffer.top->pDepthBuffer == NULL)
return;
_unbindImageTextures();
return;
glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT );
glActiveTexture( GL_TEXTURE0 );
@ -764,8 +748,7 @@ void GLS_SetShadowMapCombiner() {
glUseProgram(g_draw_shadow_map_program);
glBindImageTexture(TlutImageUnit, g_tlut_tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R16UI);
GLenum depthTexFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16UI;
GLuint texture = frameBuffer.top->pDepthBuffer->depth_texture->glName;
glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, depthTexFormat);
glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
gDP.changed |= CHANGED_COMBINE;
}

View File

@ -567,9 +567,9 @@ void OGL_UpdateStates()
OGL_UpdateDepthUpdate();
if (gDP.otherMode.depthMode == ZMODE_DEC)
glEnable( GL_POLYGON_OFFSET_FILL );
else
// if (gDP.otherMode.depthMode == ZMODE_DEC)
// glEnable( GL_POLYGON_OFFSET_FILL );
// else
{
// glPolygonOffset( -3.0f, -3.0f );
glDisable( GL_POLYGON_OFFSET_FILL );

115
Shaders.h
View File

@ -147,71 +147,64 @@ static const char* fragment_shader_end =
"} \n"
;
static const char* depth_compare_shader_int =
"#version 420 core \n"
"uniform int depthEnabled; \n"
"uniform int depthCompareEnabled; \n"
"uniform int depthUpdateEnabled; \n"
"uniform unsigned int depthPolygonOffset; \n"
"uniform float depthTrans; \n"
"uniform float depthScale; \n"
"layout(binding = 0, r16ui) uniform readonly uimage2D zlut_image;\n"
"layout(binding = 2, r16ui) uniform restrict uimage2D depth_image;\n"
"bool depth_compare() \n"
"{ \n"
" if (depthEnabled == 0) return true; \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" highp uvec4 depth = imageLoad(depth_image,coord); \n"
" highp unsigned int bufZ = depth.r; \n"
" highp float fZ = 2.0*gl_FragCoord.z - 1.0; \n"
" fZ = (depthScale*fZ + depthTrans)*8.0; \n"
" highp int iZ = int(floor(fZ + 0.5)); \n"
" int y0 = iZ / 512; \n"
" int x0 = iZ - 512*y0; \n"
" highp unsigned int curZ = imageLoad(zlut_image,ivec2(x0,y0)).r; \n"
" curZ = curZ - depthPolygonOffset;\n"
" if (depthUpdateEnabled > 0 && curZ < depth.r) { \n"
" depth.r = curZ; \n"
" imageStore(depth_image,coord,depth); \n"
" } \n"
" memoryBarrier(); \n"
" if (depthCompareEnabled > 0) \n"
" return curZ <= bufZ; \n"
" return true; \n"
"} \n"
;
static const char* depth_compare_shader_float =
"#version 420 core \n"
"uniform int depthEnabled; \n"
"uniform int depthMode; \n"
"uniform int depthCompareEnabled; \n"
"uniform int depthUpdateEnabled; \n"
"uniform float depthPolygonOffset; \n"
"uniform float depthTrans; \n"
"uniform float depthScale; \n"
"layout(binding = 0, r16ui) uniform readonly uimage2D zlut_image;\n"
"layout(binding = 2, r32f) uniform restrict image2D depth_image;\n"
"layout(binding = 2, rgba32f) uniform restrict image2D depth_image;\n"
"void write_depth(in highp float dz, in ivec2 coord) \n"
"{ \n"
" highp float fZ = 2.0*gl_FragCoord.z - 1.0; \n"
" fZ = (depthScale*fZ + depthTrans)*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(zlut_image,ivec2(x0,y0)).r;\n"
" highp float n64z = clamp(float(iN64z)/65532.0, 0.0, 1.0);\n"
" highp vec4 depth = vec4(n64z, gl_FragCoord.z, dz, 1.0); \n"
" memoryBarrier(); \n"
" imageStore(depth_image,coord,depth); \n"
"} \n"
"bool depth_compare() \n"
"{ \n"
" if (depthEnabled == 0) return true; \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" memoryBarrier(); \n"
" highp vec4 depth = imageLoad(depth_image,coord); \n"
" highp float bufZ = depth.r; \n"
" highp float fZ = 2.0*gl_FragCoord.z - 1.0; \n"
" fZ = (depthScale*fZ + depthTrans)*8.0; \n"
" 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 icurZ = imageLoad(zlut_image,ivec2(x0,y0)).r;\n"
" highp float curZ = clamp(float(icurZ)/65532.0 - depthPolygonOffset, 0.0, 1.0); \n"
//" highp float curZ = clamp(float(icurZ)/65532.0, 0.0, 1.0); \n"
" if (depthUpdateEnabled > 0 && curZ < depth.r) { \n"
" depth.r = curZ; \n"
" imageStore(depth_image,coord,depth); \n"
" highp float bufZ = depth.g; \n"
" highp float curZ = gl_FragCoord.z; \n"
" highp float dz = fwidth(gl_FragCoord.z); \n"
" highp float dzMax = max(dz, depth.b); \n"
" const bool bInfront = curZ < bufZ; \n"
" const bool bFarther = (curZ + dzMax) >= bufZ; \n"
" const bool bNearer = (curZ - dzMax) <= bufZ; \n"
" const bool bMax = bufZ == 1.0; \n"
" bool bRes; \n"
" switch(depthMode) { \n"
" case 0: \n"
" case 1: \n"
" bRes = bMax || bNearer; \n"
" break; \n"
" case 2: \n"
" bRes = bMax || bInfront; \n"
" break; \n"
" case 3: \n"
" bRes = bFarther && bNearer && !bMax; \n"
" break; \n"
" default: \n"
" bRes = bInfront; \n"
" break; \n"
" } \n"
" if (depthUpdateEnabled > 0 && bRes) { \n"
" write_depth(dz, coord); \n"
" } \n"
" memoryBarrier(); \n"
" if (depthCompareEnabled > 0) \n"
" return curZ <= bufZ; \n"
" return bRes; \n"
" return true; \n"
"} \n"
;
@ -238,7 +231,7 @@ static const char* shadow_map_vertex_shader =
static const char* shadow_map_fragment_shader_float =
"#version 420 core \n"
"layout(binding = 1, r16ui) uniform readonly uimage1D tlut_image;\n"
"layout(binding = 2, r32f) uniform readonly image2D depth_image;\n"
"layout(binding = 2, rgba32f) uniform readonly image2D depth_image;\n"
"float get_alpha() \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
@ -253,23 +246,3 @@ static const char* shadow_map_fragment_shader_float =
" gl_FragColor = vec4(gl_Fog.color.rgb, get_alpha()); \n"
"} \n"
;
static const char* shadow_map_fragment_shader_int =
"#version 420 core \n"
"layout(binding = 1, r16ui) uniform readonly uimage1D tlut_image;\n"
"layout(binding = 2, r16ui) uniform readonly uimage2D depth_image;\n"
"float get_alpha() \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy); \n"
" unsigned int bufZ = imageLoad(depth_image,coord).r; \n"
" int index = min(255, int(bufZ/256)); \n"
" index += 80; \n"
" unsigned int iAlpha = imageLoad(tlut_image,index).r; \n"
" memoryBarrier(); \n"
" return float(iAlpha/256)/255.0; \n"
"} \n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4(gl_Fog.color.rgb, get_alpha()); \n"
"} \n"
;