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
This commit is contained in:
donkopunchstania 2009-02-19 04:41:58 +00:00
parent 8bffec52dc
commit 14ab646978
7 changed files with 108 additions and 51 deletions

View File

@ -625,7 +625,19 @@ struct FogParams
u32 b_magnitude; u32 b_magnitude;
u32 b_shift; // b's exp + 1? u32 b_shift; // b's exp + 1?
FogParam3 c_proj_fsel; 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 union ZMode

View File

@ -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); ((u8*)&uid.values[1])[i/2] = (bpmem.tevksel[i].hex & 0xf) | ((bpmem.tevksel[i + 1].hex & 0xf) << 4);
uid.values[2] = s_texturemask; 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]; u32* pcurvalue = &uid.values[hdr];
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages+1; ++i) { for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages+1; ++i) {
TevStageCombiner::ColorCombiner &cc = bpmem.combiners[i].colorC; TevStageCombiner::ColorCombiner &cc = bpmem.combiners[i].colorC;
@ -114,7 +118,7 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 zbufrender, u3
} }
// yeah, well .... // 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 // 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 WrapNonPow2Tex(char* &p, const char* var, int texmap, u32 texture_mask);
static void WriteAlphaCompare(char *&p, int num, int comp); static void WriteAlphaCompare(char *&p, int num, int comp);
static bool WriteAlphaTest(char *&p); static bool WriteAlphaTest(char *&p);
static void WriteFog(char *&p);
const float epsilon8bit = 1.0f / 255.0f; 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 bRenderZ = has_zbuffer_target && bpmem.zmode.updateenable;
bool bOutputZ = bpmem.ztex2.op != ZTEXTURE_DISABLE; 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 // bool bRenderZToCol0 = ; // output z and alpha to color0
assert( !bRenderZToCol0 || bRenderZ ); 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_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_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_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"); 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 // wpos is in w of first 4 texcoords
for (int i = 0; i < numTexgen; ++i) 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 float%d uv%d : TEXCOORD%d, \n", i<4?4:3, i, i);
} }
WRITE(p, " in float4 colors[2] : COLOR0){\n"); 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"); WRITE(p, " ocol0 = float4(prev.rgb,"I_ALPHA"[0].w);\n");
else 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"); WRITE(p, ");\n");
return true; 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");
}
}

View File

@ -27,6 +27,7 @@
#define I_ZBIAS "czbias" #define I_ZBIAS "czbias"
#define I_INDTEXSCALE "cindscale" #define I_INDTEXSCALE "cindscale"
#define I_INDTEXMTX "cindmtx" #define I_INDTEXMTX "cindmtx"
#define I_FOG "cfog"
#define C_COLORS 0 #define C_COLORS 0
#define C_KCOLORS (C_COLORS+4) #define C_KCOLORS (C_COLORS+4)
@ -35,26 +36,27 @@
#define C_ZBIAS (C_TEXDIMS+8) #define C_ZBIAS (C_TEXDIMS+8)
#define C_INDTEXSCALE (C_ZBIAS+2) #define C_INDTEXSCALE (C_ZBIAS+2)
#define C_INDTEXMTX (C_INDTEXSCALE+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 class PIXELSHADERUID
{ {
public: public:
u32 values[4+32+6+11]; u32 values[5+32+6+11];
u16 tevstages, indstages; u16 tevstages, indstages;
PIXELSHADERUID() { PIXELSHADERUID() {
memset(values, 0, (4+32+6+11) * 4); memset(values, 0, (5+32+6+11) * 4);
tevstages = indstages = 0; tevstages = indstages = 0;
} }
PIXELSHADERUID(const PIXELSHADERUID& r) PIXELSHADERUID(const PIXELSHADERUID& r)
{ {
tevstages = r.tevstages; tevstages = r.tevstages;
indstages = r.indstages; indstages = r.indstages;
int N = tevstages + indstages + 3; int N = tevstages + indstages + 4;
_assert_(N <= 4+32+6+11); _assert_(N <= 5+32+6+11);
for (int i = 0; i < N; ++i) for (int i = 0; i < N; ++i)
values[i] = r.values[i]; values[i] = r.values[i];
} }

View File

@ -32,6 +32,8 @@ static bool s_bZBiasChanged;
static bool s_bIndTexScaleChanged; static bool s_bIndTexScaleChanged;
static bool s_bZTextureTypeChanged; static bool s_bZTextureTypeChanged;
static bool s_bDepthRangeChanged; 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 lastDepthRange[2] = {0}; // 0 = far z, 1 = far - near
static float lastRGBAfull[2][4][4]; static float lastRGBAfull[2][4][4];
static u8 s_nTexDimsChanged; static u8 s_nTexDimsChanged;
@ -53,6 +55,7 @@ void PixelShaderManager::Init()
s_nTexDimsChanged = 0; s_nTexDimsChanged = 0;
s_nIndTexMtxChanged = 15; s_nIndTexMtxChanged = 15;
s_bAlphaChanged = s_bZBiasChanged = s_bIndTexScaleChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true; s_bAlphaChanged = s_bZBiasChanged = s_bIndTexScaleChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
s_bFogColorChanged = s_bFogParamChanged = true;
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
maptocoord[i] = -1; maptocoord[i] = -1;
maptocoord_mask = 0; maptocoord_mask = 0;
@ -140,7 +143,7 @@ void PixelShaderManager::SetConstants()
if (s_bZBiasChanged || s_bDepthRangeChanged) { if (s_bZBiasChanged || s_bDepthRangeChanged) {
//ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias); //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; s_bZBiasChanged = s_bDepthRangeChanged = false;
} }
@ -198,6 +201,18 @@ void PixelShaderManager::SetConstants()
} }
s_nIndTexMtxChanged = 0; 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) void PixelShaderManager::SetPSTextureDims(int texid)
@ -366,6 +381,16 @@ void PixelShaderManager::SetTexDimsChanged(int texmapid)
SetIndTexScaleChanged(); SetIndTexScaleChanged();
} }
void PixelShaderManager::SetFogColorChanged()
{
s_bFogColorChanged = true;
}
void PixelShaderManager::SetFogParamChanged()
{
s_bFogParamChanged = true;
}
void PixelShaderManager::SetColorMatrix(const float* pmatrix, const float* pfConstAdd) void PixelShaderManager::SetColorMatrix(const float* pmatrix, const float* pfConstAdd)
{ {
SetPSConstant4fv(C_COLORMATRIX, pmatrix); SetPSConstant4fv(C_COLORMATRIX, pmatrix);

View File

@ -53,6 +53,8 @@ public:
static void SetZTextureTypeChanged(); static void SetZTextureTypeChanged();
static void SetTexturesUsed(u32 nonpow2tex); static void SetTexturesUsed(u32 nonpow2tex);
static void SetTexDimsChanged(int texmapid); static void SetTexDimsChanged(int texmapid);
static void SetFogColorChanged();
static void SetFogParamChanged();
static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd); static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);

View File

@ -400,9 +400,9 @@ void BPWritten(int addr, int changes, int newval)
break; break;
// dev->SetRenderState(D3DRS_FOGCOLOR,bpmem.fog.color); // 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) //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; break;

View File

@ -251,43 +251,11 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_FOGPARAM0: case BPMEM_FOGPARAM0:
case BPMEM_FOGBEXPONENT: case BPMEM_FOGBEXPONENT:
case BPMEM_FOGBMAGNITUDE: case BPMEM_FOGBMAGNITUDE:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case BPMEM_FOGPARAM3: case BPMEM_FOGPARAM3:
//fog settings
if (changes) { if (changes) {
VertexManager::Flush(); VertexManager::Flush();
((u32*)&bpmem)[addr] = newval; ((u32*)&bpmem)[addr] = newval;
//printf("%f %f magnitude: %x\n", bpmem.fog.a.GetA(),bpmem.fog.c_proj_fsel.GetC(), bpmem.fog.b_magnitude); PixelShaderManager::SetFogParamChanged();
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;
}
} }
break; break;
@ -296,9 +264,7 @@ void BPWritten(int addr, int changes, int newval)
{ {
VertexManager::Flush(); VertexManager::Flush();
((u32*)&bpmem)[addr] = newval; ((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 }; PixelShaderManager::SetFogColorChanged();
//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);
} }
break; break;