From 1bd50bad02dafdc19c87ee22246177f37c98cbe6 Mon Sep 17 00:00:00 2001 From: whitebelyash <66699673+whitebelyash@users.noreply.github.com> Date: Mon, 29 Dec 2025 16:03:55 +0400 Subject: [PATCH] Feat[depth]: implement dirty ANGLE depth clear workaround Fixes hand rendering through the blocks in vanilla Minecraft when ANGLE is used. For now requires explicitly specifying a variable. --- ltw/src/main/tinywrapper/Android.mk | 1 + ltw/src/main/tinywrapper/depth.c | 86 ++++++++++++++++++++++++ ltw/src/main/tinywrapper/depth.h | 10 +++ ltw/src/main/tinywrapper/egl.c | 6 ++ ltw/src/main/tinywrapper/egl.h | 2 +- ltw/src/main/tinywrapper/es3_overrides.h | 3 +- 6 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 ltw/src/main/tinywrapper/depth.c create mode 100644 ltw/src/main/tinywrapper/depth.h diff --git a/ltw/src/main/tinywrapper/Android.mk b/ltw/src/main/tinywrapper/Android.mk index 7735c66..40836ac 100644 --- a/ltw/src/main/tinywrapper/Android.mk +++ b/ltw/src/main/tinywrapper/Android.mk @@ -396,6 +396,7 @@ LOCAL_SRC_FILES := \ basevertex.c \ blending.c \ query.c \ + depth.c \ shader_wrapper.c \ string_utils.c \ framebuffer.c \ diff --git a/ltw/src/main/tinywrapper/depth.c b/ltw/src/main/tinywrapper/depth.c new file mode 100644 index 0000000..bcaac8c --- /dev/null +++ b/ltw/src/main/tinywrapper/depth.c @@ -0,0 +1,86 @@ +// +// Created by whbex on 29.12.2025. +// + +#include "egl.h" +#include "GL/gl.h" +#include "GL/glext.h" +#include "string.h" + +const char * v_shader_source = "" + "#version 300 es\n" + "void main() {\n" + "gl_Position = vec4(2.0 * vec2(gl_VertexID % 2, gl_VertexID / 2) - 1.0, 0.0, 1.0);\n" + "}\0"; +const char * f_shader_source = "#version 300 es\n" + "void main() {\n" + "}\0"; + +static GLuint current_program = 0; +static GLuint current_vao = 0; + +static GLuint build_shader(GLuint program, GLenum type, const char* source){ + GLuint shader = es3_functions.glCreateShader(type); + es3_functions.glShaderSource(shader, 1, &source, NULL); + es3_functions.glCompileShader(shader); + GLint status; + char log[512]; + es3_functions.glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (!status){ + printf("LTW: Depth clear shader compile failed!\n"); + es3_functions.glGetShaderInfoLog(shader, sizeof(log), NULL,log); + printf("LTW: Compile log: %s\n", log); + return shader; + } + es3_functions.glAttachShader(program, shader); + return shader; +} + +void depthfix_init_program(){ + if (!current_context->clear_depth_emu) return; + + current_program = es3_functions.glCreateProgram(); + GLuint vertex = build_shader(current_program, GL_VERTEX_SHADER, v_shader_source); + GLuint frag = build_shader(current_program, GL_FRAGMENT_SHADER, f_shader_source); + es3_functions.glLinkProgram(current_program); + es3_functions.glDeleteShader(vertex); + es3_functions.glDeleteShader(frag); + + es3_functions.glGenVertexArrays(1, ¤t_vao); +} + +void glClear(GLbitfield mask){ + if (!current_context->clear_depth_emu) goto real; + // printf("LTW: CLEAR BEGIN!!"); + if (mask != GL_DEPTH_BUFFER_BIT) goto real; + + // This is hard + GLint depth_func; + GLboolean depth_mask; + GLboolean color_mask[4]; + es3_functions.glGetIntegerv(GL_DEPTH_FUNC, &depth_func); + es3_functions.glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask); + es3_functions.glGetBooleanv(GL_COLOR_WRITEMASK, color_mask); + es3_functions.glDepthFunc(GL_ALWAYS); + es3_functions.glEnable(GL_DEPTH_TEST); + es3_functions.glDepthMask(GL_TRUE); + es3_functions.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + es3_functions.glUseProgram(current_program); + es3_functions.glBindVertexArray(current_vao); + es3_functions.glDrawArrays(GL_QUADS, 0, 4); + es3_functions.glUseProgram(0); + es3_functions.glBindVertexArray(0); + // printf("LTW: CLEAR END!!"); + + + es3_functions.glDisable(GL_DEPTH_TEST); + es3_functions.glDepthFunc(depth_func); + es3_functions.glDepthMask(depth_mask); + // es3_functions.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + es3_functions.glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]); + + return; + real: + es3_functions.glClear(mask); +} \ No newline at end of file diff --git a/ltw/src/main/tinywrapper/depth.h b/ltw/src/main/tinywrapper/depth.h new file mode 100644 index 0000000..30007fe --- /dev/null +++ b/ltw/src/main/tinywrapper/depth.h @@ -0,0 +1,10 @@ +// +// Created by whbex on 29.12.2025. +// + +#ifndef POJAVLAUNCHER_DEPTH_H +#define POJAVLAUNCHER_DEPTH_H + +void depthfix_init_program(); + +#endif //POJAVLAUNCHER_DEPTH_H diff --git a/ltw/src/main/tinywrapper/egl.c b/ltw/src/main/tinywrapper/egl.c index 2851fbc..56c8fb9 100644 --- a/ltw/src/main/tinywrapper/egl.c +++ b/ltw/src/main/tinywrapper/egl.c @@ -7,6 +7,7 @@ #include "unordered_map/int_hash.h" #include "string_utils.h" #include "env.h" +#include "depth.h" #include thread_local context_t *current_context; @@ -212,6 +213,11 @@ static void init_incontext(context_t* tw_context) { basevertex_init(tw_context); buffer_copier_init(tw_context); es3_functions.glGenBuffers(1, &tw_context->multidraw_element_buffer); + if(env_istrue_d("LTW_EMULATE_DEPTHCLEAR", false)){ + printf("LTW: Enabling ANGLE depth clear workaround\n"); + tw_context->clear_depth_emu = true; + depthfix_init_program(); + } } EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { diff --git a/ltw/src/main/tinywrapper/egl.h b/ltw/src/main/tinywrapper/egl.h index 9553e81..2cd30e8 100644 --- a/ltw/src/main/tinywrapper/egl.h +++ b/ltw/src/main/tinywrapper/egl.h @@ -69,7 +69,7 @@ typedef struct { typedef struct { EGLContext phys_context; bool context_rdy; - bool es31, es32, buffer_storage, buffer_texture_ext, multidraw_indirect, timer_query; + bool es31, es32, buffer_storage, buffer_texture_ext, multidraw_indirect, timer_query, clear_depth_emu; GLint shader_version; basevertex_renderer_t basevertex; PFNGLDRAWELEMENTSBASEVERTEXPROC drawelementsbasevertex; diff --git a/ltw/src/main/tinywrapper/es3_overrides.h b/ltw/src/main/tinywrapper/es3_overrides.h index 065b801..23a0f4e 100644 --- a/ltw/src/main/tinywrapper/es3_overrides.h +++ b/ltw/src/main/tinywrapper/es3_overrides.h @@ -132,4 +132,5 @@ GLESOVERRIDE(glGetError) GLESOVERRIDE(glTexBuffer) GLESOVERRIDE(glTexBufferRange) GLESOVERRIDE(glMapBufferRange) -GLESOVERRIDE(glFlushMappedBufferRange) \ No newline at end of file +GLESOVERRIDE(glFlushMappedBufferRange) +GLESOVERRIDE(glClear) \ No newline at end of file