From 14ab646978406e2aeee9185f7686d5f93723de71 Mon Sep 17 00:00:00 2001 From: donkopunchstania Date: Thu, 19 Feb 2009 04:41:58 +0000 Subject: [PATCH] fog is done in pixel shader but needs to factor x adjustment git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2309 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/VideoCommon/Src/BPMemory.h | 14 ++++- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 60 +++++++++++++++++-- Source/Core/VideoCommon/Src/PixelShaderGen.h | 14 +++-- .../VideoCommon/Src/PixelShaderManager.cpp | 27 ++++++++- .../Core/VideoCommon/Src/PixelShaderManager.h | 2 + .../Plugins/Plugin_VideoDX9/Src/BPStructs.cpp | 4 +- .../Plugins/Plugin_VideoOGL/Src/BPStructs.cpp | 38 +----------- 7 files changed, 108 insertions(+), 51 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index d25c1060a4..edba754015 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -625,7 +625,19 @@ struct FogParams u32 b_magnitude; u32 b_shift; // b's exp + 1? FogParam3 c_proj_fsel; - u32 color; //0:b 8:g 16:r - nice! + + union FogColor + { + struct + { + unsigned b : 8; + unsigned g : 8; + unsigned r : 8; + }; + u32 hex; + }; + + FogColor color; //0:b 8:g 16:r - nice! }; union ZMode diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index b7b51b5e4c..317131395d 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -52,7 +52,11 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 zbufrender, u3 ((u8*)&uid.values[1])[i/2] = (bpmem.tevksel[i].hex & 0xf) | ((bpmem.tevksel[i + 1].hex & 0xf) << 4); uid.values[2] = s_texturemask; - int hdr = 3; + + uid.values[3] = (u32)bpmem.fog.c_proj_fsel.fsel | + ((u32)bpmem.fog.c_proj_fsel.proj << 3); + + int hdr = 4; u32* pcurvalue = &uid.values[hdr]; for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages+1; ++i) { TevStageCombiner::ColorCombiner &cc = bpmem.combiners[i].colorC; @@ -114,7 +118,7 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 zbufrender, u3 } // yeah, well .... - uid.indstages = (u32)(pcurvalue - &uid.values[0] - 2 - uid.tevstages); + uid.indstages = (u32)(pcurvalue - &uid.values[0] - (hdr - 1) - uid.tevstages); } // old tev->pixelshader notes @@ -130,6 +134,7 @@ static void WriteStage(char *&p, int n, u32 texture_mask); static void WrapNonPow2Tex(char* &p, const char* var, int texmap, u32 texture_mask); static void WriteAlphaCompare(char *&p, int num, int comp); static bool WriteAlphaTest(char *&p); +static void WriteFog(char *&p); const float epsilon8bit = 1.0f / 255.0f; @@ -380,7 +385,7 @@ const char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool bool bRenderZ = has_zbuffer_target && bpmem.zmode.updateenable; bool bOutputZ = bpmem.ztex2.op != ZTEXTURE_DISABLE; - bool bInputZ = bpmem.ztex2.op==ZTEXTURE_ADD || bRenderZ; + bool bInputZ = bpmem.ztex2.op==ZTEXTURE_ADD || bRenderZ || bpmem.fog.c_proj_fsel.fsel != 0; // bool bRenderZToCol0 = ; // output z and alpha to color0 assert( !bRenderZToCol0 || bRenderZ ); @@ -428,6 +433,7 @@ const char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool WRITE(p, "uniform float4 "I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS); 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); WRITE(p, "void main(\n"); @@ -447,7 +453,7 @@ const char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool // wpos is in w of first 4 texcoords for (int i = 0; i < numTexgen; ++i) WRITE(p, " in float%d uv%d : TEXCOORD%d, \n", i<4?4:3, i, i); - } + } WRITE(p, " in float4 colors[2] : COLOR0){\n"); @@ -527,7 +533,8 @@ const char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool WRITE(p, " ocol0 = float4(prev.rgb,"I_ALPHA"[0].w);\n"); else */ - WRITE(p, " ocol0 = prev;\n"); + WriteFog(p); + WRITE(p, " ocol0 = prev;\n"); } } @@ -935,3 +942,46 @@ static bool WriteAlphaTest(char *&p) WRITE(p, ");\n"); return true; } + +static void WriteFog(char *&p) +{ + bool enabled = bpmem.fog.c_proj_fsel.fsel; + + if (enabled) { + if (bpmem.fog.c_proj_fsel.proj == 0) { + // perspective + // ze = A/(B - Zs) + WRITE (p, " float ze = "I_FOG"[1].x / ("I_FOG"[1].y - zCoord);\n"); + } else { + // orthographic + // ze = a*Zs + WRITE (p, " float ze = "I_FOG"[1].x * zCoord;\n"); + } + + WRITE (p, " float fog = clamp(ze - "I_FOG"[1].z, 0.0f, 1.0f);\n"); + } + + switch (bpmem.fog.c_proj_fsel.fsel) { + case 2: // linear + // empty + break; + case 4: // exp + WRITE(p, " fog = 1.0f - pow(2, -8.0f * fog);\n"); + break; + case 5: // exp2 + WRITE(p, " fog = 1.0f - pow(2, -8.0f * fog * fog);\n"); + break; + case 6: // backward exp + WRITE(p, " fog = 1.0f - fog;\n"); + WRITE(p, " fog = pow(2, -8.0f * fog);\n"); + break; + case 7: // backward exp2 + WRITE(p, " fog = 1.0f - fog;\n"); + WRITE(p, " fog = pow(2, -8.0f * fog * fog);\n"); + break; + } + + if (enabled) { + WRITE(p, " prev.rgb = (1.0f - fog) * prev.rgb + (fog * "I_FOG"[0].rgb);\n"); + } +} diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index df54a7b0a4..d69fd805c6 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -27,6 +27,7 @@ #define I_ZBIAS "czbias" #define I_INDTEXSCALE "cindscale" #define I_INDTEXMTX "cindmtx" +#define I_FOG "cfog" #define C_COLORS 0 #define C_KCOLORS (C_COLORS+4) @@ -35,26 +36,27 @@ #define C_ZBIAS (C_TEXDIMS+8) #define C_INDTEXSCALE (C_ZBIAS+2) #define C_INDTEXMTX (C_INDTEXSCALE+2) -#define C_ENVCONST_END (C_INDTEXMTX+6) +#define C_FOG (C_INDTEXMTX+6) +#define C_ENVCONST_END (C_FOG+2) -#define C_COLORMATRIX (C_INDTEXMTX+6) +#define C_COLORMATRIX (C_FOG+2) class PIXELSHADERUID { public: - u32 values[4+32+6+11]; + u32 values[5+32+6+11]; u16 tevstages, indstages; PIXELSHADERUID() { - memset(values, 0, (4+32+6+11) * 4); + memset(values, 0, (5+32+6+11) * 4); tevstages = indstages = 0; } PIXELSHADERUID(const PIXELSHADERUID& r) { tevstages = r.tevstages; indstages = r.indstages; - int N = tevstages + indstages + 3; - _assert_(N <= 4+32+6+11); + int N = tevstages + indstages + 4; + _assert_(N <= 5+32+6+11); for (int i = 0; i < N; ++i) values[i] = r.values[i]; } diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index 18c85a9dcf..4774a02b2b 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -32,6 +32,8 @@ static bool s_bZBiasChanged; static bool s_bIndTexScaleChanged; static bool s_bZTextureTypeChanged; static bool s_bDepthRangeChanged; +static bool s_bFogColorChanged; +static bool s_bFogParamChanged; static float lastDepthRange[2] = {0}; // 0 = far z, 1 = far - near static float lastRGBAfull[2][4][4]; static u8 s_nTexDimsChanged; @@ -53,6 +55,7 @@ void PixelShaderManager::Init() s_nTexDimsChanged = 0; s_nIndTexMtxChanged = 15; s_bAlphaChanged = s_bZBiasChanged = s_bIndTexScaleChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true; + s_bFogColorChanged = s_bFogParamChanged = true; for (int i = 0; i < 8; ++i) maptocoord[i] = -1; maptocoord_mask = 0; @@ -140,7 +143,7 @@ void PixelShaderManager::SetConstants() if (s_bZBiasChanged || s_bDepthRangeChanged) { //ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias); - SetPSConstant4f(C_ZBIAS+1, lastDepthRange[0] / 16777215.0f, lastDepthRange[1] / 16777215.0f, 0, (float)( (((int)lastZBias<<8)>>8))/16777216.0f); + SetPSConstant4f(C_ZBIAS+1, lastDepthRange[0] / 16777216.0f, lastDepthRange[1] / 16777216.0f, 0, (float)( (((int)lastZBias<<8)>>8))/16777216.0f); s_bZBiasChanged = s_bDepthRangeChanged = false; } @@ -198,6 +201,18 @@ void PixelShaderManager::SetConstants() } s_nIndTexMtxChanged = 0; } + + if (s_bFogColorChanged) { + SetPSConstant4f(C_FOG, bpmem.fog.color.r / 255.0f, bpmem.fog.color.g / 255.0f, bpmem.fog.color.b / 255.0f, 0); + s_bFogColorChanged = false; + } + + if (s_bFogParamChanged) { + float a = bpmem.fog.a.GetA() * ((float)(1 << bpmem.fog.b_shift)); + float b = ((float)bpmem.fog.b_magnitude / 8388638) * ((float)(1 << (bpmem.fog.b_shift - 1))); + SetPSConstant4f(C_FOG + 1, a, b, bpmem.fog.c_proj_fsel.GetC(), 0); + s_bFogParamChanged = false; + } } void PixelShaderManager::SetPSTextureDims(int texid) @@ -366,6 +381,16 @@ void PixelShaderManager::SetTexDimsChanged(int texmapid) SetIndTexScaleChanged(); } +void PixelShaderManager::SetFogColorChanged() +{ + s_bFogColorChanged = true; +} + +void PixelShaderManager::SetFogParamChanged() +{ + s_bFogParamChanged = true; +} + void PixelShaderManager::SetColorMatrix(const float* pmatrix, const float* pfConstAdd) { SetPSConstant4fv(C_COLORMATRIX, pmatrix); diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h index afe694cd4e..2229f30082 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.h +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h @@ -53,6 +53,8 @@ public: static void SetZTextureTypeChanged(); static void SetTexturesUsed(u32 nonpow2tex); static void SetTexDimsChanged(int texmapid); + static void SetFogColorChanged(); + static void SetFogParamChanged(); static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp index 07117fc44f..5b6932aeed 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/BPStructs.cpp @@ -400,9 +400,9 @@ void BPWritten(int addr, int changes, int newval) break; // dev->SetRenderState(D3DRS_FOGCOLOR,bpmem.fog.color); - int fogcolor[3] = { ((bpmem.fog.color>>16)&0xff), ((bpmem.fog.color>>8)&0xff), (bpmem.fog.color&0xff)}; + int fogcolor[3] = { bpmem.fog.color.r, bpmem.fog.color.g, bpmem.fog.color.b }; //D3DCOLOR_RGBA(fogcolor[0], fogcolor[1], fogcolor[2], 0) - Renderer::SetRenderState(D3DRS_FOGCOLOR, bpmem.fog.color); + Renderer::SetRenderState(D3DRS_FOGCOLOR, bpmem.fog.color.hex); } break; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp index 1843a4fdbe..dbb4587ac4 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp @@ -251,43 +251,11 @@ void BPWritten(int addr, int changes, int newval) case BPMEM_FOGPARAM0: case BPMEM_FOGBEXPONENT: case BPMEM_FOGBMAGNITUDE: - if (changes) { - VertexManager::Flush(); - ((u32*)&bpmem)[addr] = newval; - } - break; - case BPMEM_FOGPARAM3: - //fog settings if (changes) { VertexManager::Flush(); ((u32*)&bpmem)[addr] = newval; - //printf("%f %f magnitude: %x\n", bpmem.fog.a.GetA(),bpmem.fog.c_proj_fsel.GetC(), bpmem.fog.b_magnitude); - switch(bpmem.fog.c_proj_fsel.fsel) - { - case 0: // Off - glDisable(GL_FOG); // Should be what we do - break; - case 2: // Linear - glFogi(GL_FOG_MODE, GL_LINEAR); - glEnable(GL_FOG); - break; - case 4: // exp - glFogi(GL_FOG_MODE, GL_EXP); - glEnable(GL_FOG); - break; - case 5: // exp2 - glFogi(GL_FOG_MODE, GL_EXP2); - glEnable(GL_FOG); - break; - case 6: // Backward exp - case 7: // Backward exp2 - // TODO: Figure out how to do these in GL - //TEV_FSEL_BX, TEV_FSEL_BX2? - default: - DEBUG_LOG("Non-Emulated Fog selection %d\n", bpmem.fog.c_proj_fsel.fsel); - break; - } + PixelShaderManager::SetFogParamChanged(); } break; @@ -296,9 +264,7 @@ void BPWritten(int addr, int changes, int newval) { VertexManager::Flush(); ((u32*)&bpmem)[addr] = newval; - float fogcolor[4] = { ((bpmem.fog.color>>16)&0xff)/255.0f, ((bpmem.fog.color>>8)&0xff)/255.0f, (bpmem.fog.color&0xff)/255.0f, (bpmem.fog.color>>24)/255.0f }; - //printf("r: %f g: %f b: %f a: %f %x %x %x %f\n",fogcolor[0],fogcolor[1], fogcolor[2], fogcolor[3], bpmem.fogRangeAdj, bpmem.unknown15[0],bpmem.unknown15[1],bpmem.unknown15[2]); - glFogfv(GL_FOG_COLOR, fogcolor); + PixelShaderManager::SetFogColorChanged(); } break;