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:
parent
8bffec52dc
commit
14ab646978
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue