rasterize: add fog emulation
This commit is contained in:
parent
9828895c53
commit
db610129bb
|
@ -24,6 +24,7 @@ Graphics:
|
|||
bug: fix disp fifo capture
|
||||
bug: fix simultaneous vram display and capture via same bank
|
||||
bug: swrast: add clear image and scroll emulation
|
||||
bug: swrast: add fog emulation
|
||||
bug: swrast: fixes to shadow rendering
|
||||
|
||||
Windows:
|
||||
|
|
|
@ -1973,20 +1973,16 @@ void VIEWPORT::decode(u32 v)
|
|||
void gfx3d_glClearColor(u32 v)
|
||||
{
|
||||
gfx3d.clearColor = v;
|
||||
|
||||
}
|
||||
|
||||
void gfx3d_glFogColor(u32 v)
|
||||
{
|
||||
gfx3d.fogColor[0] = ((float)((v )&0x1F))/31.0f;
|
||||
gfx3d.fogColor[1] = ((float)((v>> 5)&0x1F))/31.0f;
|
||||
gfx3d.fogColor[2] = ((float)((v>>10)&0x1F))/31.0f;
|
||||
gfx3d.fogColor[3] = ((float)((v>>16)&0x1F))/31.0f;
|
||||
gfx3d.fogColor = v;
|
||||
}
|
||||
|
||||
void gfx3d_glFogOffset (u32 v)
|
||||
{
|
||||
gfx3d.fogOffset = (float)(v&0xffff);
|
||||
gfx3d.fogOffset = (v&0x7fff);
|
||||
}
|
||||
|
||||
void gfx3d_glClearDepth(u32 v)
|
||||
|
@ -2307,7 +2303,10 @@ static void gfx3d_doFlush()
|
|||
gfx3d.enableAlphaBlending = BIT3(control);
|
||||
gfx3d.enableAntialiasing = BIT4(control);
|
||||
gfx3d.enableEdgeMarking = BIT5(control);
|
||||
gfx3d.enableFogAlphaOnly = BIT6(control);
|
||||
gfx3d.enableFog = BIT7(control);
|
||||
gfx3d.enableClearImage = BIT14(control);
|
||||
gfx3d.fogShift = (control>>8)&0xF;
|
||||
|
||||
int polycount = polylist->count;
|
||||
|
||||
|
@ -3123,6 +3122,10 @@ SFORMAT SF_GFX3D[]={
|
|||
{ "GSEB", 4, 1, &gfx3d.enableAlphaBlending},
|
||||
{ "GSEX", 4, 1, &gfx3d.enableAntialiasing},
|
||||
{ "GSEE", 4, 1, &gfx3d.enableEdgeMarking},
|
||||
{ "GSEC", 4, 1, &gfx3d.enableClearImage},
|
||||
{ "GSEF", 4, 1, &gfx3d.enableFog},
|
||||
{ "GSEO", 4, 1, &gfx3d.enableFogAlphaOnly},
|
||||
{ "GFSH", 4, 1, &gfx3d.fogShift},
|
||||
{ "GSSH", 4, 1, &gfx3d.shading},
|
||||
{ "GSWB", 4, 1, &gfx3d.wbuffer},
|
||||
{ "GSSM", 4, 1, &gfx3d.sortmode},
|
||||
|
@ -3130,7 +3133,7 @@ SFORMAT SF_GFX3D[]={
|
|||
{ "GSVP", 4, 1, &viewport},
|
||||
{ "GSCC", 4, 1, &gfx3d.clearColor},
|
||||
{ "GSCD", 4, 1, &gfx3d.clearDepth},
|
||||
{ "GSFC", 4, 4, gfx3d.fogColor},
|
||||
{ "GSFC", 4, 4, &gfx3d.fogColor},
|
||||
{ "GSFO", 4, 1, &gfx3d.fogOffset},
|
||||
{ "GST2", 2, 32, gfx3d.u16ToonTable},
|
||||
{ "GSST", 4, 128, shininessTable},
|
||||
|
|
|
@ -185,6 +185,9 @@ struct GFX3D
|
|||
, enableAntialiasing(false)
|
||||
, enableEdgeMarking(false)
|
||||
, enableClearImage(false)
|
||||
, enableFog(false)
|
||||
, enableFogAlphaOnly(false)
|
||||
, fogShift(0)
|
||||
, shading(TOON)
|
||||
, polylist(0)
|
||||
, vertlist(0)
|
||||
|
@ -193,12 +196,14 @@ struct GFX3D
|
|||
, clearColor(0)
|
||||
, frameCtr(0)
|
||||
, frameCtrRaw(0)
|
||||
, fogOffset(0)
|
||||
, fogColor(0)
|
||||
{
|
||||
fogColor[0] = fogColor[1] = fogColor[2] = fogColor[3] = 0;
|
||||
fogOffset = 0;
|
||||
}
|
||||
BOOL enableTexturing, enableAlphaTest, enableAlphaBlending,
|
||||
enableAntialiasing, enableEdgeMarking, enableClearImage;
|
||||
enableAntialiasing, enableEdgeMarking, enableClearImage, enableFog, enableFogAlphaOnly;
|
||||
|
||||
u32 fogShift;
|
||||
|
||||
static const u32 TOON = 0;
|
||||
static const u32 HIGHLIGHT = 1;
|
||||
|
@ -214,8 +219,13 @@ struct GFX3D
|
|||
|
||||
u32 clearDepth;
|
||||
u32 clearColor;
|
||||
float fogColor[4];
|
||||
float fogOffset;
|
||||
#include "PACKED.h"
|
||||
struct {
|
||||
u32 fogColor;
|
||||
u32 pad[3]; //for savestate compatibility as of 26-jul-09
|
||||
};
|
||||
#include "PACKED_END.h"
|
||||
u32 fogOffset;
|
||||
|
||||
//ticks every time flush() is called
|
||||
int frameCtr;
|
||||
|
|
|
@ -194,6 +194,7 @@ struct PolyAttr
|
|||
u8 alpha;
|
||||
bool backfacing;
|
||||
bool translucent;
|
||||
u8 fogged;
|
||||
|
||||
bool isVisible(bool backfacing)
|
||||
{
|
||||
|
@ -214,6 +215,7 @@ struct PolyAttr
|
|||
polyid = (polyAttr>>24)&0x3F;
|
||||
alpha = (polyAttr>>16)&0x1F;
|
||||
drawBackPlaneIntersectingPolys = BIT12(val);
|
||||
fogged = BIT15(val);
|
||||
}
|
||||
|
||||
} polyAttr;
|
||||
|
@ -239,7 +241,10 @@ struct Fragment
|
|||
|
||||
u8 stencil;
|
||||
|
||||
u8 isTranslucentPoly;
|
||||
struct {
|
||||
u8 isTranslucentPoly:1;
|
||||
u8 fogged:1;
|
||||
};
|
||||
};
|
||||
|
||||
static VERT* verts[MAX_CLIPPED_VERTS];
|
||||
|
@ -252,7 +257,7 @@ INLINE static void SubmitVertex(int vert_index, VERT& rawvert)
|
|||
static Fragment screen[256*192];
|
||||
static FragmentColor screenColor[256*192];
|
||||
static FragmentColor toonTable[32];
|
||||
|
||||
static u8 fogTable[32768];
|
||||
|
||||
FORCEINLINE int iround(float f) {
|
||||
return (int)f; //lol
|
||||
|
@ -559,6 +564,7 @@ static FORCEINLINE void pixel(int adr,float r, float g, float b, float invu, flo
|
|||
{
|
||||
destFragment.polyid.opaque = polyAttr.polyid;
|
||||
destFragment.isTranslucentPoly = polyAttr.translucent?1:0;
|
||||
destFragment.fogged = polyAttr.fogged;
|
||||
destFragmentColor = shaderOutput;
|
||||
}
|
||||
else
|
||||
|
@ -584,6 +590,8 @@ static FORCEINLINE void pixel(int adr,float r, float g, float b, float invu, flo
|
|||
|
||||
//alpha blending and write color
|
||||
alphaBlend(destFragmentColor, shaderOutput);
|
||||
|
||||
destFragment.fogged &= polyAttr.fogged;
|
||||
}
|
||||
|
||||
//depth writing
|
||||
|
@ -1010,6 +1018,30 @@ static void SoftRastFramebufferProcess()
|
|||
|
||||
//}
|
||||
|
||||
if(gfx3d.enableFog)
|
||||
{
|
||||
u32 r = gfx3d.fogColor&0x1F;
|
||||
u32 g = (gfx3d.fogColor>>5)&0x1F;
|
||||
u32 b = (gfx3d.fogColor>>10)&0x1F;
|
||||
u32 a = (gfx3d.fogColor>>16)&0x1F;
|
||||
for(int i=0;i<256*192;i++)
|
||||
{
|
||||
Fragment &destFragment = screen[i];
|
||||
if(!destFragment.fogged) continue;
|
||||
FragmentColor &destFragmentColor = screenColor[i];
|
||||
u32 fogIndex = destFragment.depth>>9;
|
||||
assert(fogIndex<32768);
|
||||
u8 fog = fogTable[fogIndex];
|
||||
if(fog==127) fog=128;
|
||||
if(!gfx3d.enableFogAlphaOnly)
|
||||
{
|
||||
destFragmentColor.r = ((128-fog)*destFragmentColor.r + r*fog)>>7;
|
||||
destFragmentColor.g = ((128-fog)*destFragmentColor.g + g*fog)>>7;
|
||||
destFragmentColor.b = ((128-fog)*destFragmentColor.b + b*fog)>>7;
|
||||
}
|
||||
destFragmentColor.a = ((128-fog)*destFragmentColor.a + a*fog)>>7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SoftRastConvertFramebuffer()
|
||||
|
@ -1218,6 +1250,8 @@ static void SoftRastRender()
|
|||
clearFragment.polyid.translucent = kUnsetTranslucentPolyID;
|
||||
clearFragment.depth = gfx3d.clearDepth;
|
||||
clearFragment.stencil = 0;
|
||||
clearFragment.isTranslucentPoly = 0;
|
||||
clearFragment.fogged = BIT15(gfx3d.clearColor);
|
||||
for(int i=0;i<256*192;i++)
|
||||
screen[i] = clearFragment;
|
||||
|
||||
|
@ -1254,6 +1288,7 @@ static void SoftRastRender()
|
|||
depth &= 0x7FFF;
|
||||
//TODO - might consider a lookup table for this
|
||||
dst->depth = gfx3d_extendDepth_15_to_24(depth);
|
||||
dst->fogged = BIT15(depth);
|
||||
|
||||
dstColor++;
|
||||
dst++;
|
||||
|
@ -1272,6 +1307,36 @@ static void SoftRastRender()
|
|||
toonTable[i].b = (gfx3d.u16ToonTable[i]>>10)&0x1F;
|
||||
}
|
||||
|
||||
//setup fog variables (but only if fog is enabled)
|
||||
if(gfx3d.enableFog)
|
||||
{
|
||||
u8* fogDensity = MMU.MMU_MEM[ARMCPU_ARM9][0x40] + 0x360;
|
||||
//TODO - this might be a little slow;
|
||||
//we might need to hash all the variables and only recompute this when something changes
|
||||
const int increment = (0x400 >> gfx3d.fogShift);
|
||||
for(u32 i=0;i<32768;i++) {
|
||||
if(i<gfx3d.fogOffset) {
|
||||
fogTable[i] = fogDensity[0];
|
||||
continue;
|
||||
}
|
||||
for(int j=0;j<31;j++) {
|
||||
u32 value = gfx3d.fogOffset + increment*(j+1);
|
||||
if(i<=value) {
|
||||
if(j==0) {
|
||||
fogTable[i] = fogDensity[0];
|
||||
goto done;
|
||||
} else {
|
||||
int lastValue = value - increment;
|
||||
fogTable[i] = ((value-i)*fogDensity[j-1] + (increment-(value-i))*fogDensity[j])/increment;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
fogTable[i] = fogDensity[31];
|
||||
done: ;
|
||||
}
|
||||
}
|
||||
|
||||
//convert colors to float to get more precision in case we need it
|
||||
for(int i=0;i<gfx3d.vertlist->count;i++)
|
||||
gfx3d.vertlist->list[i].color_to_float();
|
||||
|
|
Loading…
Reference in New Issue