diff --git a/Source/Core/Common/Src/LinearDiskCache.cpp b/Source/Core/Common/Src/LinearDiskCache.cpp index 7dcc3333cb..f27b41e6e8 100644 --- a/Source/Core/Common/Src/LinearDiskCache.cpp +++ b/Source/Core/Common/Src/LinearDiskCache.cpp @@ -22,7 +22,7 @@ static const char ID[4] = {'D', 'C', 'A', 'C'}; // Update this to the current SVN revision every time you change shader generation code. // We don't automatically get this from SVN_REV because that would mean regenerating the // shader cache for every revision, graphics-related or not, which is simply annoying. -const int version = 6148; +const int version = 6223; LinearDiskCache::LinearDiskCache() : file_(NULL), num_entries_(0) { diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 1a12b60772..5a8050896a 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -24,6 +24,8 @@ #include "PixelShaderGen.h" #include "XFMemory.h" // for texture projection mode #include "BPMemory.h" +#include "VideoConfig.h" +#include "NativeVertexFormat.h" PIXELSHADERUID last_pixel_shader_uid; @@ -57,15 +59,26 @@ void GetPixelShaderId(PIXELSHADERUID *uid, u32 dstAlphaEnable) for (int i = 0; i < 8; i += 2) ((u8*)&uid->values[1])[i / 2] = (bpmem.tevksel[i].hex & 0xf) | ((bpmem.tevksel[i + 1].hex & 0xf) << 4); - uid->values[2] = 0; - u32 enableZTexture = (!bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable)?1:0; - uid->values[3] = (u32)bpmem.fog.c_proj_fsel.fsel | + uid->values[2] = (u32)bpmem.fog.c_proj_fsel.fsel | ((u32)bpmem.fog.c_proj_fsel.proj << 3) | ((u32)enableZTexture << 4); - int hdr = 4; + if(g_ActiveConfig.bEnablePixelLigting) + { + for (int i = 0; i < 2; ++i) { + uid->values[3 + i] = xfregs.colChans[i].color.enablelighting ? + (u32)xfregs.colChans[i].color.hex : + (u32)xfregs.colChans[i].color.matsource; + uid->values[3 + i] |= (xfregs.colChans[i].alpha.enablelighting ? + (u32)xfregs.colChans[i].alpha.hex : + (u32)xfregs.colChans[i].alpha.matsource) << 15; + } + } + uid->values[4] |= g_ActiveConfig.bEnablePixelLigting << 31; + + int hdr = 5; u32 *pcurvalue = &uid->values[hdr]; for (u32 i = 0; i < numstages; ++i) { @@ -135,7 +148,8 @@ void GetPixelShaderId(PIXELSHADERUID *uid, u32 dstAlphaEnable) } // yeah, well .... - uid->indstages = (u32)(pcurvalue - &uid->values[0] - (hdr - 1) - uid->tevstages); + uid->indstages = (u32)(pcurvalue - &uid->values[0] - (hdr - 1) - uid->tevstages); + } // old tev->pixelshader notes @@ -366,7 +380,69 @@ static void BuildSwapModeTable() } } -const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType) +char *GeneratePixelLightShader(char *p, int index, const LitChannel& chan, const char *dest, int coloralpha) +{ + const char* swizzle = "xyzw"; + if (coloralpha == 1 ) swizzle = "xyz"; + else if (coloralpha == 2 ) swizzle = "w"; + + if (!(chan.attnfunc & 1)) { + // atten disabled + switch (chan.diffusefunc) { + case LIGHTDIF_NONE: + WRITE(p, "%s.%s += "I_PLIGHTS".lights[%d].col.%s;\n", dest, swizzle, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + WRITE(p, "ldir = normalize("I_PLIGHTS".lights[%d].pos.xyz - pos.xyz);\n", index); + WRITE(p, "%s.%s += %sdot(ldir, _norm0)) * "I_PLIGHTS".lights[%d].col.%s;\n", + dest, swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", index, swizzle); + break; + default: _assert_(0); + } + } + else { // spec and spot + + if (chan.attnfunc == 3) + { // spot + WRITE(p, "ldir = "I_PLIGHTS".lights[%d].pos.xyz - pos.xyz;\n", index); + WRITE(p, "dist2 = dot(ldir, ldir);\n" + "dist = sqrt(dist2);\n" + "ldir = ldir / dist;\n" + "attn = max(0.0f, dot(ldir, "I_PLIGHTS".lights[%d].dir.xyz));\n",index); + WRITE(p, "attn = max(0.0f, dot("I_PLIGHTS".lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot("I_PLIGHTS".lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", index, index); + } + else if (chan.attnfunc == 1) + { // specular + WRITE(p, "ldir = normalize("I_PLIGHTS".lights[%d].pos.xyz);\n",index); + WRITE(p, "attn = (dot(_norm0,ldir) > 0.0f) ? max(0.0f, dot(_norm0, "I_PLIGHTS".lights[%d].dir.xyz)) : 0.0f;\n", index); + WRITE(p, "attn = max(0.0f, dot("I_PLIGHTS".lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot("I_PLIGHTS".lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", index, index); + } + + switch (chan.diffusefunc) + { + case LIGHTDIF_NONE: + WRITE(p, "%s.%s += attn * "I_PLIGHTS".lights[%d].col.%s;\n", dest, swizzle, index, swizzle); + break; + case LIGHTDIF_SIGN: + case LIGHTDIF_CLAMP: + WRITE(p, "%s.%s += attn * %sdot(ldir, _norm0)) * "I_PLIGHTS".lights[%d].col.%s;\n", + dest, + swizzle, + chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", + index, + swizzle); + break; + default: _assert_(0); + } + } + WRITE(p, "\n"); + return p; +} + + + +const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType,u32 components) { setlocale(LC_NUMERIC, "C"); // Reset locale for compilation text[sizeof(text) - 1] = 0x7C; // canary @@ -431,10 +507,18 @@ const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType) WRITE(p, "uniform float4 "I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE); WRITE(p, "uniform float4 "I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX); WRITE(p, "uniform float4 "I_FOG"[2] : register(c%d);\n", C_FOG); + if(g_ActiveConfig.bEnablePixelLigting) + { + WRITE(p,"typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n"); + WRITE(p,"typedef struct { Light lights[8]; } s_"I_PLIGHTS";\n"); + WRITE(p, "uniform s_"I_PLIGHTS" "I_PLIGHTS" : register(c%d);\n", C_PLIGHTS); + WRITE(p, "typedef struct { float4 C0, C1, C2, C3; } s_"I_PMATERIALS";\n"); + WRITE(p, "uniform s_"I_PMATERIALS" "I_PMATERIALS" : register(c%d);\n", C_PMATERIALS); + } WRITE(p, "void main(\n"); if(ApiType != API_D3D11) - WRITE(p, " out float4 ocol0 : COLOR0,%s\n in float4 rawpos : POSITION,\n",DepthTextureEnable ? "\n out float depth : DEPTH," : ""); + WRITE(p, " out float4 ocol0 : COLOR0,%s\n in float4 rawpos : %s,\n",DepthTextureEnable ? "\n out float depth : DEPTH," : "", ApiType == API_OPENGL ? "WPOS" : "POSITION"); else WRITE(p, " out float4 ocol0 : SV_Target,%s\n in float4 rawpos : SV_Position,\n",DepthTextureEnable ? "\n out float depth : SV_Depth," : ""); @@ -446,14 +530,14 @@ const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType) { for (int i = 0; i < numTexgen; ++i) WRITE(p, ",\n in float3 uv%d : TEXCOORD%d", i, i); - WRITE(p, ",\n in float4 clipPos : TEXCOORD%d", numTexgen); + WRITE(p, ",\n in float4 Normal : TEXCOORD%d", numTexgen + 1); } else { // wpos is in w of first 4 texcoords - for (int i = 0; i < numTexgen; ++i) - WRITE(p, ",\n in float%d uv%d : TEXCOORD%d", i<4?4:3, i, i); + for (int i = 0; i < 8; ++i) + WRITE(p, ",\n in float4 uv%d : TEXCOORD%d", i, i); } WRITE(p, " ) {\n"); @@ -466,7 +550,138 @@ const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType) " float3 tevcoord;\n" " float2 wrappedcoord, tempcoord;\n" " float4 cc0, cc1, cc2, cprev,crastemp,ckonsttemp;\n\n"); + + if(g_ActiveConfig.bEnablePixelLigting) + { + if (xfregs.numTexGens < 7) + { + WRITE(p,"float3 _norm0 = normalize(Normal.xyz);\n\n"); + WRITE(p,"float3 pos = float3(clipPos.x,clipPos.y,Normal.w);\n"); + } + else + { + WRITE(p," float3 _norm0 = normalize(float3(uv4.w,uv5.w,uv6.w));\n\n"); + WRITE(p,"float3 pos = float3(uv0.w,uv1.w,uv7.w);\n"); + } + + WRITE(p, "float4 mat, lacc;\n" + "float3 ldir, h;\n" + "float dist, dist2, attn;\n"); + // lights/colors + for (int j = 0; j < xfregs.nNumChans; j++) + { + const LitChannel& color = xfregs.colChans[j].color; + const LitChannel& alpha = xfregs.colChans[j].alpha; + + WRITE(p, "{\n"); + + if (color.matsource) {// from vertex + if (components & (VB_HAS_COL0 << j)) + WRITE(p, "mat = colors_%d;\n", j); + else if (components & VB_HAS_COL0) + WRITE(p, "mat = colors_0;\n"); + else + WRITE(p, "mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + } + else // from color + WRITE(p, "mat = "I_PMATERIALS".C%d;\n", j+2); + + if (color.enablelighting) { + if (color.ambsource) { // from vertex + if (components & (VB_HAS_COL0<= 7) - WRITE(p, "float4 clipPos = float4(uv0.w, uv1.w, uv2.w, uv3.w);\n"); + // the screen space depth value = far z + (clip z / clip w) * z range WRITE(p, "float zCoord = "I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * "I_ZBIAS"[1].y;\n"); } @@ -579,7 +792,7 @@ const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType) { WriteFog(p); WRITE(p, " ocol0 = prev;\n"); - } + } } WRITE(p, "}\n"); if (text[sizeof(text) - 1] != 0x7C) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 0e0b6b3e3d..1552d949fe 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -28,18 +28,22 @@ #define I_INDTEXSCALE "cindscale" #define I_INDTEXMTX "cindmtx" #define I_FOG "cfog" +#define I_PLIGHTS "cLights" +#define I_PMATERIALS "cmtrl" -#define C_COLORS 0 -#define C_KCOLORS (C_COLORS + 4) -#define C_ALPHA (C_KCOLORS + 4) -#define C_TEXDIMS (C_ALPHA + 1) -#define C_ZBIAS (C_TEXDIMS + 8) -#define C_INDTEXSCALE (C_ZBIAS + 2) -#define C_INDTEXMTX (C_INDTEXSCALE + 2) -#define C_FOG (C_INDTEXMTX + 6) -#define C_COLORMATRIX (C_FOG + 2) -#define C_PENVCONST_END (C_COLORMATRIX + 16) -#define PIXELSHADERUID_MAX_VALUES (5 + 32 + 6 + 11) +#define C_COLORS 0 +#define C_KCOLORS (C_COLORS + 4) +#define C_ALPHA (C_KCOLORS + 4) +#define C_TEXDIMS (C_ALPHA + 1) +#define C_ZBIAS (C_TEXDIMS + 8) +#define C_INDTEXSCALE (C_ZBIAS + 2) +#define C_INDTEXMTX (C_INDTEXSCALE + 2) +#define C_FOG (C_INDTEXMTX + 6) +#define C_COLORMATRIX (C_FOG + 2) +#define C_PLIGHTS (C_COLORMATRIX + 4) +#define C_PMATERIALS (C_PLIGHTS + 40) +#define C_PENVCONST_END (C_PMATERIALS + 4) +#define PIXELSHADERUID_MAX_VALUES (5 + 32 + 6 + 11 + 2) // DO NOT make anything in this class virtual. class PIXELSHADERUID @@ -100,7 +104,7 @@ public: } }; -const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType); +const char *GeneratePixelShaderCode(bool dstAlphaEnable, API_TYPE ApiType,u32 components); void GetPixelShaderId(PIXELSHADERUID *uid, u32 dstAlphaEnable); extern PIXELSHADERUID last_pixel_shader_uid; diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index 304d3df941..e0bad16ee5 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -23,7 +23,7 @@ #include "PixelShaderManager.h" #include "VideoCommon.h" #include "VideoConfig.h" - +static float GC_ALIGNED16(s_fMaterials[16]); static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors static int s_nIndTexMtxChanged; static bool s_bAlphaChanged; @@ -32,6 +32,7 @@ static bool s_bZTextureTypeChanged; static bool s_bDepthRangeChanged; static bool s_bFogColorChanged; static bool s_bFogParamChanged; +static int nLightsChanged[2]; // min,max static float lastDepthRange[2]; // 0 = far z, 1 = far - near static float lastRGBAfull[2][4][4]; static u8 s_nTexDimsChanged; @@ -39,6 +40,7 @@ static u8 s_nIndTexScaleChanged; static u32 lastAlpha; static u32 lastTexDims[8]; // width | height << 16 | wrap_s << 28 | wrap_t << 30 static u32 lastZBias; +static int nMaterialsChanged; void PixelShaderManager::Init() { @@ -57,6 +59,8 @@ void PixelShaderManager::Dirty() s_nIndTexMtxChanged = 15; s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true; s_bFogColorChanged = s_bFogParamChanged = true; + nLightsChanged[0] = 0; nLightsChanged[1] = 0x80; + nMaterialsChanged = 15; } void PixelShaderManager::Shutdown() @@ -207,6 +211,50 @@ void PixelShaderManager::SetConstants() } s_bFogParamChanged = false; } + + if (nLightsChanged[0] >= 0) + { + // lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats + int istart = nLightsChanged[0] / 0x10; + int iend = (nLightsChanged[1] + 15) / 0x10; + const float* xfmemptr = (const float*)&xfmem[0x10 * istart + XFMEM_LIGHTS]; + + for (int i = istart; i < iend; ++i) + { + u32 color = *(const u32*)(xfmemptr + 3); + float NormalizationCoef = 1 / 255.0f; + SetPSConstant4f(C_PLIGHTS + 5 * i, + ((color >> 24) & 0xFF) * NormalizationCoef, + ((color >> 16) & 0xFF) * NormalizationCoef, + ((color >> 8) & 0xFF) * NormalizationCoef, + ((color) & 0xFF) * NormalizationCoef); + xfmemptr += 4; + + for (int j = 0; j < 4; ++j, xfmemptr += 3) + { + if (j == 1 && + fabs(xfmemptr[0]) < 0.00001f && + fabs(xfmemptr[1]) < 0.00001f && + fabs(xfmemptr[2]) < 0.00001f) + { + // dist attenuation, make sure not equal to 0!!! + SetPSConstant4f(C_PLIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0); + } + else + SetPSConstant4fv(C_PLIGHTS+5*i+j+1, xfmemptr); + } + } + + nLightsChanged[0] = nLightsChanged[1] = -1; + } + if (nMaterialsChanged) + { + for (int i = 0; i < 4; ++i) + if (nMaterialsChanged & (1 << i)) + SetPSConstant4fv(C_PMATERIALS + i, &s_fMaterials[4 * i]); + + nMaterialsChanged = 0; + } } void PixelShaderManager::SetPSTextureDims(int texid) @@ -349,3 +397,35 @@ void PixelShaderManager::SetColorMatrix(const float* pmatrix, const float* pfCon SetMultiPSConstant4fv(C_COLORMATRIX,4,pmatrix); SetPSConstant4fv(C_COLORMATRIX+4, pfConstAdd); } + +void PixelShaderManager::InvalidateXFRange(int start, int end) +{ + if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS) + { + int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start-XFMEM_LIGHTS; + int _end = end < XFMEM_LIGHTS_END ? end-XFMEM_LIGHTS : XFMEM_LIGHTS_END-XFMEM_LIGHTS; + + if (nLightsChanged[0] == -1 ) + { + nLightsChanged[0] = _start; + nLightsChanged[1] = _end; + } + else + { + if (nLightsChanged[0] > _start) nLightsChanged[0] = _start; + if (nLightsChanged[1] < _end) nLightsChanged[1] = _end; + } + } +} + +void PixelShaderManager::SetMaterialColor(int index, u32 data) +{ + int ind = index * 4; + + nMaterialsChanged |= (1 << index); + float NormalizationCoef = 1 / 255.0f; + s_fMaterials[ind++] = ((data >> 24) & 0xFF) * NormalizationCoef; + s_fMaterials[ind++] = ((data >> 16) & 0xFF) * NormalizationCoef; + s_fMaterials[ind++] = ((data >> 8) & 0xFF) * NormalizationCoef; + s_fMaterials[ind] = ( data & 0xFF) * NormalizationCoef; +} diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h index a838e75c91..c45f9153a0 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.h +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h @@ -19,6 +19,7 @@ #define _PIXELSHADERMANAGER_H #include "BPMemory.h" +#include "XFMemory.h" #include "PixelShaderGen.h" void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); @@ -51,6 +52,8 @@ public: static void SetFogColorChanged(); static void SetFogParamChanged(); static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd); + static void InvalidateXFRange(int start, int end); + static void SetMaterialColor(int index, u32 data); }; diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index d271299d44..ab9e46182b 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -24,6 +24,7 @@ #include "BPMemory.h" #include "CPMemory.h" #include "VertexShaderGen.h" +#include "VideoConfig.h" VERTEXSHADERUID last_vertex_shader_uid; @@ -44,7 +45,7 @@ void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components) (u32)xfregs.colChans[i].alpha.hex : (u32)xfregs.colChans[i].alpha.matsource) << 15; } - + uid->values[2] |= g_ActiveConfig.bEnablePixelLigting << 31; u32 *pcurvalue = &uid->values[3]; for (int i = 0; i < xfregs.numTexGens; ++i) { TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo; @@ -115,11 +116,21 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) for (int i = 0; i < xfregs.numTexGens; ++i) WRITE(p, " float3 tex%d : TEXCOORD%d;\n", i, i); WRITE(p, " float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGens); + if(g_ActiveConfig.bEnablePixelLigting) + WRITE(p, " float4 Normal : TEXCOORD%d;\n", xfregs.numTexGens + 1); } else { // clip position is in w of first 4 texcoords - for (int i = 0; i < xfregs.numTexGens; ++i) - WRITE(p, " float%d tex%d : TEXCOORD%d;\n", i<4?4:3, i, i); - } + if(g_ActiveConfig.bEnablePixelLigting) + { + for (int i = 0; i < 8; ++i) + WRITE(p, " float4 tex%d : TEXCOORD%d;\n", i, i); + } + else + { + for (int i = 0; i < xfregs.numTexGens; ++i) + WRITE(p, " float%d tex%d : TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, i); + } + } WRITE(p, "};\n"); // uniforms @@ -134,7 +145,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) WRITE(p, "uniform s_"I_PROJECTION" "I_PROJECTION" : register(c%d);\n", C_PROJECTION); WRITE(p, "uniform float4 "I_DEPTHPARAMS" : register(c%d);\n", C_DEPTHPARAMS); - WRITE(p, "VS_OUTPUT main(\n"); + WRITE(p, "VS_OUTPUT main(\n"); // inputs if (components & VB_HAS_NRM0) @@ -169,8 +180,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) WRITE(p, " float fposmtx : ATTR%d,\n", SHADER_POSMTX_ATTRIB); } WRITE(p, " float4 rawpos : POSITION) {\n"); - WRITE(p, "VS_OUTPUT o;\n"); - + WRITE(p, "VS_OUTPUT o;\n"); // transforms if (components & VB_HAS_POSMTXIDX) { if (api_type == API_D3D9) @@ -187,8 +197,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) WRITE(p, "int posmtx = fposmtx;\n"); } - WRITE(p, "float4 pos = float4(dot("I_TRANSFORMMATRICES".T[posmtx].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+1].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+2].t, rawpos), 1);\n"); - + WRITE(p, "float4 pos = float4(dot("I_TRANSFORMMATRICES".T[posmtx].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+1].t, rawpos), dot("I_TRANSFORMMATRICES".T[posmtx+2].t, rawpos), 1);\n"); + if (components & VB_HAS_NRMALL) { WRITE(p, "int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n"); WRITE(p, "float3 N0 = "I_NORMALMATRICES".T[normidx].t.xyz, N1 = "I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = "I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); @@ -215,9 +225,11 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) if (!(components & VB_HAS_NRM0)) WRITE(p, "float3 _norm0 = float3(0.0f, 0.0f, 0.0f);\n"); + + WRITE(p, "o.pos = float4(dot("I_PROJECTION".T0, pos), dot("I_PROJECTION".T1, pos), dot("I_PROJECTION".T2, pos), dot("I_PROJECTION".T3, pos));\n"); - WRITE(p, "float4 mat, lacc;\n" // = half4(1, 1, 1, 1), lacc = half4(0, 0, 0, 0);\n" + WRITE(p, "float4 mat, lacc;\n" "float3 ldir, h;\n" "float dist, dist2, attn;\n"); @@ -226,7 +238,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) if (components & VB_HAS_COL0) WRITE(p, "o.colors_0 = color0;\n"); else - WRITE(p, "o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); + WRITE(p, "o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); } // lights/colors for (int j = 0; j < xfregs.nNumChans; j++) @@ -293,8 +305,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) else { WRITE(p, "lacc.w = 1.0f;\n"); - } - + } if(color.enablelighting && alpha.enablelighting) { @@ -341,7 +352,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) if (components & VB_HAS_COL1) WRITE(p, "o.colors_1 = color1;\n"); else - WRITE(p, "o.colors_1 = o.colors_0;\n"); + WRITE(p, "o.colors_1 = o.colors_0;\n"); } // special case if only pos and tex coord 0 and tex coord input is AB11 // donko - this has caused problems in some games. removed for now. @@ -460,14 +471,34 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) // clipPos/w needs to be done in pixel shader, not here if (xfregs.numTexGens < 7) { - WRITE(p, "o.clipPos = o.pos;\n"); + WRITE(p, "o.clipPos = float4(pos.x,pos.y,o.pos.z,o.pos.w);\n"); } else { - WRITE(p, "o.tex0.w = o.pos.x;\n"); - WRITE(p, "o.tex1.w = o.pos.y;\n"); + WRITE(p, "o.tex0.w = pos.x;\n"); + WRITE(p, "o.tex1.w = pos.y;\n"); WRITE(p, "o.tex2.w = o.pos.z;\n"); WRITE(p, "o.tex3.w = o.pos.w;\n"); } + if(g_ActiveConfig.bEnablePixelLigting) + { + if (xfregs.numTexGens < 7) { + WRITE(p, "o.Normal = float4(_norm0.x,_norm0.y,_norm0.z,pos.z);\n"); + } else { + WRITE(p, "o.tex4.w = _norm0.x;\n"); + WRITE(p, "o.tex5.w = _norm0.y;\n"); + WRITE(p, "o.tex6.w = _norm0.z;\n"); + if (xfregs.numTexGens < 8) + WRITE(p, "o.tex7 = pos.xyzz;\n"); + else + WRITE(p, "o.tex7.w = pos.z;\n"); + } + if (components & VB_HAS_COL0) + WRITE(p, "o.colors_0 = color0;\n"); + + if (components & VB_HAS_COL1) + WRITE(p, "o.colors_1 = color1;\n"); + } + //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed if (is_d3d) { diff --git a/Source/Core/VideoCommon/Src/VertexShaderManager.cpp b/Source/Core/VideoCommon/Src/VertexShaderManager.cpp index fead1e0797..db272fd08c 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderManager.cpp @@ -379,7 +379,7 @@ void VertexShaderManager::SetConstants() PRIM_LOG("Projection: %f %f %f %f %f %f\n", xfregs.rawProjection[0], xfregs.rawProjection[1], xfregs.rawProjection[2], xfregs.rawProjection[3], xfregs.rawProjection[4], xfregs.rawProjection[5]); - if (g_ActiveConfig.bFreeLook) + if ((g_ActiveConfig.bFreeLook || g_ActiveConfig.bAnaglyphStereo ) && xfregs.rawProjection[6] == 0) { Matrix44 mtxA; Matrix44 mtxB; diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 3483ac1b37..f9584fc89c 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -72,6 +72,11 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Settings", "DumpEFBTarget", &bDumpEFBTarget, 0); iniFile.Get("Settings", "DumpFrames", &bDumpFrames, 0); iniFile.Get("Settings", "FreeLook", &bFreeLook, 0); + iniFile.Get("Settings", "AnaglyphStereo", &bAnaglyphStereo, false); + iniFile.Get("Settings", "AnaglyphStereoSeparation", &iAnaglyphStereoSeparation, 200); + iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0); + iniFile.Get("Settings", "EnablePixelLigting", &bEnablePixelLigting, 0); + iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0); iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); iniFile.Get("Settings", "EFBScale", &iEFBScale, 0); @@ -184,6 +189,11 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Settings", "DumpEFBTarget", bDumpEFBTarget); iniFile.Set("Settings", "DumpFrames", bDumpFrames); iniFile.Set("Settings", "FreeLook", bFreeLook); + iniFile.Set("Settings", "AnaglyphStereo", bAnaglyphStereo); + iniFile.Set("Settings", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation); + iniFile.Set("Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); + iniFile.Set("Settings", "EnablePixelLigting", bEnablePixelLigting); + iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions); iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors); iniFile.Set("Settings", "MSAA", iMultisampleMode); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index be370f6e1c..1591f92575 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -109,6 +109,9 @@ struct VideoConfig bool bDumpEFBTarget; bool bDumpFrames; bool bFreeLook; + bool bAnaglyphStereo; + int iAnaglyphStereoSeparation; + int iAnaglyphFocalAngle; // Hacks bool bEFBAccessEnable; @@ -127,6 +130,7 @@ struct VideoConfig bool bProjHack1; float fAspectRatioHackW, fAspectRatioHackH; bool bZTPSpeedHack; // The Legend of Zelda: Twilight Princess + bool bEnablePixelLigting; int iLog; // CONF_ bits int iSaveTargetId; diff --git a/Source/Core/VideoCommon/Src/XFStructs.cpp b/Source/Core/VideoCommon/Src/XFStructs.cpp index 670e4bf188..b505351aff 100644 --- a/Source/Core/VideoCommon/Src/XFStructs.cpp +++ b/Source/Core/VideoCommon/Src/XFStructs.cpp @@ -36,6 +36,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) { VertexManager::Flush(); VertexShaderManager::InvalidateXFRange(address, address + transferSize); + PixelShaderManager::InvalidateXFRange(address, address + transferSize); //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize); memcpy_gc((u32*)&xfmem[address], &pData[i], transferSize*4); @@ -111,6 +112,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) VertexManager::Flush(); xfregs.colChans[chan].ambColor = data; VertexShaderManager::SetMaterialColor(chan, data); + PixelShaderManager::SetMaterialColor(chan, data); } break; } @@ -124,6 +126,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) VertexManager::Flush(); xfregs.colChans[chan].matColor = data; VertexShaderManager::SetMaterialColor(address - XFMEM_SETCHAN0_AMBCOLOR, data); + PixelShaderManager::SetMaterialColor(address - XFMEM_SETCHAN0_AMBCOLOR, data); } break; } @@ -217,6 +220,7 @@ void LoadIndexedXF(u32 val, int array) VertexManager::Flush(); VertexShaderManager::InvalidateXFRange(address, address+size); + PixelShaderManager::InvalidateXFRange(address, address+size); //PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address+size); for (int i = 0; i < size; i++) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp index 6f2bd39e1d..e861eec9a4 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp @@ -92,6 +92,8 @@ struct TabDirect3D : public W32Util::Tab Button_SetCheck(GetDlgItem(hDlg, IDC_VSYNC), g_Config.bVSync); Button_SetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE), g_Config.bSafeTextureCache); Button_SetCheck(GetDlgItem(hDlg, IDC_DLIST_CACHING), g_Config.bDlistCachingEnable); + Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLEPIXELLIGHTING), g_Config.bEnablePixelLigting); + if (g_Config.iSafeTextureCache_ColorSamples == 0) @@ -141,6 +143,9 @@ struct TabDirect3D : public W32Util::Tab case IDC_DLIST_CACHING: g_Config.bDlistCachingEnable = Button_GetCheck(GetDlgItem(hDlg, IDC_DLIST_CACHING)) == 0 ? false : true; break; + case IDC_ENABLEPIXELLIGHTING: + g_Config.bEnablePixelLigting = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEPIXELLIGHTING)) == 0 ? false : true; + break; case IDC_EFB_ACCESS_ENABLE: g_Config.bEFBAccessEnable = Button_GetCheck(GetDlgItem(hDlg, IDC_EFB_ACCESS_ENABLE)) == 0 ? false : true; break; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index c876652aa8..e482265c44 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -125,6 +125,16 @@ unsigned int ps_constant_offset_table[] = { 76, 80, // C_INDTEXSCALE, 8 84, 88, 92, 96, 100, 104, // C_INDTEXMTX, 24 108, 112, // C_FOG, 8 + 116, 120, 124 ,128, // C_COLORMATRIX, 16 + 132, 136, 140, 144, 148, // C_PLIGHTS0, 20 + 152, 156, 160, 164, 168, // C_PLIGHTS1, 20 + 172, 176, 180, 184, 188, // C_PLIGHTS2, 20 + 192, 196, 200, 204, 208, // C_PLIGHTS3, 20 + 212, 216, 220, 224, 228, // C_PLIGHTS4, 20 + 232, 236, 240, 244, 248, // C_PLIGHTS5, 20 + 252, 256, 260, 264, 268, // C_PLIGHTS6, 20 + 272, 276, 280, 284, 288, // C_PLIGHTS7, 20 + 292, 296, 300, 304, // C_PMATERIALS, 16 }; void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { @@ -215,7 +225,7 @@ void PixelShaderCache::Shutdown() g_ps_disk_cache.Close(); } -bool PixelShaderCache::SetShader(bool dstAlpha) +bool PixelShaderCache::SetShader(bool dstAlpha,u32 components) { PIXELSHADERUID uid; GetPixelShaderId(&uid, dstAlpha); @@ -243,7 +253,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha) } // need to compile a new shader - const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11); + const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11,components); D3DBlob* pbytecode; if (!D3D::CompilePixelShader(code, strlen(code), &pbytecode)) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h index d105503647..bc4691d431 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h @@ -32,7 +32,7 @@ public: static void Init(); static void Clear(); static void Shutdown(); - static bool SetShader(bool dstAlpha); + static bool SetShader(bool dstAlpha,u32 components); static bool InsertByteCode(const PIXELSHADERUID &uid, void* bytecode, unsigned int bytecodelen); static ID3D11PixelShader* GetColorMatrixProgram(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 8694f6955d..da04ef5edd 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -341,7 +341,7 @@ void Flush() VertexShaderManager::SetConstants(); PixelShaderManager::SetConstants(); - if (!PixelShaderCache::SetShader(false)) + if (!PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components)) goto shader_fail; if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) goto shader_fail; @@ -354,7 +354,7 @@ void Flush() if (bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate) { DWORD write = 0; - if (!PixelShaderCache::SetShader(true)) + if (!PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components)) goto shader_fail; // update alpha only diff --git a/Source/Plugins/Plugin_VideoDX11/Src/resource.h b/Source/Plugins/Plugin_VideoDX11/Src/resource.h index 7795520c82..c4d464ef1b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/resource.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/resource.h @@ -31,6 +31,7 @@ #define IDC_RADIO3 1043 #define IDC_SAFE_TEXTURE_CACHE_FAST 1043 #define IDC_DLIST_CACHING 1044 +#define IDC_ENABLEPIXELLIGHTING 1045 #define IDC_STATIC -1 // Next default values for new objects @@ -39,7 +40,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 106 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1045 +#define _APS_NEXT_CONTROL_VALUE 1046 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/Source/Plugins/Plugin_VideoDX11/Src/resource.rc b/Source/Plugins/Plugin_VideoDX11/Src/resource.rc index e19f898546..22fbdd0240 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/resource.rc +++ b/Source/Plugins/Plugin_VideoDX11/Src/resource.rc @@ -52,6 +52,7 @@ BEGIN CONTROL "Normal",IDC_SAFE_TEXTURE_CACHE_NORMAL,"Button",BS_AUTORADIOBUTTON,52,87,40,10 CONTROL "Fast",IDC_SAFE_TEXTURE_CACHE_FAST,"Button",BS_AUTORADIOBUTTON,92,87,32,10 CONTROL "Enable Dlist Caching",IDC_DLIST_CACHING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,98,80,10 + CONTROL "Enable Pixel Lighting",IDC_ENABLEPIXELLIGHTING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,112,81,10 END IDD_ADVANCED DIALOGEX 0, 0, 244, 200 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp index 0f756c68ca..0eeceaec65 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp @@ -55,6 +55,11 @@ BEGIN_EVENT_TABLE(GFXConfigDialogDX,wxDialog) EVT_CHECKBOX(ID_FORCEANISOTROPY, GFXConfigDialogDX::EnhancementsSettingsChanged) EVT_CHECKBOX(ID_LOADHIRESTEXTURES, GFXConfigDialogDX::EnhancementsSettingsChanged) EVT_CHECKBOX(ID_EFBSCALEDCOPY, GFXConfigDialogDX::EnhancementsSettingsChanged) + EVT_CHECKBOX(ID_PIXELLIGHTING, GFXConfigDialogDX::EnhancementsSettingsChanged) + EVT_CHECKBOX(ID_ANAGLYPH, GFXConfigDialogDX::EnhancementsSettingsChanged) + EVT_SLIDER(ID_ANAGLYPHSEPARATION, GFXConfigDialogDX::EnhancementsSettingsChanged) + EVT_SLIDER(ID_ANAGLYPHFOCALANGLE, GFXConfigDialogDX::EnhancementsSettingsChanged) + //Advanced Tab EVT_CHECKBOX(ID_DISABLEFOG, GFXConfigDialogDX::AdvancedSettingsChanged) @@ -133,7 +138,10 @@ void GFXConfigDialogDX::InitializeGUIValues() m_HiresTextures->SetValue(g_Config.bHiresTextures); m_MSAAModeCB->SetSelection(g_Config.iMultisampleMode); m_EFBScaledCopy->SetValue(g_Config.bCopyEFBScaled); - + m_Anaglyph->SetValue(g_Config.bAnaglyphStereo); + m_PixelLighting->SetValue(g_Config.bEnablePixelLigting); + m_AnaglyphSeparation->SetValue(g_Config.iAnaglyphStereoSeparation); + m_AnaglyphFocalAngle->SetValue(g_Config.iAnaglyphFocalAngle); //Advance m_DisableFog->SetValue(g_Config.bDisableFog); m_OverlayFPS->SetValue(g_Config.bShowFPS); @@ -267,6 +275,12 @@ void GFXConfigDialogDX::CreateGUIControls() wxStaticBoxSizer* sbEFBHacks; sbEFBHacks = new wxStaticBoxSizer( new wxStaticBox( m_PageEnhancements, wxID_ANY, wxT("EFB hacks") ), wxVERTICAL ); m_EFBScaledCopy = new wxCheckBox( m_PageEnhancements, ID_EFBSCALEDCOPY, wxT("EFB scaled copy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_Anaglyph = new wxCheckBox( m_PageEnhancements, ID_ANAGLYPH, wxT("Enable Anaglyph Stereo"), wxDefaultPosition, wxDefaultSize, 0 ); + m_PixelLighting = new wxCheckBox( m_PageEnhancements, ID_PIXELLIGHTING, wxT("Enable Pixel Lighting"), wxDefaultPosition, wxDefaultSize, 0 ); + m_AnaglyphSeparation = new wxSlider( m_PageEnhancements, ID_ANAGLYPHSEPARATION,2000,1,10000, wxDefaultPosition, wxDefaultSize, wxHORIZONTAL,wxDefaultValidator, wxT("Stereo separation") ); + m_AnaglyphFocalAngle = new wxSlider( m_PageEnhancements, ID_ANAGLYPHFOCALANGLE,0,-1000,1000, wxDefaultPosition, wxDefaultSize, wxHORIZONTAL,wxDefaultValidator, wxT("Stereo Focal Angle") ); + m_AnaglyphSeparationText = new wxStaticText( m_PageEnhancements, wxID_ANY, wxT("Stereo Separation:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_AnaglyphFocalAngleText= new wxStaticText( m_PageEnhancements, wxID_ANY, wxT("Focal Angle:"), wxDefaultPosition, wxDefaultSize, 0 ); // Sizers wxBoxSizer* sEnhancements; @@ -289,6 +303,21 @@ void GFXConfigDialogDX::CreateGUIControls() sbEFBHacks->Add( sEFBHacks, 1, wxEXPAND, 5 ); sEnhancements->Add( sbEFBHacks, 0, wxEXPAND|wxALL, 5 ); + wxStaticBoxSizer* sbImprovements; + sbImprovements = new wxStaticBoxSizer( new wxStaticBox( m_PageEnhancements, wxID_ANY, wxT("Improvements") ), wxVERTICAL ); + wxGridBagSizer* sImprovements; + sImprovements = new wxGridBagSizer( 0, 0 ); + sImprovements->SetFlexibleDirection( wxBOTH ); + sImprovements->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + sImprovements->Add( m_Anaglyph, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + sImprovements->Add( m_AnaglyphSeparationText, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + sImprovements->Add( m_AnaglyphFocalAngleText, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + sImprovements->Add( m_AnaglyphSeparation, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + sImprovements->Add( m_AnaglyphFocalAngle, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + sImprovements->Add( m_PixelLighting, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + sbImprovements->Add( sImprovements, 1, wxEXPAND, 5 ); + sEnhancements->Add( sbImprovements, 0, wxEXPAND|wxALL, 5 ); + m_PageEnhancements->SetSizer( sEnhancements ); m_PageEnhancements->Layout(); sEnhancements->Fit( m_PageEnhancements ); @@ -447,7 +476,19 @@ void GFXConfigDialogDX::EnhancementsSettingsChanged(wxCommandEvent& event) g_Config.bHiresTextures = m_HiresTextures->IsChecked(); break; case ID_EFBSCALEDCOPY: - g_Config.bCopyEFBScaled = m_EFBScaledCopy->IsChecked(); + g_Config.bCopyEFBScaled = m_EFBScaledCopy->IsChecked(); + break; + case ID_PIXELLIGHTING: + g_Config.bEnablePixelLigting = m_PixelLighting->IsChecked(); + break; + case ID_ANAGLYPH: + g_Config.bAnaglyphStereo = m_Anaglyph->IsChecked(); + break; + case ID_ANAGLYPHSEPARATION: + g_Config.iAnaglyphStereoSeparation = m_AnaglyphSeparation->GetValue(); + break; + case ID_ANAGLYPHFOCALANGLE: + g_Config.iAnaglyphFocalAngle = m_AnaglyphFocalAngle->GetValue(); break; } UpdateGUI(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.h b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.h index 553c98290a..064f883636 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.h @@ -106,7 +106,12 @@ class GFXConfigDialogDX : public wxDialog wxCheckBox *m_MaxAnisotropy; wxCheckBox *m_HiresTextures; wxCheckBox *m_EFBScaledCopy; - + wxCheckBox *m_Anaglyph; + wxCheckBox *m_PixelLighting; + wxStaticText* m_AnaglyphSeparationText; + wxSlider *m_AnaglyphSeparation; + wxStaticText* m_AnaglyphFocalAngleText; + wxSlider *m_AnaglyphFocalAngle; //Advanced Tab wxCheckBox *m_DisableFog; wxCheckBox *m_OverlayFPS; @@ -173,7 +178,11 @@ class GFXConfigDialogDX : public wxDialog ID_ABOUT, ID_DIRERCT3D, ID_PAGEENHANCEMENTS, - ID_PAGEADVANCED + ID_PAGEADVANCED, + ID_PIXELLIGHTING, + ID_ANAGLYPH, + ID_ANAGLYPHSEPARATION, + ID_ANAGLYPHFOCALANGLE, }; void InitializeAdapters(); void OnClose(wxCloseEvent& event); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 05449152d0..eca26d8bdd 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -274,7 +274,7 @@ void PixelShaderCache::Shutdown() unique_shaders.clear(); } -bool PixelShaderCache::SetShader(bool dstAlpha) +bool PixelShaderCache::SetShader(bool dstAlpha,u32 components) { PIXELSHADERUID uid; GetPixelShaderId(&uid, dstAlpha); @@ -312,7 +312,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha) } // OK, need to generate and compile it. - const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9); + const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9,components); u32 code_hash = HashAdler32((const u8 *)code, strlen(code)); unique_shaders.insert(code_hash); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h index 06ae56b935..713fc20557 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h @@ -60,7 +60,7 @@ private: public: static void Init(); static void Shutdown(); - static bool SetShader(bool dstAlpha); + static bool SetShader(bool dstAlpha, u32 componets); static bool InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate); static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode); static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 5fd1139295..97d17955b7 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -977,7 +977,7 @@ void Renderer::SetBlendMode(bool forceUpdate) } } - +static bool RightFrame = false; void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc) { @@ -1000,6 +1000,25 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } Renderer::ResetAPIState(); + if(g_ActiveConfig.bAnaglyphStereo) + { + if(RightFrame) + { + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); + VertexShaderManager::ResetView(); + VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); + VertexShaderManager::RotateView(-0.0001 *g_ActiveConfig.iAnaglyphFocalAngle,0.0f); + RightFrame = false; + } + else + { + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED); + VertexShaderManager::ResetView(); + VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); + VertexShaderManager::RotateView(0.0001 * g_ActiveConfig.iAnaglyphFocalAngle,0.0f); + RightFrame = true; + } + } // Set the backbuffer as the rendering target D3D::dev->SetDepthStencilSurface(NULL); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); @@ -1014,7 +1033,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons vp.MinZ = 0.0f; vp.MaxZ = 1.0f; D3D::dev->SetViewport(&vp); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + //D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); int X = dst_rect.left; int Y = dst_rect.top; @@ -1102,6 +1122,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); + if(g_ActiveConfig.bAnaglyphStereo) + { + DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); + } vp.X = 0; vp.Y = 0; vp.Width = s_backbuffer_width; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 3e8b2b0ed0..a5e33e0677 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -274,7 +274,7 @@ void Flush() VertexShaderManager::SetConstants(); PixelShaderManager::SetConstants(); - if (!PixelShaderCache::SetShader(false)) + if (!PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components)) { DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); goto shader_fail; @@ -294,7 +294,7 @@ void Flush() if (bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate) { DWORD write = 0; - if (!PixelShaderCache::SetShader(true)) + if (!PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components)) { DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); goto shader_fail; @@ -304,7 +304,6 @@ void Flush() D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); Draw(stride); - D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); } diff --git a/Source/Plugins/Plugin_VideoMerge/Src/DX11/DX11_PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoMerge/Src/DX11/DX11_PixelShaderCache.cpp index 9e89025ad2..a017600c1f 100644 --- a/Source/Plugins/Plugin_VideoMerge/Src/DX11/DX11_PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoMerge/Src/DX11/DX11_PixelShaderCache.cpp @@ -132,6 +132,16 @@ unsigned int ps_constant_offset_table[] = { 76, 80, // C_INDTEXSCALE, 8 84, 88, 92, 96, 100, 104, // C_INDTEXMTX, 24 108, 112, // C_FOG, 8 + 116, 120, 124 ,128, // C_COLORMATRIX, 16 + 132, 136, 140, 144, 148, // C_PLIGHTS0, 20 + 152, 156, 160, 164, 168, // C_PLIGHTS1, 20 + 172, 176, 180, 184, 188, // C_PLIGHTS2, 20 + 192, 196, 200, 204, 208, // C_PLIGHTS3, 20 + 212, 216, 220, 224, 228, // C_PLIGHTS4, 20 + 232, 236, 240, 244, 248, // C_PLIGHTS5, 20 + 252, 256, 260, 264, 268, // C_PLIGHTS6, 20 + 272, 276, 280, 284, 288, // C_PLIGHTS7, 20 + 292, 296, 300, 304, // C_PMATERIALS, 16 }; void PixelShaderCache::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp index 5a22922f33..166340168c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp @@ -74,6 +74,7 @@ BEGIN_EVENT_TABLE(GFXConfigDialogOGL,wxDialog) EVT_RADIOBUTTON(ID_RADIO_SAFETEXTURECACHE_FAST, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_DSTALPHAPASS,GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_CHECKBOX_DISABLECOPYEFB, GFXConfigDialogOGL::AdvancedSettingsChanged) + EVT_CHECKBOX(ID_PIXELLIGHTING, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_RADIOBUTTON(ID_RADIO_COPYEFBTORAM, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_RADIOBUTTON(ID_RADIO_COPYEFBTOGL, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_DLISTCACHING, GFXConfigDialogOGL::AdvancedSettingsChanged) @@ -240,7 +241,8 @@ void GFXConfigDialogOGL::InitializeGUIValues() m_HiresTextures->SetValue(g_Config.bHiresTextures); m_DumpEFBTarget->SetValue(g_Config.bDumpEFBTarget); m_DumpFrames->SetValue(g_Config.bDumpFrames); - m_FreeLook->SetValue(g_Config.bFreeLook); + m_FreeLook->SetValue(g_Config.bFreeLook); + m_PixelLighting->SetValue(g_Config.bEnablePixelLigting);; // Hacks controls m_PhackvalueCB->SetSelection(g_Config.iPhackvalue); @@ -308,6 +310,8 @@ void GFXConfigDialogOGL::InitializeGUITooltips() m_FreeLook->SetToolTip( wxT("Use WASD to move around, 0 and 9 to move faster or slower, and the") wxT(" left mouse button to pan the view.")); + m_PixelLighting->SetToolTip( + wxT("Enables Pixel ligting to improve Ilumination.")); // Hacks controls m_SafeTextureCache->SetToolTip(wxT("This is useful to prevent Metroid Prime from crashing, but can cause problems in other games.") @@ -450,6 +454,7 @@ void GFXConfigDialogOGL::CreateGUIControls() m_DisableTexturing = new wxCheckBox(m_PageAdvanced, ID_DISABLETEXTURING, wxT("Disable Texturing"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_DstAlphaPass = new wxCheckBox(m_PageAdvanced, ID_DSTALPHAPASS, wxT("Disable Destination Alpha Pass"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_DisableFog = new wxCheckBox(m_PageAdvanced, ID_DISABLEFOG, wxT("Disable Fog"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_PixelLighting = new wxCheckBox(m_PageAdvanced, ID_PIXELLIGHTING, wxT("Enable Pixel Lighting"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_StaticBox_EFB = new wxStaticBox(m_PageAdvanced, ID_STATICBOX_EFB, wxT("EFB Copy")); m_CheckBox_DisableCopyEFB = new wxCheckBox(m_PageAdvanced, ID_CHECKBOX_DISABLECOPYEFB, wxT("Disable")); @@ -462,7 +467,7 @@ void GFXConfigDialogOGL::CreateGUIControls() m_HiresTextures = new wxCheckBox(m_PageAdvanced, ID_HIRESTEXTURES, wxT("Load Hires textures"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_DumpEFBTarget = new wxCheckBox(m_PageAdvanced, ID_DUMPEFBTARGET, wxT("Dump EFB Target"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_DumpFrames = new wxCheckBox(m_PageAdvanced, ID_DUMPFRAMES, wxT("Dump Rendered Frames"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_FreeLook = new wxCheckBox(m_PageAdvanced, ID_FREELOOK, wxT("Free Look"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_FreeLook = new wxCheckBox(m_PageAdvanced, ID_FREELOOK, wxT("Free Look"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); // Hacks controls sHacks = new wxStaticBoxSizer(wxVERTICAL, m_PageAdvanced, wxT("Hacks")); @@ -503,6 +508,7 @@ void GFXConfigDialogOGL::CreateGUIControls() sRendering->Add(m_DstAlphaPass, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALL, 4); sRendering->Add(m_DisableFog, wxGBPosition(4, 0), wxGBSpan(1, 1), wxALL, 4); sRendering->Add(m_DlistCaching, wxGBPosition(5, 0), wxGBSpan(1, 1), wxALL, 4); + sRendering->Add(m_PixelLighting, wxGBPosition(6, 0), wxGBSpan(1, 1), wxALL, 4); sRenderBoxRow1->Add(sRendering, 0, wxALL|wxEXPAND, 1); wxStaticBoxSizer *sSBox = new wxStaticBoxSizer(m_StaticBox_EFB, wxVERTICAL); @@ -683,6 +689,9 @@ void GFXConfigDialogOGL::AdvancedSettingsChanged(wxCommandEvent& event) case ID_DISABLEFOG: g_Config.bDisableFog = m_DisableFog->IsChecked(); break; + case ID_PIXELLIGHTING: + g_Config.bEnablePixelLigting = m_PixelLighting->IsChecked(); + break; case ID_DSTALPHAPASS: g_Config.bDstAlphaPass = m_DstAlphaPass->IsChecked(); break; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h index 7592f2aeb9..f82373398f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h @@ -119,6 +119,7 @@ class GFXConfigDialogOGL : public wxDialog wxCheckBox *m_DumpEFBTarget; wxCheckBox *m_DumpFrames; wxCheckBox *m_FreeLook; + wxCheckBox *m_PixelLighting; wxStaticBox * m_StaticBox_EFB; wxCheckBox *m_CheckBox_DisableCopyEFB; wxRadioButton *m_Radio_CopyEFBToRAM, *m_Radio_CopyEFBToGL; @@ -174,6 +175,7 @@ class GFXConfigDialogOGL : public wxDialog ID_WIREFRAME, ID_DISABLELIGHTING, + ID_PIXELLIGHTING, ID_DISABLETEXTURING, ID_DISABLEFOG, ID_STATICBOX_EFB, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp index e992a61549..4e50ee4e28 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp @@ -155,8 +155,9 @@ void FreeLookInput( UINT iMsg, WPARAM wParam ) { static float debugSpeed = 1.0f; static bool mouseLookEnabled = false; + static bool mouseMoveEnabled = false; static float lastMouse[2]; - + POINT point; switch( iMsg ) { case WM_USER_KEYDOWN: @@ -189,24 +190,38 @@ void FreeLookInput( UINT iMsg, WPARAM wParam ) case WM_MOUSEMOVE: if (mouseLookEnabled) { - POINT point; GetCursorPos(&point); VertexShaderManager::RotateView((point.x - lastMouse[0]) / 200.0f, (point.y - lastMouse[1]) / 200.0f); lastMouse[0] = point.x; lastMouse[1] = point.y; } + + if (mouseMoveEnabled) { + GetCursorPos(&point); + VertexShaderManager::TranslateView((point.x - lastMouse[0]) / 50.0f, (point.y - lastMouse[1]) / 50.0f); + lastMouse[0] = point.x; + lastMouse[1] = point.y; + } break; case WM_RBUTTONDOWN: - POINT point; GetCursorPos(&point); lastMouse[0] = point.x; lastMouse[1] = point.y; mouseLookEnabled= true; break; + case WM_MBUTTONDOWN: + GetCursorPos(&point); + lastMouse[0] = point.x; + lastMouse[1] = point.y; + mouseMoveEnabled= true; + break; case WM_RBUTTONUP: mouseLookEnabled = false; break; + case WM_MBUTTONUP: + mouseMoveEnabled = false; + break; } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index ba97af6d66..0ffa54c838 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -185,7 +185,7 @@ GLuint PixelShaderCache::GetDepthMatrixProgram() } -FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable) +FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable,u32 components) { DVSTARTPROFILE(); PIXELSHADERUID uid; @@ -214,7 +214,7 @@ FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable) PSCacheEntry& newentry = pshaders[uid]; newentry.frameCount = frameCount; pShaderLast = &newentry.shader; - const char *code = GeneratePixelShaderCode(dstAlphaEnable,API_OPENGL); + const char *code = GeneratePixelShaderCode(dstAlphaEnable,API_OPENGL,components); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h index 09aff051a5..a99ff7b57a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h @@ -71,7 +71,7 @@ public: static void Init(); static void Shutdown(); - static FRAGMENTSHADER* GetShader(bool dstAlphaEnable); + static FRAGMENTSHADER* GetShader(bool dstAlphaEnable,u32 components); static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram); static GLuint GetColorMatrixProgram(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index baf8d57747..ae47b8b33f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -894,7 +894,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons DVSTARTPROFILE(); ResetAPIState(); - TargetRectangle back_rc; ComputeDrawRectangle(m_CustomWidth, m_CustomHeight, true, &back_rc); @@ -1083,7 +1082,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); TextureMngr::DisableStage(0); - + if(g_ActiveConfig.bAnaglyphStereo) + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Wireframe if (g_ActiveConfig.bWireFrame) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -1305,8 +1305,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons GL_REPORT_ERRORD(); // Clear framebuffer - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); + if(!g_ActiveConfig.bAnaglyphStereo) + { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + } GL_REPORT_ERRORD(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 1289b677a6..d3ca1ba131 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -289,7 +289,7 @@ void Flush() } } - FRAGMENTSHADER* ps = PixelShaderCache::GetShader(false); + FRAGMENTSHADER* ps = PixelShaderCache::GetShader(false,g_nativeVertexFmt->m_components); VERTEXSHADER* vs = VertexShaderCache::GetShader(g_nativeVertexFmt->m_components); // set global constants @@ -306,7 +306,7 @@ void Flush() // run through vertex groups again to set alpha if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate) { - ps = PixelShaderCache::GetShader(true); + ps = PixelShaderCache::GetShader(true,g_nativeVertexFmt->m_components); if (ps)PixelShaderCache::SetCurrentShader(ps->glprogid);