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
|
//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;
|
VERT ret;
|
||||||
const float coord_inside = inside->coord[coord];
|
const float coord_inside = inside->coord[COORD];
|
||||||
const float coord_outside = outside->coord[coord];
|
const float coord_outside = outside->coord[COORD];
|
||||||
const float w_inside = (which == -1) ? -inside->coord[3] : inside->coord[3];
|
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 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));
|
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 )
|
#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
|
//this seems like a prudent measure to make sure that math doesnt make a point pop back out
|
||||||
//of the clip volume through interpolation
|
//of the clip volume through interpolation
|
||||||
if (which == -1)
|
if (WHICH == -1)
|
||||||
ret.coord[coord] = -ret.coord[3];
|
ret.coord[COORD] = -ret.coord[3];
|
||||||
else
|
else
|
||||||
ret.coord[coord] = ret.coord[3];
|
ret.coord[COORD] = ret.coord[3];
|
||||||
|
|
||||||
return ret;
|
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 VERT scratchClipVerts [MAX_SCRATCH_CLIP_VERTS];
|
||||||
static int numScratchClipVerts = 0;
|
static int numScratchClipVerts = 0;
|
||||||
|
|
||||||
template <int coord, int which, class Next>
|
template <int COORD, int WHICH, class NEXT>
|
||||||
class ClipperPlane
|
class ClipperPlane
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClipperPlane(Next& next) : m_next(next) {}
|
ClipperPlane(NEXT& next) : m_next(next) {}
|
||||||
|
|
||||||
void init(VERT* verts)
|
void init(VERT* verts)
|
||||||
{
|
{
|
||||||
|
@ -2693,14 +2694,14 @@ public:
|
||||||
private:
|
private:
|
||||||
VERT* m_prevVert;
|
VERT* m_prevVert;
|
||||||
VERT* m_firstVert;
|
VERT* m_firstVert;
|
||||||
Next& m_next;
|
NEXT& m_next;
|
||||||
|
|
||||||
FORCEINLINE void clipSegmentVsPlane(bool hirez, const VERT *vert0, const VERT *vert1)
|
FORCEINLINE void clipSegmentVsPlane(bool hirez, const VERT *vert0, const VERT *vert1)
|
||||||
{
|
{
|
||||||
const float *vert0coord = vert0->coord;
|
const float *vert0coord = vert0->coord;
|
||||||
const float *vert1coord = vert1->coord;
|
const float *vert1coord = vert1->coord;
|
||||||
const bool out0 = (which == -1) ? (vert0coord[coord] < -vert0coord[3]) : (vert0coord[coord] > vert0coord[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]);
|
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.
|
//CONSIDER: should we try and clip things behind the eye? does this code even successfully do it? not sure.
|
||||||
//if(coord==2 && which==1) {
|
//if(coord==2 && which==1) {
|
||||||
|
@ -2726,7 +2727,7 @@ private:
|
||||||
{
|
{
|
||||||
CLIPLOG(" exiting\n");
|
CLIPLOG(" exiting\n");
|
||||||
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
|
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++]);
|
m_next.clipVert(hirez, &scratchClipVerts[numScratchClipVerts++]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2735,7 +2736,7 @@ private:
|
||||||
{
|
{
|
||||||
CLIPLOG(" entering\n");
|
CLIPLOG(" entering\n");
|
||||||
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
|
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, &scratchClipVerts[numScratchClipVerts++]);
|
||||||
m_next.clipVert(hirez, vert1);
|
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,Stage3> Stage2; static Stage2 clipper2 (clipper3); // right plane
|
||||||
typedef ClipperPlane<0,-1,Stage2> Stage1; static Stage1 clipper (clipper2); // left 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)
|
void GFX3D_Clipper::clipPoly(const POLY &poly, const VERT **verts)
|
||||||
{
|
{
|
||||||
CLIPLOG("==Begin poly==\n");
|
CLIPLOG("==Begin poly==\n");
|
||||||
|
@ -2788,9 +2789,9 @@ void GFX3D_Clipper::clipPoly(const POLY &poly, const VERT **verts)
|
||||||
|
|
||||||
clipper.init(clippedPolys[clippedPolyCounter].clipVerts);
|
clipper.init(clippedPolys[clippedPolyCounter].clipVerts);
|
||||||
for (size_t i = 0; i < type; i++)
|
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);
|
assert((u32)outType < MAX_CLIPPED_VERTS);
|
||||||
if (outType < POLYGON_TYPE_TRIANGLE)
|
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)
|
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;
|
FragmentColor srcColor;
|
||||||
|
@ -596,7 +596,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//handle shadow polys
|
//handle shadow polys
|
||||||
if (isShadowPolygon)
|
if (ISSHADOWPOLYGON)
|
||||||
{
|
{
|
||||||
if (polyAttr.polygonID == 0)
|
if (polyAttr.polygonID == 0)
|
||||||
{
|
{
|
||||||
|
@ -680,19 +680,19 @@ public:
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
depth_fail:
|
depth_fail:
|
||||||
if (isShadowPolygon && polyAttr.polygonID == 0)
|
if (ISSHADOWPOLYGON && polyAttr.polygonID == 0)
|
||||||
dstAttributeStencil++;
|
dstAttributeStencil++;
|
||||||
|
|
||||||
rejected_fragment:
|
rejected_fragment:
|
||||||
done:
|
done:
|
||||||
;
|
;
|
||||||
|
|
||||||
if (isShadowPolygon && polyAttr.polygonID != 0 && dstAttributeStencil)
|
if (ISSHADOWPOLYGON && polyAttr.polygonID != 0 && dstAttributeStencil)
|
||||||
dstAttributeStencil--;
|
dstAttributeStencil--;
|
||||||
}
|
}
|
||||||
|
|
||||||
//draws a single scanline
|
//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)
|
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;
|
int XStart = pLeft->X;
|
||||||
|
@ -779,7 +779,7 @@ public:
|
||||||
|
|
||||||
while (width-- > 0)
|
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++;
|
adr++;
|
||||||
x++;
|
x++;
|
||||||
|
|
||||||
|
@ -794,7 +794,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//runs several scanlines, until an edge is finished
|
//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)
|
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
|
//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)
|
if (lineHack && left->Height == 0 && right->Height == 0 && left->Y<framebufferHeight && left->Y>=0)
|
||||||
{
|
{
|
||||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
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--)
|
while(Height--)
|
||||||
{
|
{
|
||||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
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 xl = left->X;
|
||||||
const int xr = right->X;
|
const int xr = right->X;
|
||||||
const int y = left->Y;
|
const int y = left->Y;
|
||||||
|
@ -886,39 +886,39 @@ public:
|
||||||
|
|
||||||
|
|
||||||
//rotates verts counterclockwise
|
//rotates verts counterclockwise
|
||||||
template<int type>
|
template<int TYPE>
|
||||||
INLINE void rot_verts()
|
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(1); ROTSWAP(2); ROTSWAP(3); ROTSWAP(4);
|
||||||
ROTSWAP(5); ROTSWAP(6); ROTSWAP(7); ROTSWAP(8); ROTSWAP(9);
|
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
|
//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
|
//this is a necessary precondition for our shape engine
|
||||||
template<int type>
|
template<int TYPE>
|
||||||
void sort_verts(bool backwards)
|
void sort_verts(bool backwards)
|
||||||
{
|
{
|
||||||
//if the verts are backwards, reorder them first
|
//if the verts are backwards, reorder them first
|
||||||
if (backwards)
|
if (backwards)
|
||||||
for (size_t i = 0; i < type/2; i++)
|
for (size_t i = 0; i < TYPE/2; i++)
|
||||||
swap(verts[i],verts[type-i-1]);
|
swap(verts[i],verts[TYPE-i-1]);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
//this was the only way we could get this to unroll
|
//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(1); CHECKY(2); CHECKY(3); CHECKY(4);
|
||||||
CHECKY(5); CHECKY(6); CHECKY(7); CHECKY(8); CHECKY(9);
|
CHECKY(5); CHECKY(6); CHECKY(7); CHECKY(8); CHECKY(9);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
doswap:
|
doswap:
|
||||||
rot_verts<type>();
|
rot_verts<TYPE>();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (verts[0]->y == verts[1]->y && verts[0]->x > verts[1]->x)
|
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?)
|
// hack for VC++ 2010 (bug in compiler optimization?)
|
||||||
// freeze on 3D
|
// freeze on 3D
|
||||||
// TODO: study it
|
// TODO: study it
|
||||||
|
@ -933,7 +933,7 @@ public:
|
||||||
//verts must be clockwise.
|
//verts must be clockwise.
|
||||||
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
|
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
|
||||||
//Maybe it is like crow's algorithm
|
//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)
|
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;
|
bool failure = false;
|
||||||
|
@ -974,7 +974,7 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool horizontal = left.Y == right.Y;
|
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 we ran out of an edge, step to the next one
|
||||||
if (right.Height == 0)
|
if (right.Height == 0)
|
||||||
|
@ -1270,7 +1270,7 @@ Render3DError SoftRasterizerRenderer::InitTables()
|
||||||
return RENDER3DERROR_NOERR;
|
return RENDER3DERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool useHiResInterpolate>
|
template<bool USEHIRESINTERPOLATE>
|
||||||
size_t SoftRasterizerRenderer::performClipping(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList)
|
size_t SoftRasterizerRenderer::performClipping(const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList)
|
||||||
{
|
{
|
||||||
//submit all polys to clipper
|
//submit all polys to clipper
|
||||||
|
@ -1287,7 +1287,7 @@ size_t SoftRasterizerRenderer::performClipping(const VERTLIST *vertList, const P
|
||||||
:NULL
|
:NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
clipper.clipPoly<useHiResInterpolate>(poly, clipVerts);
|
clipper.clipPoly<USEHIRESINTERPOLATE>(poly, clipVerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clipper.clippedPolyCounter;
|
return clipper.clippedPolyCounter;
|
||||||
|
|
Loading…
Reference in New Issue