forked from Ports/goldeneye-pc-port
Draw order more fixes
This commit is contained in:
1 parent
6c183d9434
commit
0e767334f7
1 file changed
+44
-5
@@ -42,6 +42,8 @@ struct ShaderProgram {
|
||||
GLint decal_scale_location;
|
||||
int decal_mode;
|
||||
float decal_scale;
|
||||
GLint depth_prepass_location;
|
||||
int depth_prepass;
|
||||
};
|
||||
|
||||
struct Framebuffer {
|
||||
@@ -83,6 +85,14 @@ static uint32_t depth_copy_width, depth_copy_height;
|
||||
static bool current_depth_test;
|
||||
static bool current_depth_decal;
|
||||
|
||||
// Translucent surfaces write no depth and are only drawn in rough back-to-front order, so a farther
|
||||
// railing drawn later blended over a nearer one. Their nearly opaque texels (railing bars) first get
|
||||
// a depth-only pass, then the surface is drawn as usual: semi-transparent texels are unchanged.
|
||||
#define XLU_DEPTH_PREPASS_ALPHA "0.98"
|
||||
static bool current_depth_compare;
|
||||
static GLenum current_depth_func = GL_LESS;
|
||||
static bool current_blend;
|
||||
|
||||
static int gl_glsl_version = 130;
|
||||
static char gl_glsl_version_str[16] = "130";
|
||||
static GLenum gl_mirror_clamp = GL_MIRROR_CLAMP_TO_EDGE;
|
||||
@@ -417,6 +427,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||
append_line(fs_buf, &fs_len, "uniform int frame_count;");
|
||||
append_line(fs_buf, &fs_len, "uniform float noise_scale;");
|
||||
append_line(fs_buf, &fs_len, "uniform int uDecalMode;");
|
||||
append_line(fs_buf, &fs_len, "uniform int uDepthPrepass;");
|
||||
append_line(fs_buf, &fs_len, "uniform highp float uDecalPixelScale;");
|
||||
append_line(fs_buf, &fs_len, "uniform highp sampler2D uDepthTex;");
|
||||
|
||||
@@ -617,6 +628,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||
if (cc_features.opt_invisible) {
|
||||
append_line(fs_buf, &fs_len, " texel.a = 0.0;");
|
||||
}
|
||||
append_line(fs_buf, &fs_len, " if (uDepthPrepass != 0 && texel.a < " XLU_DEPTH_PREPASS_ALPHA ") discard;");
|
||||
|
||||
append_line(fs_buf, &fs_len, " OUTPUT_COLOR = texel;");
|
||||
} else {
|
||||
@@ -740,6 +752,11 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||
prg->decal_scale_location = glGetUniformLocation(shader_program, "uDecalPixelScale");
|
||||
prg->decal_mode = 0;
|
||||
prg->decal_scale = 0.0f;
|
||||
prg->depth_prepass_location = glGetUniformLocation(shader_program, "uDepthPrepass");
|
||||
prg->depth_prepass = 0;
|
||||
if (prg->depth_prepass_location >= 0) {
|
||||
glUniform1i(prg->depth_prepass_location, 0);
|
||||
}
|
||||
if (prg->decal_mode_location >= 0) {
|
||||
glUniform1i(prg->decal_mode_location, 0);
|
||||
glUniform1i(glGetUniformLocation(shader_program, "uDepthTex"), DECAL_DEPTH_TEXTURE_UNIT);
|
||||
@@ -902,6 +919,7 @@ static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint
|
||||
|
||||
static void gfx_opengl_set_depth_mode(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode) {
|
||||
current_depth_test = depth_test;
|
||||
current_depth_compare = depth_compare;
|
||||
current_depth_decal = depth_test && depth_compare && zmode == ZMODE_DEC;
|
||||
|
||||
if (depth_test) {
|
||||
@@ -912,7 +930,7 @@ static void gfx_opengl_set_depth_mode(bool depth_test, bool depth_update, bool d
|
||||
if (depth_compare) {
|
||||
switch (zmode) {
|
||||
case ZMODE_INTER:
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthFunc(current_depth_func = GL_LEQUAL);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0, 0);
|
||||
break;
|
||||
@@ -920,22 +938,22 @@ static void gfx_opengl_set_depth_mode(bool depth_test, bool depth_update, bool d
|
||||
case ZMODE_OPA:
|
||||
case ZMODE_XLU:
|
||||
if (depth_source_prim) {
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthFunc(current_depth_func = GL_LEQUAL);
|
||||
} else {
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthFunc(current_depth_func = GL_LESS);
|
||||
}
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0, 0);
|
||||
break;
|
||||
|
||||
case ZMODE_DEC:
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthFunc(current_depth_func = GL_LEQUAL);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-2, -2);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glDepthFunc(current_depth_func = GL_ALWAYS);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0, 0);
|
||||
}
|
||||
@@ -961,6 +979,7 @@ static void gfx_opengl_set_scissor(int x, int y, int width, int height) {
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_use_alpha(bool use_alpha, bool modulate) {
|
||||
current_blend = use_alpha && !modulate;
|
||||
if (use_alpha) {
|
||||
glEnable(GL_BLEND);
|
||||
} else {
|
||||
@@ -1084,6 +1103,26 @@ static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_
|
||||
}
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buf_vbo_len, buf_vbo, GL_STREAM_DRAW);
|
||||
|
||||
struct ShaderProgram* prg = current_shader_program;
|
||||
if (!current_depth_decal && current_depth_test && current_depth_compare && !current_depth_mask && current_blend &&
|
||||
prg != nullptr && prg->depth_prepass_location >= 0) {
|
||||
glUniform1i(prg->depth_prepass_location, 1);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
||||
glUniform1i(prg->depth_prepass_location, 0);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
// The colour pass must pass where the prepass just stored this surface's own depth
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
||||
glDepthFunc(current_depth_func);
|
||||
depth_copy_dirty = true;
|
||||
return;
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
||||
|
||||
if (current_depth_test && current_depth_mask) {
|
||||
|
||||
Reference in new issue
Block a user