diff --git a/src/pc/gfx/gfx.h b/src/pc/gfx/gfx.h index bcd524c6f..fb8137fb1 100644 --- a/src/pc/gfx/gfx.h +++ b/src/pc/gfx/gfx.h @@ -46,6 +46,7 @@ struct Box { struct GfxVertex { float x, y, z, w; + float clipX, clipY, clipZ, clipW; float u, v; struct RGBA color; uint8_t fog_z; diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 4d3a1cf4f..24693cfd1 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -693,6 +693,7 @@ static void OPTIMIZE_O3 gfx_sp_matrix(uint8_t parameters, const int32_t *addr) { memcpy(matrix, addr, sizeof(matrix)); #endif + gfx_flush(); if (parameters & G_MTX_PROJECTION) { if (parameters & G_MTX_LOAD) { @@ -718,6 +719,7 @@ static void OPTIMIZE_O3 gfx_sp_matrix(uint8_t parameters, const int32_t *addr) { } static void gfx_sp_pop_matrix(uint32_t count) { + gfx_flush(); while (count--) { if (rsp.modelview_matrix_stack_size > 0) { --rsp.modelview_matrix_stack_size; @@ -978,6 +980,12 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons d->z = v->ob[2]; d->w = 1.0; + d->clipX = v->ob[0] * rsp.MVP_matrix[0][0] + v->ob[1] * rsp.MVP_matrix[1][0] + v->ob[2] * rsp.MVP_matrix[2][0] + rsp.MVP_matrix[3][0]; + d->clipX *= gfx_current_dimensions.x_adjust_ratio; + d->clipY = v->ob[0] * rsp.MVP_matrix[0][1] + v->ob[1] * rsp.MVP_matrix[1][1] + v->ob[2] * rsp.MVP_matrix[2][1] + rsp.MVP_matrix[3][1]; + d->clipZ = v->ob[0] * rsp.MVP_matrix[0][2] + v->ob[1] * rsp.MVP_matrix[1][2] + v->ob[2] * rsp.MVP_matrix[2][2] + rsp.MVP_matrix[3][2]; + d->clipW = v->ob[0] * rsp.MVP_matrix[0][3] + v->ob[1] * rsp.MVP_matrix[1][3] + v->ob[2] * rsp.MVP_matrix[2][3] + rsp.MVP_matrix[3][3]; + if (!(rsp.geometry_mode & G_FRESNEL_ALPHA_EXT)) { d->color.a = v->cn[3]; } @@ -990,7 +998,7 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t struct GfxVertex *v1 = &rsp.loaded_vertices[vtx1_idx]; struct GfxVertex *v2 = &rsp.loaded_vertices[vtx2_idx]; struct GfxVertex *v3 = &rsp.loaded_vertices[vtx3_idx]; - struct GfxVertex *v_arr[3] = {v1, v2, v3}; + struct GfxVertex *v_arr[3] = { v1, v2, v3 }; int cull_mode = (rsp.geometry_mode & G_CULL_BOTH); if (cull_mode != sRenderingState.cull_mode) { @@ -1073,31 +1081,6 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t sRenderingState.rdp_fog_color_b = rdp.fog_color.b; } - if (memcmp(rsp.MVP_matrix, sRenderingState.mvp_matrix, sizeof(sRenderingState.mvp_matrix)) != 0) { - gfx_flush(); - mtxf_copy(sRenderingState.mvp_matrix, rsp.MVP_matrix); - } - - if (rsp.modelview_matrix_stack_size > 0 && memcmp(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], sRenderingState.mv_matrix, sizeof(sRenderingState.mv_matrix)) != 0) { - gfx_flush(); - mtxf_copy(sRenderingState.mv_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1]); - } - - if (memcmp(rsp.M_matrix, sRenderingState.m_matrix, sizeof(sRenderingState.m_matrix)) != 0) { - gfx_flush(); - mtxf_copy(sRenderingState.m_matrix, rsp.M_matrix); - } - - if (memcmp(rsp.V_matrix, sRenderingState.v_matrix, sizeof(sRenderingState.v_matrix)) != 0) { - gfx_flush(); - mtxf_copy(sRenderingState.v_matrix, rsp.V_matrix); - } - - if (memcmp(rsp.P_matrix, sRenderingState.p_matrix, sizeof(sRenderingState.p_matrix)) != 0) { - gfx_flush(); - mtxf_copy(sRenderingState.p_matrix, rsp.P_matrix); - } - if (rdp.viewport_or_scissor_changed) { static uint32_t x_adjust_4by3_prev; if (memcmp(&rdp.viewport, &sRenderingState.viewport, sizeof(rdp.viewport)) != 0 @@ -1186,16 +1169,10 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t buf_vbo[buf_vbo_len++] = v_arr[i]->w; // send position in clip space - float clipX = v_arr[i]->x * rsp.MVP_matrix[0][0] + v_arr[i]->y * rsp.MVP_matrix[1][0] + v_arr[i]->z * rsp.MVP_matrix[2][0] + rsp.MVP_matrix[3][0]; - clipX *= gfx_current_dimensions.x_adjust_ratio; - float clipY = v_arr[i]->x * rsp.MVP_matrix[0][1] + v_arr[i]->y * rsp.MVP_matrix[1][1] + v_arr[i]->z * rsp.MVP_matrix[2][1] + rsp.MVP_matrix[3][1]; - float clipZ = v_arr[i]->x * rsp.MVP_matrix[0][2] + v_arr[i]->y * rsp.MVP_matrix[1][2] + v_arr[i]->z * rsp.MVP_matrix[2][2] + rsp.MVP_matrix[3][2]; - float clipW = v_arr[i]->x * rsp.MVP_matrix[0][3] + v_arr[i]->y * rsp.MVP_matrix[1][3] + v_arr[i]->z * rsp.MVP_matrix[2][3] + rsp.MVP_matrix[3][3]; - - buf_vbo[buf_vbo_len++] = clipX; - buf_vbo[buf_vbo_len++] = clipY; - buf_vbo[buf_vbo_len++] = clipZ; - buf_vbo[buf_vbo_len++] = clipW; + buf_vbo[buf_vbo_len++] = v_arr[i]->clipX; + buf_vbo[buf_vbo_len++] = v_arr[i]->clipY; + buf_vbo[buf_vbo_len++] = v_arr[i]->clipZ; + buf_vbo[buf_vbo_len++] = v_arr[i]->clipW; // send texture data for (int32_t j = 0; j < 2; j++) { @@ -1259,7 +1236,7 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t color = &tmp; break; case CC_LOD: { - float distance_frac = (clipW - 3000.0f) / 3000.0f; + float distance_frac = (v_arr[i]->clipW - 3000.0f) / 3000.0f; if (distance_frac < 0.0f) { distance_frac = 0.0f; } if (distance_frac > 1.0f) { distance_frac = 1.0f; } tmp.r = tmp.g = tmp.b = tmp.a = distance_frac * 255.0f; @@ -1629,6 +1606,9 @@ static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lr lrxf = lrxf / (4.0f * HALF_SCREEN_WIDTH) - 1.0f; lryf = -(lryf / (4.0f * HALF_SCREEN_HEIGHT)) + 1.0f; + ulxf *= gfx_current_dimensions.x_adjust_ratio; + lrxf *= gfx_current_dimensions.x_adjust_ratio; + struct GfxVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0]; struct GfxVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1]; struct GfxVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2]; @@ -1638,21 +1618,25 @@ static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lr ul->y = ulyf; ul->z = 0.0f; ul->w = 1.0f; + memcpy(&ul->clipX, &ul->x, 4 * sizeof(float)); ll->x = ulxf; ll->y = lryf; ll->z = 0.0f; ll->w = 1.0f; + memcpy(&ll->clipX, &ll->x, 4 * sizeof(float)); lr->x = lrxf; lr->y = lryf; lr->z = 0.0f; lr->w = 1.0f; + memcpy(&lr->clipX, &lr->x, 4 * sizeof(float)); ur->x = lrxf; ur->y = ulyf; ur->z = 0.0f; ur->w = 1.0f; + memcpy(&ur->clipX, &ur->x, 4 * sizeof(float)); // The coordinates for texture rectangle shall bypass the viewport setting Mat4 oldMatrixMVP; @@ -1711,7 +1695,7 @@ static void gfx_draw_fullscreen_quad() { #else if (gRenderApi == &gfx_metal_api) { #endif - // flip y coordinates on texture + // flip y coordinates for (int i = 0; i < 6; i++) { quadVerticies[i * 6 + 5] = 1.0f - quadVerticies[i * 6 + 5]; } diff --git a/src/pc/gfx/gfx_shader.c b/src/pc/gfx/gfx_shader.c index 62ff769f6..a263b79b7 100644 --- a/src/pc/gfx/gfx_shader.c +++ b/src/pc/gfx/gfx_shader.c @@ -187,18 +187,17 @@ char *gfx_get_default_vertex_shader_from_cc(struct ColorCombiner *cc) { vs_len += sprintf(vs_buf + vs_len, "out vec4 vInput%d;\n", i + 1); } append_line(vs_buf, &vs_len, "in vec3 aNormal;"); - append_line(vs_buf, &vs_len, "out vec3 vNormal;"); append_line(vs_buf, &vs_len, "in vec3 aBarycentric;"); - append_line(vs_buf, &vs_len, "out vec3 vBarycentric;"); if (opt_fog) { append_line(vs_buf, &vs_len, "out float vFogZ;"); + append_line(vs_buf, &vs_len, "uniform float uFogMul;"); + append_line(vs_buf, &vs_len, "uniform float uFogIntensity;"); + append_line(vs_buf, &vs_len, "uniform float uFogOffset;"); + append_line(vs_buf, &vs_len, "uniform float uDepthZSub;"); + append_line(vs_buf, &vs_len, "uniform float uDepthZMult;"); + append_line(vs_buf, &vs_len, "uniform float uDepthZAdd;"); } - append_line(vs_buf, &vs_len, "uniform float uFogMul;"); - append_line(vs_buf, &vs_len, "uniform float uFogIntensity;"); - append_line(vs_buf, &vs_len, "uniform float uFogOffset;"); - append_line(vs_buf, &vs_len, "uniform float uDepthZSub;"); - append_line(vs_buf, &vs_len, "uniform float uDepthZMult;"); - append_line(vs_buf, &vs_len, "uniform float uDepthZAdd;"); + append_line(vs_buf, &vs_len, "uniform mat4 uModelViewProjectionMatrix;"); append_line(vs_buf, &vs_len, "void main() {"); for (int t = 0; t < 2; t++) { vs_len += sprintf(vs_buf + vs_len, "vTexCoord%d = aTexCoord%d;\n", t, t); @@ -208,15 +207,11 @@ char *gfx_get_default_vertex_shader_from_cc(struct ColorCombiner *cc) { for (int i = 0; i < CC_MAX_INPUTS; i++) { vs_len += sprintf(vs_buf + vs_len, "vInput%d = aInput%d;\n", i + 1, i + 1); } - append_line(vs_buf, &vs_len, "vNormal = aNormal;"); - append_line(vs_buf, &vs_len, "vBarycentric = aBarycentric;"); append_line(vs_buf, &vs_len, "gl_Position = aClipPos;"); if (opt_fog) { - append_line(vs_buf, &vs_len, "float w = aClipPos.w;"); - append_line(vs_buf, &vs_len, "if (abs(w) < 0.001) { w = 0.001; }"); + append_line(vs_buf, &vs_len, "float w = max(abs(aClipPos.w), 0.001);"); append_line(vs_buf, &vs_len, "float winv = 1.0 / w;"); - append_line(vs_buf, &vs_len, "if (winv < 0.0) { winv = 32767.0; }"); append_line(vs_buf, &vs_len, "float adjClipZ = aClipPos.z;"); append_line(vs_buf, &vs_len, "adjClipZ -= uDepthZSub;"); append_line(vs_buf, &vs_len, "adjClipZ *= uDepthZMult;"); @@ -259,9 +254,6 @@ char *gfx_get_default_fragment_shader_from_cc(struct ColorCombiner *cc) { fs_len += sprintf(fs_buf + fs_len, "in vec4 vInput%d;\n", i + 1); } - append_line(fs_buf, &fs_len, "in vec3 vNormal;"); - append_line(fs_buf, &fs_len, "in vec3 vBarycentric;"); - if (opt_fog) { append_line(fs_buf, &fs_len, "in float vFogZ;"); } @@ -364,7 +356,10 @@ char *gfx_get_default_fragment_shader_from_cc(struct ColorCombiner *cc) { } append_line(fs_buf, &fs_len, "uniform int uFilter;"); - append_line(fs_buf, &fs_len, "uniform vec3 uFogColor;"); + + if (opt_fog) { + append_line(fs_buf, &fs_len, "uniform vec3 uFogColor;"); + } append_line(fs_buf, &fs_len, "void main() {");