rasterize: experimental edge marking; also mess around with alpha blending a bit
This commit is contained in:
parent
8495cce7d8
commit
a0c9689b6f
|
@ -191,6 +191,7 @@ struct PolyAttr
|
|||
u8 polyid;
|
||||
u8 alpha;
|
||||
bool backfacing;
|
||||
bool translucent;
|
||||
|
||||
bool isVisible(bool backfacing)
|
||||
{
|
||||
|
@ -236,7 +237,7 @@ struct Fragment
|
|||
|
||||
u8 stencil;
|
||||
|
||||
u8 pad;
|
||||
u8 isTranslucentPoly;
|
||||
};
|
||||
|
||||
static VERT* verts[MAX_CLIPPED_VERTS];
|
||||
|
@ -440,26 +441,22 @@ struct Shader
|
|||
|
||||
static FORCEINLINE void alphaBlend(FragmentColor & dst, const FragmentColor & src)
|
||||
{
|
||||
u8 dstAlpha = dst.a;
|
||||
if(gfx3d.enableAlphaBlending)
|
||||
{
|
||||
if(src.a == 0)
|
||||
{
|
||||
dst.a = max(src.a,dst.a);
|
||||
}
|
||||
else if(src.a == 31 || dst.a == 0)
|
||||
{
|
||||
dst = src;
|
||||
dst.a = max(src.a,dst.a);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 alpha = src.a+1;
|
||||
u8 invAlpha = 32 - alpha;
|
||||
dst.r = (alpha*src.r + invAlpha*dst.r)>>5;
|
||||
dst.g = (alpha*src.g + invAlpha*dst.g)>>5;
|
||||
dst.b = (alpha*src.b + invAlpha*dst.b)>>5;
|
||||
dst.a = max(src.a,dst.a);
|
||||
//TODO - check decal table for src.a = 0 case, maybe it is wrong for the shader also
|
||||
dst.r = decal_table[src.a][src.r][dst.r];
|
||||
dst.g = decal_table[src.a][src.g][dst.g];
|
||||
dst.b = decal_table[src.a][src.b][dst.b];
|
||||
}
|
||||
|
||||
dst.a = max(src.a,dst.a);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -576,6 +573,7 @@ static FORCEINLINE void pixel(int adr,float r, float g, float b, float invu, flo
|
|||
if(isOpaquePixel)
|
||||
{
|
||||
destFragment.polyid.opaque = polyAttr.polyid;
|
||||
destFragment.isTranslucentPoly = polyAttr.translucent?1:0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -979,6 +977,55 @@ static void SoftRastVramReconfigureSignal() {
|
|||
TexCache_Invalidate();
|
||||
}
|
||||
|
||||
static void SoftRastFramebufferProcess()
|
||||
{
|
||||
//this is not very accurate, but it works roughly
|
||||
if(gfx3d.enableEdgeMarking)
|
||||
{
|
||||
u8 clearPolyid = ((gfx3d.clearColor>>24)&0x3F)>>3;
|
||||
|
||||
//TODO - need to test and find out whether these get grabbed at flush time, or at render time
|
||||
//we can do this by rendering a 3d frame and then freezing the system, but only changing the edge mark colors
|
||||
|
||||
//now, I am not entirely sure about this. I can't find any documentation about the high bit here but
|
||||
//it doesnt seem plausible to me that its all or nothing. I think that only polyid groups with a color
|
||||
//with the high bit set get edge marked.
|
||||
u16 edgeMarkColors[8];
|
||||
bool edgeMarkEnables[8];
|
||||
for(int i=0;i<8;i++)
|
||||
{
|
||||
edgeMarkColors[i] = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x330+i*2);
|
||||
edgeMarkEnables[i] = (edgeMarkColors[i]&0x8000)!=0;
|
||||
}
|
||||
|
||||
for(int i=0,y=0;y<192;y++)
|
||||
{
|
||||
for(int x=0;x<256;x++,i++)
|
||||
{
|
||||
Fragment &destFragment = screen[i];
|
||||
FragmentColor &destFragmentColor = screenColor[i];
|
||||
u8 self = destFragment.polyid.opaque>>3;
|
||||
if(!edgeMarkEnables[self]) continue;
|
||||
if(destFragment.isTranslucentPoly) continue;
|
||||
|
||||
u8 left = x==0?clearPolyid:(screen[i-1].polyid.opaque>>3);
|
||||
u8 right = x==255?clearPolyid:(screen[i+1].polyid.opaque>>3);
|
||||
u8 top = y==0?clearPolyid:(screen[i-256].polyid.opaque>>3);
|
||||
u8 bottom = y==191?clearPolyid:(screen[i+256].polyid.opaque>>3);
|
||||
|
||||
if(left != self || right != self || top != self || bottom != self)
|
||||
{
|
||||
destFragmentColor.color = edgeMarkColors[self];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void SoftRastConvertFramebuffer()
|
||||
{
|
||||
FragmentColor* src = screenColor;
|
||||
|
@ -1175,7 +1222,7 @@ static void SoftRastRender()
|
|||
{
|
||||
Fragment clearFragment;
|
||||
FragmentColor clearFragmentColor;
|
||||
clearFragment.pad = 0;
|
||||
clearFragment.isTranslucentPoly = 0;
|
||||
clearFragmentColor.r = gfx3d.clearColor&0x1F;
|
||||
clearFragmentColor.g = (gfx3d.clearColor>>5)&0x1F;
|
||||
clearFragmentColor.b = (gfx3d.clearColor>>10)&0x1F;
|
||||
|
@ -1314,6 +1361,7 @@ static void SoftRastRender()
|
|||
if(i == 0 || lastPolyAttr != poly->polyAttr)
|
||||
{
|
||||
polyAttr.setup(poly->polyAttr);
|
||||
polyAttr.translucent = poly->isTranslucent();
|
||||
lastPolyAttr = poly->polyAttr;
|
||||
}
|
||||
|
||||
|
@ -1360,6 +1408,8 @@ static void SoftRastRender()
|
|||
shape_engine(type,!polyAttr.backfacing);
|
||||
}
|
||||
|
||||
SoftRastFramebufferProcess();
|
||||
|
||||
// printf("rendered %d of %d polys after backface culling\n",gfx3d.polylist->count-culled,gfx3d.polylist->count);
|
||||
SoftRastConvertFramebuffer();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue