rasterize: continue formulating new triangle engine into a form that will be easier to extend to quads

This commit is contained in:
zeromus 2009-02-26 09:06:24 +00:00
parent cfc4dfe53d
commit e7c46f12a0
1 changed files with 74 additions and 69 deletions

View File

@ -23,7 +23,7 @@
//nothing in this file should be assumed to be accurate //nothing in this file should be assumed to be accurate
const bool USE_HECKER = false; //#define USE_HECKER
#include "rasterize.h" #include "rasterize.h"
@ -170,10 +170,11 @@ static VERT* verts[3];
INLINE static void SubmitVertex(int vert_index, VERT* rawvert) INLINE static void SubmitVertex(int vert_index, VERT* rawvert)
{ {
//HACK - reverse winding //HACK - reverse winding
if(USE_HECKER) #ifdef USE_HECKER
verts[2-vert_index] = rawvert; verts[2-vert_index] = rawvert;
else #else
verts[vert_index] = rawvert; verts[vert_index] = rawvert;
#endif
} }
static Fragment screen[256*192]; static Fragment screen[256*192];
@ -781,76 +782,78 @@ void hecker_DrawScanLine( gradients_fx_fl const &Gradients,edge_fx_fl *pLeft, ed
} }
} }
static void runscanline(gradients_fx_fl & gradients, edge_fx_fl *left, edge_fx_fl *right)
{
int Height = min(left->Height,right->Height);
while(Height--) {
hecker_DrawScanLine(gradients,left,right);
left->Step(); right->Step();
}
}
//http://chrishecker.com/Miscellaneous_Technical_Articles //http://chrishecker.com/Miscellaneous_Technical_Articles
static void triangle_from_hecker() static void triangle_from_hecker()
{ {
int Top, Middle, Bottom, MiddleForCompare, BottomForCompare; VERT* v[3] = {verts[0],verts[1],verts[2]};
fixed28_4 Y0 = verts[0]->y, Y1 = verts[1]->y, Y2 = verts[2]->y;
// sort vertices in y //rotate verts until vert0.y is minimum, and then vert0.x is minimum in case of ties
if(Y0 < Y1) { //this will reduce the complexity of our logic
if(Y2 < Y0) { while(v[0]->y > v[1]->y || v[0]->y > v[2]->y) {
Top = 2; Middle = 0; Bottom = 1; swap(v[0],v[1]);
MiddleForCompare = 0; BottomForCompare = 1; swap(v[1],v[2]);
} else {
Top = 0;
if(Y1 < Y2) {
Middle = 1; Bottom = 2;
MiddleForCompare = 1; BottomForCompare = 2;
} else {
Middle = 2; Bottom = 1;
MiddleForCompare = 2; BottomForCompare = 1;
}
}
} else {
if(Y2 < Y1) {
Top = 2; Middle = 1; Bottom = 0;
MiddleForCompare = 1; BottomForCompare = 0;
} else {
Top = 1;
if(Y0 < Y2) {
Middle = 0; Bottom = 2;
MiddleForCompare = 3; BottomForCompare = 2;
} else {
Middle = 2; Bottom = 0;
MiddleForCompare = 2; BottomForCompare = 3;
}
} }
while(v[0]->y == v[1]->y && v[0]->x > v[1]->x) {
swap(v[0],v[1]);
swap(v[1],v[2]);
} }
gradients_fx_fl Gradients((const VERT**)verts); //wants clockwise
edge_fx_fl TopToBottom(Gradients,verts,Top,Bottom);
edge_fx_fl TopToMiddle(Gradients,verts,Top,Middle);
edge_fx_fl MiddleToBottom(Gradients,verts,Middle,Bottom);
edge_fx_fl *pLeft, *pRight;
int MiddleIsLeft;
if(BottomForCompare > MiddleForCompare) { fixed28_4 Y0 = v[0]->y, Y1 = v[1]->y, Y2 = v[2]->y;
MiddleIsLeft = 0;
pLeft = &TopToBottom; pRight = &TopToMiddle; gradients_fx_fl Gradients((const VERT**)v);
} else {
MiddleIsLeft = 1; if(Y0 == Y1)
pLeft = &TopToMiddle; pRight = &TopToBottom; {
//if the first two points have the same y-coord, then there is only one pair of edges
edge_fx_fl edge1 = edge_fx_fl(Gradients,v,0,2);
edge_fx_fl edge2 = edge_fx_fl(Gradients,v,1,2);
runscanline(Gradients,&edge1,&edge2);
} }
else if(Y1 == Y2)
int Height = TopToMiddle.Height; {
//if the last two points have the same y-coord then there is only one pair of edges
while(Height--) { edge_fx_fl edge1 = edge_fx_fl(Gradients,v,0,2);
hecker_DrawScanLine(Gradients,pLeft,pRight); edge_fx_fl edge2 = edge_fx_fl(Gradients,v,0,1);
TopToMiddle.Step(); TopToBottom.Step(); runscanline(Gradients,&edge1,&edge2);
} }
else
Height = MiddleToBottom.Height; {
//there are two pairs of edges
if(MiddleIsLeft) { if(Y1<Y2)
pLeft = &MiddleToBottom; pRight = &TopToBottom; {
} else { //a triangle like
pLeft = &TopToBottom; pRight = &MiddleToBottom; // 0
// 1
//2
edge_fx_fl edge1 = edge_fx_fl(Gradients,v,0,2);
edge_fx_fl edge2 = edge_fx_fl(Gradients,v,0,1);
runscanline(Gradients,&edge1,&edge2);
edge2 = edge_fx_fl(Gradients,v,1,2);
runscanline(Gradients,&edge1,&edge2);
}
else
{
//a triangle like
// 0
//2
// 1
edge_fx_fl edge1 = edge_fx_fl(Gradients,v,0,2);
edge_fx_fl edge2 = edge_fx_fl(Gradients,v,0,1);
runscanline(Gradients,&edge1,&edge2);
edge1 = edge_fx_fl(Gradients,v,2,1);
runscanline(Gradients,&edge1,&edge2);
} }
while(Height--) {
hecker_DrawScanLine(Gradients,pLeft,pRight);
MiddleToBottom.Step(); TopToBottom.Step();
} }
} }
@ -859,11 +862,12 @@ static void triangle_from_hecker()
//http://www.devmaster.net/forums/showthread.php?t=1884&page=1 //http://www.devmaster.net/forums/showthread.php?t=1884&page=1
static void triangle_from_devmaster() static void triangle_from_devmaster()
{ {
if(USE_HECKER) #ifdef USE_HECKER
{ {
triangle_from_hecker(); triangle_from_hecker();
return; return;
} }
#endif
// 28.4 fixed-point coordinates // 28.4 fixed-point coordinates
const int Y1 = iround(16.0f * verts[0]->coord[1]); const int Y1 = iround(16.0f * verts[0]->coord[1]);
@ -1381,10 +1385,11 @@ static void SoftRastRender()
needInitTexture = false; needInitTexture = false;
} }
if(USE_HECKER) #ifdef USE_HECKER
for(int i=0;i<type;i++) for(int i=0;i<type;i++)
for(int j=0;j<2;j++) for(int j=0;j<2;j++)
verts[i]->coord[j] = iround(16.0f * verts[i]->coord[j]); verts[i]->coord[j] = iround(16.0f * verts[i]->coord[j]);
#endif
//hmm... shader gets setup every time because it depends on sampler which may have just changed //hmm... shader gets setup every time because it depends on sampler which may have just changed
shader.setup(poly->polyAttr); shader.setup(poly->polyAttr);