mirror of
https://github.com/MobileGL-Dev/MobileGlues.git
synced 2025-09-22 10:42:11 -04:00
[Fix] (GL): Force depth clear when glClear is called with depth=1.0 on ANGLE.
This commit is contained in:
parent
4bcd4d0dee
commit
d16d87fd26
@ -1,4 +1,4 @@
|
|||||||
//
|
//
|
||||||
// Created by Swung0x48 on 2024/10/8.
|
// Created by Swung0x48 on 2024/10/8.
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -7,16 +7,124 @@
|
|||||||
#include "glcorearb.h"
|
#include "glcorearb.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "../gles/loader.h"
|
#include "../gles/loader.h"
|
||||||
|
#include "../config/settings.h"
|
||||||
#include "mg.h"
|
#include "mg.h"
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
|
static GLclampd currentDepthValue;
|
||||||
|
|
||||||
void glClearDepth(GLclampd depth) {
|
void glClearDepth(GLclampd depth) {
|
||||||
LOG()
|
LOG()
|
||||||
|
currentDepthValue = depth;
|
||||||
GLES.glClearDepthf((float)depth);
|
GLES.glClearDepthf((float)depth);
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLuint g_depthClearProgram = 0;
|
||||||
|
static GLuint g_depthClearVAO = 0;
|
||||||
|
static GLuint g_depthClearVBO = 0;
|
||||||
|
|
||||||
|
static const GLfloat kFullScreenTri[3][2] = {
|
||||||
|
{ -1.0f, -1.0f },
|
||||||
|
{ 3.0f, -1.0f },
|
||||||
|
{ -1.0f, 3.0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* kDepthClearVS = R"glsl(
|
||||||
|
#version 300 es
|
||||||
|
layout(location = 0) in vec2 aPos;
|
||||||
|
void main() {
|
||||||
|
// Write far‐plane depth
|
||||||
|
gl_Position = vec4(aPos, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
)glsl";
|
||||||
|
static const char* kDepthClearFS = R"glsl(
|
||||||
|
#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
out vec4 fragColor;
|
||||||
|
void main() {
|
||||||
|
// Empty—color writes will be disabled
|
||||||
|
fragColor = vec4(0.0);
|
||||||
|
}
|
||||||
|
)glsl";
|
||||||
|
|
||||||
|
void InitDepthClearCoreProfile() {
|
||||||
|
if (g_depthClearProgram) return;
|
||||||
|
|
||||||
|
auto compile = [&](GLenum type, const char* src) {
|
||||||
|
GLuint s = GLES.glCreateShader(type);
|
||||||
|
GLES.glShaderSource(s, 1, &src, nullptr);
|
||||||
|
GLES.glCompileShader(s);
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
GLuint vs = compile(GL_VERTEX_SHADER, kDepthClearVS);
|
||||||
|
GLuint fs = compile(GL_FRAGMENT_SHADER, kDepthClearFS);
|
||||||
|
|
||||||
|
g_depthClearProgram = GLES.glCreateProgram();
|
||||||
|
GLES.glAttachShader(g_depthClearProgram, vs);
|
||||||
|
GLES.glAttachShader(g_depthClearProgram, fs);
|
||||||
|
GLES.glLinkProgram(g_depthClearProgram);
|
||||||
|
GLES.glDeleteShader(vs);
|
||||||
|
GLES.glDeleteShader(fs);
|
||||||
|
|
||||||
|
GLES.glGenVertexArrays(1, &g_depthClearVAO);
|
||||||
|
GLES.glGenBuffers(1, &g_depthClearVBO);
|
||||||
|
|
||||||
|
GLES.glBindVertexArray(g_depthClearVAO);
|
||||||
|
GLES.glBindBuffer(GL_ARRAY_BUFFER, g_depthClearVBO);
|
||||||
|
GLES.glBufferData(GL_ARRAY_BUFFER, sizeof(kFullScreenTri), kFullScreenTri, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
GLES.glEnableVertexAttribArray(0);
|
||||||
|
GLES.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
|
|
||||||
|
GLES.glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
GLES.glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawDepthClearTri() {
|
||||||
|
InitDepthClearCoreProfile();
|
||||||
|
|
||||||
|
GLboolean prevColorMask[4];
|
||||||
|
GLES.glGetBooleanv(GL_COLOR_WRITEMASK, prevColorMask);
|
||||||
|
GLboolean prevDepthMask;
|
||||||
|
GLES.glGetBooleanv(GL_DEPTH_WRITEMASK, &prevDepthMask);
|
||||||
|
GLint prevDepthFunc;
|
||||||
|
GLES.glGetIntegerv(GL_DEPTH_FUNC, &prevDepthFunc);
|
||||||
|
|
||||||
|
GLES.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
GLES.glDepthMask(GL_TRUE);
|
||||||
|
GLES.glDepthFunc(GL_ALWAYS);
|
||||||
|
|
||||||
|
GLES.glUseProgram(g_depthClearProgram);
|
||||||
|
GLES.glBindVertexArray(g_depthClearVAO);
|
||||||
|
GLES.glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
GLES.glBindVertexArray(0);
|
||||||
|
GLES.glUseProgram(0);
|
||||||
|
|
||||||
|
GLES.glDepthFunc(prevDepthFunc);
|
||||||
|
GLES.glDepthMask(prevDepthMask);
|
||||||
|
GLES.glColorMask(prevColorMask[0], prevColorMask[1], prevColorMask[2], prevColorMask[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glClear(GLbitfield mask) {
|
||||||
|
LOG();
|
||||||
|
LOG_D("glClear, mask = 0x%x", mask);
|
||||||
|
|
||||||
|
if (global_settings.angle == AngleMode::Enabled && mask == GL_DEPTH_BUFFER_BIT && fabs(currentDepthValue - 1.0f) <= 0.001f) {
|
||||||
|
// Workaround for ANGLE depth-clear bug: if depth≈1.0, draw a fullscreen triangle at z=1.0 to force actual depth buffer write.
|
||||||
|
DrawDepthClearTri();
|
||||||
|
// Clear again
|
||||||
|
GLES.glClear(mask);
|
||||||
|
} else {
|
||||||
|
GLES.glClear(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_GL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void glHint(GLenum target, GLenum mode) {
|
void glHint(GLenum target, GLenum mode) {
|
||||||
LOG()
|
LOG()
|
||||||
LOG_D("glHint, target = %s, mode = %s", glEnumToString(target), glEnumToString(mode))
|
LOG_D("glHint, target = %s, mode = %s", glEnumToString(target), glEnumToString(mode))
|
||||||
|
@ -27,7 +27,7 @@ NATIVE_FUNCTION_HEAD(void, glBlendFuncSeparate, GLenum sfactorRGB, GLenum dfacto
|
|||||||
//NATIVE_FUNCTION_HEAD(void, glBufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) NATIVE_FUNCTION_END_NO_RETURN(void, glBufferData, target,size,data,usage)
|
//NATIVE_FUNCTION_HEAD(void, glBufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) NATIVE_FUNCTION_END_NO_RETURN(void, glBufferData, target,size,data,usage)
|
||||||
NATIVE_FUNCTION_HEAD(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) NATIVE_FUNCTION_END_NO_RETURN(void, glBufferSubData, target,offset,size,data)
|
NATIVE_FUNCTION_HEAD(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) NATIVE_FUNCTION_END_NO_RETURN(void, glBufferSubData, target,offset,size,data)
|
||||||
//NATIVE_FUNCTION_HEAD(GLenum, glCheckFramebufferStatus, GLenum target) NATIVE_FUNCTION_END(GLenum, glCheckFramebufferStatus, target)
|
//NATIVE_FUNCTION_HEAD(GLenum, glCheckFramebufferStatus, GLenum target) NATIVE_FUNCTION_END(GLenum, glCheckFramebufferStatus, target)
|
||||||
NATIVE_FUNCTION_HEAD(void, glClear, GLbitfield mask) NATIVE_FUNCTION_END_NO_RETURN(void, glClear, mask)
|
//NATIVE_FUNCTION_HEAD(void, glClear, GLbitfield mask) NATIVE_FUNCTION_END_NO_RETURN(void, glClear, mask)
|
||||||
NATIVE_FUNCTION_HEAD(void, glClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) NATIVE_FUNCTION_END_NO_RETURN(void, glClearColor, red,green,blue,alpha)
|
NATIVE_FUNCTION_HEAD(void, glClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) NATIVE_FUNCTION_END_NO_RETURN(void, glClearColor, red,green,blue,alpha)
|
||||||
NATIVE_FUNCTION_HEAD(void, glClearDepthf, GLfloat d) NATIVE_FUNCTION_END_NO_RETURN(void, glClearDepthf, d)
|
NATIVE_FUNCTION_HEAD(void, glClearDepthf, GLfloat d) NATIVE_FUNCTION_END_NO_RETURN(void, glClearDepthf, d)
|
||||||
NATIVE_FUNCTION_HEAD(void, glClearStencil, GLint s) NATIVE_FUNCTION_END_NO_RETURN(void, glClearStencil, s)
|
NATIVE_FUNCTION_HEAD(void, glClearStencil, GLint s) NATIVE_FUNCTION_END_NO_RETURN(void, glClearStencil, s)
|
||||||
|
@ -52,9 +52,9 @@ void internal_convert(GLenum* internal_format, GLenum* type, GLenum* format) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEPTH_COMPONENT32:
|
case GL_DEPTH_COMPONENT32:
|
||||||
*internal_format = GL_DEPTH_COMPONENT32F;
|
*internal_format = GL_DEPTH_COMPONENT;
|
||||||
if(type)
|
if(type)
|
||||||
*type = GL_FLOAT;
|
*type = GL_UNSIGNED_INT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEPTH_COMPONENT32F:
|
case GL_DEPTH_COMPONENT32F:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user