From 7271e3fcd59feb587c9c77182a736fdec8a6c50b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 14 Jan 2013 20:43:18 +0100 Subject: [PATCH] Fix fog and stencil buffer clearing. The latter fixes the sky in MotoGP. --- Core/Dialog/PSPSaveDialog.cpp | 1 - GPU/GLES/DisplayListInterpreter.cpp | 41 +++++++++++++++++++++++----- GPU/GLES/FragmentShaderGenerator.cpp | 28 +++++++++---------- GPU/GLES/ShaderManager.cpp | 27 ++++++++++++++---- GPU/GLES/StateMapping.cpp | 4 +++ GPU/GLES/TransformPipeline.cpp | 16 +++++++---- GPU/GLES/TransformPipeline.h | 4 +-- GPU/GLES/VertexDecoder.h | 2 +- GPU/GLES/VertexShaderGenerator.cpp | 40 +++++++++++++++++++-------- GPU/ge_constants.h | 3 ++ 10 files changed, 120 insertions(+), 46 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index c225d8ecb9..f845ba6ef6 100644 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -249,7 +249,6 @@ void PSPSaveDialog::DisplaySaveDataInfo1() char time[512]; char saveTitle[512]; char saveDetail[512]; - _dbg_assert_msg_(HLE, sizeof(txt) > sizeof(SaveFileInfo), "Local buffer is too small."); snprintf(title,512,"%s", param.GetFileInfo(currentSelectedSave).title); snprintf(time,512,"%02d/%02d/%d %02d:%02d %lld KB" diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 611364881d..af2186ade7 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -61,6 +61,12 @@ const int flushBeforeCommandList[] = { GE_CMD_TEXTUREMAPENABLE, GE_CMD_LIGHTINGENABLE, GE_CMD_FOGENABLE, + GE_CMD_ALPHABLENDENABLE, + GE_CMD_ALPHATESTENABLE, + GE_CMD_ALPHATEST, + GE_CMD_COLORTESTENABLE, + GE_CMD_COLORTESTMASK, + GE_CMD_COLORREF, GE_CMD_TEXSCALEU,GE_CMD_TEXSCALEV, GE_CMD_TEXOFFSETU,GE_CMD_TEXOFFSETV, GE_CMD_MINZ,GE_CMD_MAXZ, @@ -79,14 +85,24 @@ const int flushBeforeCommandList[] = { GE_CMD_TEXSIZE4,GE_CMD_TEXSIZE5,GE_CMD_TEXSIZE6,GE_CMD_TEXSIZE7, GE_CMD_ZBUFPTR, GE_CMD_ZBUFWIDTH, - GE_CMD_AMBIENTCOLOR, - GE_CMD_AMBIENTALPHA, + GE_CMD_TEXOFFSETU, + GE_CMD_TEXOFFSETV, + GE_CMD_TEXSCALEU, + GE_CMD_TEXSCALEV, + GE_CMD_OFFSETY, + GE_CMD_OFFSETX, + GE_CMD_OFFSETY, + GE_CMD_LMODE, + GE_CMD_REVERSENORMAL, + GE_CMD_MATERIALUPDATE, + GE_CMD_MATERIALEMISSIVE, GE_CMD_MATERIALAMBIENT, GE_CMD_MATERIALDIFFUSE, - GE_CMD_MATERIALEMISSIVE, GE_CMD_MATERIALSPECULAR, GE_CMD_MATERIALALPHA, GE_CMD_MATERIALSPECULARCOEF, + GE_CMD_AMBIENTCOLOR, + GE_CMD_AMBIENTALPHA, GE_CMD_COLORMODEL, GE_CMD_LIGHTTYPE0, GE_CMD_LIGHTTYPE1, GE_CMD_LIGHTTYPE2, GE_CMD_LIGHTTYPE3, GE_CMD_LX0,GE_CMD_LY0,GE_CMD_LZ0, @@ -112,14 +128,10 @@ const int flushBeforeCommandList[] = { GE_CMD_VIEWPORTZ1,GE_CMD_VIEWPORTZ2, GE_CMD_LIGHTENABLE0,GE_CMD_LIGHTENABLE1,GE_CMD_LIGHTENABLE2,GE_CMD_LIGHTENABLE3, GE_CMD_CULL, - GE_CMD_LMODE, GE_CMD_REVERSENORMAL, GE_CMD_PATCHDIVISION, GE_CMD_MATERIALUPDATE, GE_CMD_CLEARMODE, - GE_CMD_ALPHABLENDENABLE, - GE_CMD_ALPHATESTENABLE, - GE_CMD_ALPHATEST, GE_CMD_TEXFUNC, GE_CMD_TEXFILTER, GE_CMD_TEXENVCOLOR, @@ -130,6 +142,7 @@ const int flushBeforeCommandList[] = { GE_CMD_ZTESTENABLE, GE_CMD_STENCILTESTENABLE, GE_CMD_STENCILOP, + GE_CMD_STENCILTEST, GE_CMD_ZTEST, GE_CMD_FOG1, GE_CMD_FOG2, @@ -680,6 +693,18 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { case GE_CMD_LIGHTINGENABLE: break; + case GE_CMD_FOGCOLOR: + shaderManager_->DirtyUniform(DIRTY_FOGCOLOR); + break; + + case GE_CMD_FOG1: + shaderManager_->DirtyUniform(DIRTY_FOGCOEF); + break; + + case GE_CMD_FOG2: + shaderManager_->DirtyUniform(DIRTY_FOGCOEF); + break; + case GE_CMD_FOGENABLE: break; @@ -973,9 +998,11 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { break; case GE_CMD_ALPHATESTENABLE: + case GE_CMD_COLORTESTENABLE: // This is done in the shader. break; + case GE_CMD_COLORREF: case GE_CMD_ALPHATEST: shaderManager_->DirtyUniform(DIRTY_ALPHACOLORREF); break; diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 090f0684cc..8b86c23c47 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -73,23 +73,23 @@ void GenerateFragmentShader(char *buffer) int lmode = gstate.lmode & 1; int doTexture = (gstate.textureMapEnable & 1) && !(gstate.clearmode & 1); + bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear(); if (doTexture) WRITE(p, "uniform sampler2D tex;\n"); - if ((gstate.alphaTestEnable & 1) || (gstate.colorTestEnable & 1)) + if ((gstate.alphaTestEnable & 1) || (gstate.colorTestEnable & 1)) { WRITE(p, "uniform vec4 u_alphacolorref;\n"); - if (gstate.fogEnable & 1) { - WRITE(p, "uniform vec3 u_fogcolor;\n"); - WRITE(p, "uniform vec2 u_fogcoef;\n"); } WRITE(p, "uniform vec3 u_texenv;\n"); WRITE(p, "varying vec4 v_color0;\n"); if (lmode) WRITE(p, "varying vec3 v_color1;\n"); + if (enableFog) { + WRITE(p, "uniform vec3 u_fogcolor;\n"); + WRITE(p, "varying float v_fogdepth;\n"); + } if (doTexture) WRITE(p, "varying vec2 v_texcoord;\n"); - if (gstate.isFogEnabled()) - WRITE(p, "varying float v_depth;\n"); WRITE(p, "void main() {\n"); WRITE(p, " vec4 v;\n"); @@ -107,17 +107,17 @@ void GenerateFragmentShader(char *buffer) WRITE(p, " vec4 s = vec4(v_color1, 0.0);"); secondary = " + s"; } else { - WRITE(p, " vec4 s = vec4(0.0, 0.0, 0.0, 0.0);\n"); + WRITE(p, " vec4 s = vec4(0.0, 0.0, 0.0, 0.0);\n"); secondary = ""; } if (gstate.textureMapEnable & 1) { - WRITE(p, " vec4 t = texture2D(tex, v_texcoord);\n"); - WRITE(p, " vec4 p = clamp(v_color0, 0.0, 1.0);\n"); + WRITE(p, " vec4 t = texture2D(tex, v_texcoord);\n"); + WRITE(p, " vec4 p = clamp(v_color0, 0.0, 1.0);\n"); } else { // No texture mapping - WRITE(p, " vec4 t = vec4(1.0, 1.0, 1.0, 1.0);\n"); - WRITE(p, " vec4 p = clamp(v_color0, 0.0, 1.0);\n"); + WRITE(p, " vec4 t = vec4(1.0, 1.0, 1.0, 1.0);\n"); + WRITE(p, " vec4 p = clamp(v_color0, 0.0, 1.0);\n"); } if (gstate.texfunc & 0x100) { // texfmt == RGBA @@ -174,9 +174,9 @@ void GenerateFragmentShader(char *buffer) WRITE(p, "if (!(v.rgb %s u_alphacolorref.rgb)) discard;", colorTestFuncs[colorTestFunc]); }*/ - if (gstate.isFogEnabled()) { - // Haven't figured out how to adjust the depth range yet. - // WRITE(p, " v = mix(v, u_fogcolor, u_fogcoef.x + u_fogcoef.y * v_depth;\n"); + if (enableFog) { + WRITE(p, " float fogCoef = clamp(v_fogdepth, 0.0, 1.0);\n"); + WRITE(p, " v = mix(vec4(u_fogcolor, v.a), v, fogCoef);\n"); // WRITE(p, " v.x = v_depth;\n"); } } diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 4cc0261a83..6adf32d051 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -138,19 +138,33 @@ LinkedShader::~LinkedShader() { // Utility static void SetColorUniform3(int uniform, u32 color) { - const float col[3] = { ((color & 0xFF0000) >> 16) / 255.0f, ((color & 0xFF00) >> 8) / 255.0f, ((color & 0xFF)) / 255.0f}; + const float col[3] = { + ((color & 0xFF)) / 255.0f, + ((color & 0xFF00) >> 8) / 255.0f, + ((color & 0xFF0000) >> 16) / 255.0f + }; glUniform3fv(uniform, 1, col); } static void SetColorUniform3Alpha(int uniform, u32 color, u8 alpha) { - const float col[4] = { ((color & 0xFF0000) >> 16) / 255.0f, ((color & 0xFF00) >> 8) / 255.0f, ((color & 0xFF)) / 255.0f, alpha/255.0f}; + const float col[4] = { + ((color & 0xFF)) / 255.0f, + ((color & 0xFF00) >> 8) / 255.0f, + ((color & 0xFF0000) >> 16) / 255.0f, + alpha/255.0f + }; glUniform4fv(uniform, 1, col); } static void SetColorUniform3ExtraFloat(int uniform, u32 color, float extra) { - const float col[4] = { ((color & 0xFF0000) >> 16) / 255.0f, ((color & 0xFF00) >> 8) / 255.0f, ((color & 0xFF)) / 255.0f, extra}; + const float col[4] = { + ((color & 0xFF)) / 255.0f, + ((color & 0xFF00) >> 8) / 255.0f, + ((color & 0xFF0000) >> 16) / 255.0f, + extra + }; glUniform4fv(uniform, 1, col); } @@ -226,13 +240,16 @@ void LinkedShader::updateUniforms() { SetColorUniform3(u_texenv, gstate.texenvcolor); } if (u_alphacolorref != -1 && (dirtyUniforms & DIRTY_ALPHACOLORREF)) { - glUniform4f(u_alphacolorref, 0.0f, 0.0f, 0.0f, ((float)((gstate.alphatest >> 8) & 0xFF)) / 255.0f); + SetColorUniform3Alpha(u_alphacolorref, gstate.colortest, (gstate.alphatest >> 8) & 0xFF); } if (u_fogcolor != -1 && (dirtyUniforms & DIRTY_FOGCOLOR)) { SetColorUniform3(u_fogcolor, gstate.fogcolor); } if (u_fogcoef != -1 && (dirtyUniforms & DIRTY_FOGCOEF)) { - const float fogcoef[2] = { getFloat24(gstate.fog1), getFloat24(gstate.fog2) }; + const float fogcoef[2] = { + getFloat24(gstate.fog1), + getFloat24(gstate.fog2), + }; glUniform2fv(u_fogcoef, 1, fogcoef); } diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 4e2be0fd0a..460bef72e7 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -183,6 +183,10 @@ void ApplyDrawState(int prim) { glstate.stencilOp.set(stencilOps[gstate.stencilop & 0x7], // stencil fail stencilOps[(gstate.stencilop >> 8) & 0x7], // depth fail stencilOps[(gstate.stencilop >> 16) & 0x7]); + } else if (gstate.isModeClear()) { + glstate.stencilTest.enable(); + glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE); + glstate.stencilFunc.set(GL_ALWAYS, 0, 0xFF); } else { glstate.stencilTest.disable(); } diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 511a38d5ed..e5367f10df 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -332,7 +332,7 @@ static void SwapUVs(TransformedVertex &a, TransformedVertex &b) { // Used by Star Soldier and Ys vs Sora. static void RotateUVs(TransformedVertex v[4]) { - if ((v[0].x > v[2].x && v[0].y < v[2].y) || (v[0].x < v[2].x && v[0].y > v[2].y)) { + if ((v[0].x > v[2].x && v[0].y < v[2].y) /*|| (v[0].x < v[2].x && v[0].y > v[2].y)*/) { SwapUVs(v[1], v[3]); } } @@ -365,6 +365,8 @@ void TransformDrawEngine::SoftwareTransformAndDraw( #endif Lighter lighter; + float fog_end = getFloat24(gstate.fog1); + float fog_slope = getFloat24(gstate.fog2); VertexReader reader(decoded, decVtxFormat); for (int index = 0; index < maxIndex; index++) { @@ -374,6 +376,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( float c0[4] = {1, 1, 1, 1}; float c1[4] = {0, 0, 0, 0}; float uv[2] = {0, 0}; + float fogCoef = 1.0f; if (throughmode) { // Do not touch the coordinates or the colors. No lighting. @@ -393,6 +396,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( if (reader.hasUV()) { reader.ReadUV(uv); } + fogCoef = 1.0f; // Scale UV? } else { // We do software T&L for now @@ -533,10 +537,12 @@ void TransformDrawEngine::SoftwareTransformAndDraw( // Transform the coord by the view matrix. Vec3ByMatrix43(v, out, gstate.viewMatrix); + fogCoef = (v[2] + fog_end) * fog_slope; } // TODO: Write to a flexible buffer, we don't always need all four components. memcpy(&transformed[index].x, v, 3 * sizeof(float)); + transformed[index].fog = fogCoef; memcpy(&transformed[index].u, uv, 2 * sizeof(float)); memcpy(&transformed[index].color0, c0, 4 * sizeof(float)); memcpy(&transformed[index].color1, c1, 3 * sizeof(float)); @@ -622,10 +628,10 @@ void TransformDrawEngine::SoftwareTransformAndDraw( glBufferData(GL_ARRAY_BUFFER, vertexSize * numTrans, drawBuffer, GL_DYNAMIC_DRAW); drawBuffer = 0; // so that the calls use offsets instead. } - glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, vertexSize, drawBuffer); - if (program->a_texcoord != -1) glVertexAttribPointer(program->a_texcoord, 2, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 3 * 4); - if (program->a_color0 != -1) glVertexAttribPointer(program->a_color0, 4, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 5 * 4); - if (program->a_color1 != -1) glVertexAttribPointer(program->a_color1, 3, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 9 * 4); + glVertexAttribPointer(program->a_position, 4, GL_FLOAT, GL_FALSE, vertexSize, drawBuffer); + if (program->a_texcoord != -1) glVertexAttribPointer(program->a_texcoord, 2, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 4 * 4); + if (program->a_color0 != -1) glVertexAttribPointer(program->a_color0, 4, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 6 * 4); + if (program->a_color1 != -1) glVertexAttribPointer(program->a_color1, 3, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 10 * 4); if (drawIndexed) { if (useVBO) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_[curVbo_]); diff --git a/GPU/GLES/TransformPipeline.h b/GPU/GLES/TransformPipeline.h index 6c3164bd40..8591213dd4 100644 --- a/GPU/GLES/TransformPipeline.h +++ b/GPU/GLES/TransformPipeline.h @@ -98,9 +98,9 @@ struct Color4 { a+=c.a; } void GetFromRGB(u32 col) { - r = ((col>>16) & 0xff)/255.0f; + b = ((col>>16) & 0xff)/255.0f; g = ((col>>8) & 0xff)/255.0f; - b = ((col>>0) & 0xff)/255.0f; + r = ((col>>0) & 0xff)/255.0f; } void GetFromA(u32 col) { a = (col&0xff)/255.0f; diff --git a/GPU/GLES/VertexDecoder.h b/GPU/GLES/VertexDecoder.h index 771e1e35a7..3d348a64cc 100644 --- a/GPU/GLES/VertexDecoder.h +++ b/GPU/GLES/VertexDecoder.h @@ -53,7 +53,7 @@ struct DecVtxFormat { // This struct too. struct TransformedVertex { - float x, y, z; // in case of morph, preblend during decode + float x, y, z, fog; // in case of morph, preblend during decode float u; float v; // scaled by uscale, vscale, if there float color0[4]; // prelit float color1[3]; // prelit diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index 5444be8489..3829db0cee 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -135,6 +135,7 @@ void GenerateVertexShader(int prim, char *buffer) { bool hwXForm = CanUseHardwareTransform(prim); bool hasColor = (gstate.vertType & GE_VTYPE_COL_MASK) != 0 || !hwXForm; bool hasNormal = (gstate.vertType & GE_VTYPE_NRM_MASK) != 0 && hwXForm; + bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear(); DoLightComputation doLight[4] = {LIGHT_OFF, LIGHT_OFF, LIGHT_OFF, LIGHT_OFF}; if (hwXForm) { @@ -154,7 +155,11 @@ void GenerateVertexShader(int prim, char *buffer) { WRITE(p, "%s", boneWeightAttrDecl[gstate.getNumBoneWeights() - 1]); } - WRITE(p, "attribute vec3 a_position;\n"); + if (hwXForm) + WRITE(p, "attribute vec3 a_position;\n"); + else + WRITE(p, "attribute vec4 a_position;\n"); // need to pass the fog coord in w + if (doTexture) WRITE(p, "attribute vec2 a_texcoord;\n"); if (hasColor) { WRITE(p, "attribute vec4 a_color0;\n"); @@ -175,6 +180,10 @@ void GenerateVertexShader(int prim, char *buffer) { if (hwXForm || !hasColor) WRITE(p, "uniform vec4 u_matambientalpha;\n"); // matambient + matalpha + if (enableFog) { + WRITE(p, "uniform vec2 u_fogcoef;\n"); + } + if (hwXForm) { // When transforming by hardware, we need a great deal more uniforms... WRITE(p, "uniform mat4 u_world;\n"); @@ -216,7 +225,8 @@ void GenerateVertexShader(int prim, char *buffer) { WRITE(p, "varying vec4 v_color0;\n"); if (lmode) WRITE(p, "varying vec3 v_color1;\n"); if (doTexture) WRITE(p, "varying vec2 v_texcoord;\n"); - if (gstate.isFogEnabled()) WRITE(p, "varying float v_depth;\n"); + if (enableFog) WRITE(p, "varying float v_fogdepth;\n"); + WRITE(p, "void main() {\n"); if (!hwXForm) { @@ -232,16 +242,19 @@ void GenerateVertexShader(int prim, char *buffer) { if (lmode) WRITE(p, " v_color1 = vec3(0.0, 0.0, 0.0);\n"); } + if (enableFog) { + WRITE(p, " v_fogdepth = a_position.w;\n"); + } if (gstate.isModeThrough()) { - WRITE(p, " gl_Position = u_proj_through * vec4(a_position, 1.0);\n"); + WRITE(p, " gl_Position = u_proj_through * vec4(a_position.xyz, 1.0);\n"); } else { - WRITE(p, " gl_Position = u_proj * vec4(a_position, 1.0);\n"); + WRITE(p, " gl_Position = u_proj * vec4(a_position.xyz, 1.0);\n"); } } else { // Step 1: World Transform / Skinning if ((gstate.vertType & GE_VTYPE_WEIGHT_MASK) == GE_VTYPE_WEIGHT_NONE) { // No skinning, just standard T&L. - WRITE(p, " vec3 worldpos = (u_world * vec4(a_position, 1.0)).xyz;\n"); + WRITE(p, " vec3 worldpos = (u_world * vec4(a_position.xyz, 1.0)).xyz;\n"); if (hasNormal) WRITE(p, " vec3 worldnormal = (u_world * vec4(a_normal, 0.0)).xyz;\n"); } else { @@ -254,7 +267,7 @@ void GenerateVertexShader(int prim, char *buffer) { // workaround for "cant do .x of scalar" issue if (numWeights == 1 && i == 0) weightAttr = "a_weight0123"; if (numWeights == 5 && i == 4) weightAttr = "a_weight4567"; - WRITE(p, " worldpos += %s * (u_bone%i * vec4(a_position, 1.0)).xyz;\n", weightAttr, i); + WRITE(p, " worldpos += %s * (u_bone%i * vec4(a_position.xyz, 1.0)).xyz;\n", weightAttr, i); if (hasNormal) WRITE(p, " worldnormal += %s * (u_bone%i * vec4(a_normal, 0.0)).xyz;\n", weightAttr, i); } @@ -266,6 +279,8 @@ void GenerateVertexShader(int prim, char *buffer) { if (hasNormal) WRITE(p, " worldnormal = normalize(worldnormal);\n"); + WRITE(p, " vec4 viewPos = u_view * vec4(worldpos, 1.0);\n"); + // Step 2: Color/Lighting if (hasColor) { WRITE(p, " vec3 unlitColor = a_color0.rgb;\n"); @@ -331,7 +346,7 @@ void GenerateVertexShader(int prim, char *buffer) { if (lmode) { WRITE(p, " v_color1 = clamp(lightSum1, 0.0, 1.0);\n"); } else { - WRITE(p, " v_color0 += vec4(lightSum1, 0.0);\n"); + WRITE(p, " v_color0 = clamp(v_color0 + vec4(lightSum1, 0.0), 0.0, 1.0);\n"); } } else { // Lighting doesn't affect color. @@ -354,7 +369,7 @@ void GenerateVertexShader(int prim, char *buffer) { case 1: // Projection mapping. switch (gstate.getUVProjMode()) { case 0: // Use model space XYZ as source - WRITE(p, " vec3 temp_tc = a_position;\n"); + WRITE(p, " vec3 temp_tc = a_position.xyz;\n"); break; case 1: // Use unscaled UV as source WRITE(p, " vec3 temp_tc = vec3(a_texcoord.xy, 0.0);\n"); @@ -379,11 +394,14 @@ void GenerateVertexShader(int prim, char *buffer) { break; } } + + // Compute fogdepth + if (enableFog) + WRITE(p, " v_fogdepth = (viewPos.z + u_fogcoef.x) * u_fogcoef.y;\n"); + // Step 4: Final view and projection transforms. - WRITE(p, " gl_Position = u_proj * (u_view * vec4(worldpos, 1.0));\n"); + WRITE(p, " gl_Position = u_proj * viewPos;\n"); } - if (gstate.isFogEnabled()) - WRITE(p, " v_depth = gl_Position.z;\n"); WRITE(p, "}\n"); } diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index da29502624..2d131442f4 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -220,6 +220,9 @@ enum GECommand GE_CMD_SCISSOR2=0xD5, GE_CMD_MINZ=0xD6, GE_CMD_MAXZ=0xD7, + GE_CMD_COLORTEST=0xD8, + GE_CMD_COLORREF=0xD9, + GE_CMD_COLORTESTMASK=0xDA, GE_CMD_ALPHATEST=0xDB, GE_CMD_STENCILTEST=0xDC, GE_CMD_STENCILOP=0xDD,