parent
fedef6c842
commit
3a11617bed
|
@ -2623,13 +2623,14 @@ static T interpolate(const float ratio, const T& x0, const T& x1)
|
|||
}
|
||||
|
||||
//http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/as6/discussion.shtml
|
||||
template<int coord, int which> static FORCEINLINE VERT clipPoint(bool hirez, const VERT *inside, const VERT *outside)
|
||||
template<int COORD, int WHICH>
|
||||
static FORCEINLINE VERT clipPoint(bool hirez, const VERT *inside, const VERT *outside)
|
||||
{
|
||||
VERT ret;
|
||||
const float coord_inside = inside->coord[coord];
|
||||
const float coord_outside = outside->coord[coord];
|
||||
const float w_inside = (which == -1) ? -inside->coord[3] : inside->coord[3];
|
||||
const float w_outside = (which == -1) ? -outside->coord[3] : outside->coord[3];
|
||||
const float coord_inside = inside->coord[COORD];
|
||||
const float coord_outside = outside->coord[COORD];
|
||||
const float w_inside = (WHICH == -1) ? -inside->coord[3] : inside->coord[3];
|
||||
const float w_outside = (WHICH == -1) ? -outside->coord[3] : outside->coord[3];
|
||||
const float t = (coord_inside - w_inside) / ((w_outside-w_inside) - (coord_outside-coord_inside));
|
||||
|
||||
#define INTERP(X) ret . X = interpolate(t, inside-> X ,outside-> X )
|
||||
|
@ -2649,10 +2650,10 @@ template<int coord, int which> static FORCEINLINE VERT clipPoint(bool hirez, con
|
|||
|
||||
//this seems like a prudent measure to make sure that math doesnt make a point pop back out
|
||||
//of the clip volume through interpolation
|
||||
if (which == -1)
|
||||
ret.coord[coord] = -ret.coord[3];
|
||||
if (WHICH == -1)
|
||||
ret.coord[COORD] = -ret.coord[3];
|
||||
else
|
||||
ret.coord[coord] = ret.coord[3];
|
||||
ret.coord[COORD] = ret.coord[3];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2661,11 +2662,11 @@ template<int coord, int which> static FORCEINLINE VERT clipPoint(bool hirez, con
|
|||
static VERT scratchClipVerts [MAX_SCRATCH_CLIP_VERTS];
|
||||
static int numScratchClipVerts = 0;
|
||||
|
||||
template <int coord, int which, class Next>
|
||||
template <int COORD, int WHICH, class NEXT>
|
||||
class ClipperPlane
|
||||
{
|
||||
public:
|
||||
ClipperPlane(Next& next) : m_next(next) {}
|
||||
ClipperPlane(NEXT& next) : m_next(next) {}
|
||||
|
||||
void init(VERT* verts)
|
||||
{
|
||||
|
@ -2693,14 +2694,14 @@ public:
|
|||
private:
|
||||
VERT* m_prevVert;
|
||||
VERT* m_firstVert;
|
||||
Next& m_next;
|
||||
NEXT& m_next;
|
||||
|
||||
FORCEINLINE void clipSegmentVsPlane(bool hirez, const VERT *vert0, const VERT *vert1)
|
||||
{
|
||||
const float *vert0coord = vert0->coord;
|
||||
const float *vert1coord = vert1->coord;
|
||||
const bool out0 = (which == -1) ? (vert0coord[coord] < -vert0coord[3]) : (vert0coord[coord] > vert0coord[3]);
|
||||
const bool out1 = (which == -1) ? (vert1coord[coord] < -vert1coord[3]) : (vert1coord[coord] > vert1coord[3]);
|
||||
const bool out0 = (WHICH == -1) ? (vert0coord[COORD] < -vert0coord[3]) : (vert0coord[COORD] > vert0coord[3]);
|
||||
const bool out1 = (WHICH == -1) ? (vert1coord[COORD] < -vert1coord[3]) : (vert1coord[COORD] > vert1coord[3]);
|
||||
|
||||
//CONSIDER: should we try and clip things behind the eye? does this code even successfully do it? not sure.
|
||||
//if(coord==2 && which==1) {
|
||||
|
@ -2726,7 +2727,7 @@ private:
|
|||
{
|
||||
CLIPLOG(" exiting\n");
|
||||
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
|
||||
scratchClipVerts[numScratchClipVerts] = clipPoint<coord, which>(hirez, vert0, vert1);
|
||||
scratchClipVerts[numScratchClipVerts] = clipPoint<COORD, WHICH>(hirez, vert0, vert1);
|
||||
m_next.clipVert(hirez, &scratchClipVerts[numScratchClipVerts++]);
|
||||
}
|
||||
|
||||
|
@ -2735,7 +2736,7 @@ private:
|
|||
{
|
||||
CLIPLOG(" entering\n");
|
||||
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
|
||||
scratchClipVerts[numScratchClipVerts] = clipPoint<coord, which>(hirez, vert1, vert0);
|
||||
scratchClipVerts[numScratchClipVerts] = clipPoint<COORD, WHICH>(hirez, vert1, vert0);
|
||||
m_next.clipVert(hirez, &scratchClipVerts[numScratchClipVerts++]);
|
||||
m_next.clipVert(hirez, vert1);
|
||||
}
|
||||
|
@ -2778,7 +2779,7 @@ typedef ClipperPlane<1,-1,Stage4> Stage3; static Stage3 clipper3 (clipper
|
|||
typedef ClipperPlane<0, 1,Stage3> Stage2; static Stage2 clipper2 (clipper3); // right plane
|
||||
typedef ClipperPlane<0,-1,Stage2> Stage1; static Stage1 clipper (clipper2); // left plane
|
||||
|
||||
template<bool useHiResInterpolate>
|
||||
template<bool USEHIRESINTERPOLATE>
|
||||
void GFX3D_Clipper::clipPoly(const POLY &poly, const VERT **verts)
|
||||
{
|
||||
CLIPLOG("==Begin poly==\n");
|
||||
|
@ -2788,9 +2789,9 @@ void GFX3D_Clipper::clipPoly(const POLY &poly, const VERT **verts)
|
|||
|
||||
clipper.init(clippedPolys[clippedPolyCounter].clipVerts);
|
||||
for (size_t i = 0; i < type; i++)
|
||||
clipper.clipVert(useHiResInterpolate, verts[i]);
|
||||
clipper.clipVert(USEHIRESINTERPOLATE, verts[i]);
|
||||
|
||||
const PolygonType outType = (PolygonType)clipper.finish(useHiResInterpolate);
|
||||
const PolygonType outType = (PolygonType)clipper.finish(USEHIRESINTERPOLATE);
|
||||
|
||||
assert((u32)outType < MAX_CLIPPED_VERTS);
|
||||
if (outType < POLYGON_TYPE_TRIANGLE)
|
||||
|
|
|
@ -555,7 +555,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<bool isShadowPolygon>
|
||||
template<bool ISSHADOWPOLYGON>
|
||||
FORCEINLINE void pixel(const PolygonAttributes &polyAttr, const size_t fragmentIndex, FragmentColor &dstColor, float r, float g, float b, float invu, float invv, float w, float z)
|
||||
{
|
||||
FragmentColor srcColor;
|
||||
|
@ -596,7 +596,7 @@ public:
|
|||
}
|
||||
|
||||
//handle shadow polys
|
||||
if (isShadowPolygon)
|
||||
if (ISSHADOWPOLYGON)
|
||||
{
|
||||
if (polyAttr.polygonID == 0)
|
||||
{
|
||||
|
@ -680,19 +680,19 @@ public:
|
|||
|
||||
goto done;
|
||||
depth_fail:
|
||||
if (isShadowPolygon && polyAttr.polygonID == 0)
|
||||
if (ISSHADOWPOLYGON && polyAttr.polygonID == 0)
|
||||
dstAttributeStencil++;
|
||||
|
||||
rejected_fragment:
|
||||
done:
|
||||
;
|
||||
|
||||
if (isShadowPolygon && polyAttr.polygonID != 0 && dstAttributeStencil)
|
||||
if (ISSHADOWPOLYGON && polyAttr.polygonID != 0 && dstAttributeStencil)
|
||||
dstAttributeStencil--;
|
||||
}
|
||||
|
||||
//draws a single scanline
|
||||
template <bool isShadowPolygon>
|
||||
template <bool ISSHADOWPOLYGON>
|
||||
FORCEINLINE void drawscanline(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *pLeft, edge_fx_fl *pRight, bool lineHack)
|
||||
{
|
||||
int XStart = pLeft->X;
|
||||
|
@ -779,7 +779,7 @@ public:
|
|||
|
||||
while (width-- > 0)
|
||||
{
|
||||
pixel<isShadowPolygon>(polyAttr, adr, dstColor[adr], color[0], color[1], color[2], u, v, 1.0f/invw, z);
|
||||
pixel<ISSHADOWPOLYGON>(polyAttr, adr, dstColor[adr], color[0], color[1], color[2], u, v, 1.0f/invw, z);
|
||||
adr++;
|
||||
x++;
|
||||
|
||||
|
@ -794,7 +794,7 @@ public:
|
|||
}
|
||||
|
||||
//runs several scanlines, until an edge is finished
|
||||
template<bool SLI, bool isShadowPolygon>
|
||||
template<bool SLI, bool ISSHADOWPOLYGON>
|
||||
void runscanlines(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, edge_fx_fl *left, edge_fx_fl *right, bool horizontal, bool lineHack)
|
||||
{
|
||||
//oh lord, hack city for edge drawing
|
||||
|
@ -807,13 +807,13 @@ public:
|
|||
if (lineHack && left->Height == 0 && right->Height == 0 && left->Y<framebufferHeight && left->Y>=0)
|
||||
{
|
||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||
if(draw) drawscanline<isShadowPolygon>(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
|
||||
if(draw) drawscanline<ISSHADOWPOLYGON>(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
|
||||
}
|
||||
|
||||
while(Height--)
|
||||
{
|
||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||
if(draw) drawscanline<isShadowPolygon>(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
|
||||
if(draw) drawscanline<ISSHADOWPOLYGON>(polyAttr, dstColor, framebufferWidth, framebufferHeight, left,right,lineHack);
|
||||
const int xl = left->X;
|
||||
const int xr = right->X;
|
||||
const int y = left->Y;
|
||||
|
@ -886,39 +886,39 @@ public:
|
|||
|
||||
|
||||
//rotates verts counterclockwise
|
||||
template<int type>
|
||||
template<int TYPE>
|
||||
INLINE void rot_verts()
|
||||
{
|
||||
#define ROTSWAP(X) if(type>X) swap(verts[X-1],verts[X]);
|
||||
#define ROTSWAP(X) if(TYPE>X) swap(verts[X-1],verts[X]);
|
||||
ROTSWAP(1); ROTSWAP(2); ROTSWAP(3); ROTSWAP(4);
|
||||
ROTSWAP(5); ROTSWAP(6); ROTSWAP(7); ROTSWAP(8); ROTSWAP(9);
|
||||
}
|
||||
|
||||
//rotate verts until vert0.y is minimum, and then vert0.x is minimum in case of ties
|
||||
//this is a necessary precondition for our shape engine
|
||||
template<int type>
|
||||
template<int TYPE>
|
||||
void sort_verts(bool backwards)
|
||||
{
|
||||
//if the verts are backwards, reorder them first
|
||||
if (backwards)
|
||||
for (size_t i = 0; i < type/2; i++)
|
||||
swap(verts[i],verts[type-i-1]);
|
||||
for (size_t i = 0; i < TYPE/2; i++)
|
||||
swap(verts[i],verts[TYPE-i-1]);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
//this was the only way we could get this to unroll
|
||||
#define CHECKY(X) if(type>X) if(verts[0]->y > verts[X]->y) goto doswap;
|
||||
#define CHECKY(X) if(TYPE>X) if(verts[0]->y > verts[X]->y) goto doswap;
|
||||
CHECKY(1); CHECKY(2); CHECKY(3); CHECKY(4);
|
||||
CHECKY(5); CHECKY(6); CHECKY(7); CHECKY(8); CHECKY(9);
|
||||
break;
|
||||
|
||||
doswap:
|
||||
rot_verts<type>();
|
||||
rot_verts<TYPE>();
|
||||
}
|
||||
|
||||
while (verts[0]->y == verts[1]->y && verts[0]->x > verts[1]->x)
|
||||
{
|
||||
rot_verts<type>();
|
||||
rot_verts<TYPE>();
|
||||
// hack for VC++ 2010 (bug in compiler optimization?)
|
||||
// freeze on 3D
|
||||
// TODO: study it
|
||||
|
@ -933,7 +933,7 @@ public:
|
|||
//verts must be clockwise.
|
||||
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
|
||||
//Maybe it is like crow's algorithm
|
||||
template<bool SLI, bool isShadowPolygon>
|
||||
template<bool SLI, bool ISSHADOWPOLYGON>
|
||||
void shape_engine(const PolygonAttributes &polyAttr, FragmentColor *dstColor, const size_t framebufferWidth, const size_t framebufferHeight, int type, const bool backwards, bool lineHack)
|
||||
{
|
||||
bool failure = false;
|
||||
|
@ -974,7 +974,7 @@ public:
|
|||
return;
|
||||
|
||||
bool horizontal = left.Y == right.Y;
|
||||
runscanlines<SLI, isShadowPolygon>(polyAttr, dstColor, framebufferWidth, framebufferHeight, &left, &right, horizontal, lineHack);
|
||||
runscanlines<SLI, ISSHADOWPOLYGON>(polyAttr, dstColor, framebufferWidth, framebufferHeight, &left, &right, horizontal, lineHack);
|
||||
|
||||
//if we ran out of an edge, step to the next one
|
||||
if (right.Height == 0)
|
||||
|
@ -1270,7 +1270,7 @@ Render3DError SoftRasterizerRenderer::InitTables()
|
|||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
template<bool useHiResInterpolate>
|
||||
template<bool USEHIRESINTERPOLATE>
|
||||
size_t SoftRasterizerRenderer::performClipping(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList)
|
||||
{
|
||||
//submit all polys to clipper
|
||||
|
@ -1287,7 +1287,7 @@ size_t SoftRasterizerRenderer::performClipping(const VERTLIST *vertList, const P
|
|||
:NULL
|
||||
};
|
||||
|
||||
clipper.clipPoly<useHiResInterpolate>(poly, clipVerts);
|
||||
clipper.clipPoly<USEHIRESINTERPOLATE>(poly, clipVerts);
|
||||
}
|
||||
|
||||
return clipper.clippedPolyCounter;
|
||||
|
|
Loading…
Reference in New Issue