rasterize: handle polyids, improve transparency logic

This commit is contained in:
zeromus 2009-02-06 04:56:14 +00:00
parent a0940cad34
commit a73e0bf6a2
1 changed files with 35 additions and 23 deletions

View File

@ -107,8 +107,8 @@ struct PolyAttr
u32 val; u32 val;
bool decalMode; bool decalMode;
bool translucent;
bool translucentDepthWrite; bool translucentDepthWrite;
u8 polyid;
bool isVisible(bool backfacing) bool isVisible(bool backfacing)
{ {
@ -125,8 +125,8 @@ struct PolyAttr
{ {
val = polyAttr; val = polyAttr;
decalMode = BIT14(val); decalMode = BIT14(val);
this->translucent = translucent;
translucentDepthWrite = BIT11(val); translucentDepthWrite = BIT11(val);
polyid = (polyAttr>>24)&0x3F;
} }
} polyAttr; } polyAttr;
@ -141,8 +141,12 @@ struct Fragment
} components; } components;
} color; } color;
u8 polyid;
u32 depth; u32 depth;
struct {
u8 opaque, translucent;
} polyid;
u8 pad[6];
}; };
struct Vertex struct Vertex
@ -523,23 +527,30 @@ static void triangle_from_devmaster()
goto rejected_fragment; goto rejected_fragment;
} }
//alpha blending //handle polyids
alphaBlend(destFragment, shaderOutput); bool isOpaquePixel = shaderOutput.color.components.a == 31;
if(isOpaquePixel)
//depth writing
if(destFragment.color.components.a == 0)
{ {
//never update depth if the pixel is transparent destFragment.polyid.opaque = polyAttr.polyid;
} }
else else
{ {
if(!polyAttr.translucent) //dont overwrite pixels on translucent polys with the same polyids
destFragment.depth = w; if(destFragment.polyid.translucent == polyAttr.polyid)
else goto rejected_fragment;
if(polyAttr.translucent && polyAttr.translucentDepthWrite) destFragment.polyid.translucent = polyAttr.polyid;
destFragment.depth = w;
} }
//alpha blending and write to framebuffer
alphaBlend(destFragment, shaderOutput);
//depth writing
//at one point i wrote code with this comment, but I'm not sure whether it is accurate
//if(destFragment.color.components.a == 0) {} //never update depth if the pixel is transparent
if(isOpaquePixel || polyAttr.translucentDepthWrite)
destFragment.depth = w;
} else if(done) break; } else if(done) break;
rejected_fragment: rejected_fragment:
@ -642,16 +653,17 @@ static void SoftRastRender()
//B. backface cull //B. backface cull
//C. transforms //C. transforms
Fragment::Color clearColor; Fragment clearFragment;
clearColor.components.r = gfx3d.clearColor&0x1F; clearFragment.color.components.r = gfx3d.clearColor&0x1F;
clearColor.components.g = (gfx3d.clearColor>>5)&0x1F; clearFragment.color.components.g = (gfx3d.clearColor>>5)&0x1F;
clearColor.components.b = (gfx3d.clearColor>>10)&0x1F; clearFragment.color.components.b = (gfx3d.clearColor>>10)&0x1F;
clearColor.components.a = (gfx3d.clearColor>>16)&0x1F; clearFragment.color.components.a = (gfx3d.clearColor>>16)&0x1F;
memset(screen,0,sizeof(screen)); clearFragment.polyid.opaque = clearFragment.polyid.translucent = (gfx3d.clearColor>>24)&0x3F;
clearFragment.depth = 0x007FFFFF;
for(int i=0;i<256*192;i++) for(int i=0;i<256*192;i++)
{ {
screen[i].depth = 0x007FFFFF; screen[i] = clearFragment;
screen[i].color = clearColor;
} }
@ -763,7 +775,7 @@ static void SoftRastRender()
} }
printf("rendered %d of %d polys after backface culling\n",gfx3d.polylist->count-culled,gfx3d.polylist->count); //printf("rendered %d of %d polys after backface culling\n",gfx3d.polylist->count-culled,gfx3d.polylist->count);
} }