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_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

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);
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");
}
}

View File

@ -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];
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;