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,89 +782,92 @@ 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; while(v[0]->y == v[1]->y && v[0]->x > v[1]->x) {
if(Y1 < Y2) { swap(v[0],v[1]);
Middle = 1; Bottom = 2; swap(v[1],v[2]);
MiddleForCompare = 1; BottomForCompare = 2; }
} else {
Middle = 2; Bottom = 1; //wants clockwise
MiddleForCompare = 2; BottomForCompare = 1;
} fixed28_4 Y0 = v[0]->y, Y1 = v[1]->y, Y2 = v[2]->y;
gradients_fx_fl Gradients((const VERT**)v);
if(Y0 == Y1)
{
//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)
{
//if the last 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,0,1);
runscanline(Gradients,&edge1,&edge2);
}
else
{
//there are two pairs of edges
if(Y1<Y2)
{
//a triangle like
// 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 { else
if(Y2 < Y1) { {
Top = 2; Middle = 1; Bottom = 0; //a triangle like
MiddleForCompare = 1; BottomForCompare = 0; // 0
} else { //2
Top = 1; // 1
if(Y0 < Y2) { edge_fx_fl edge1 = edge_fx_fl(Gradients,v,0,2);
Middle = 0; Bottom = 2; edge_fx_fl edge2 = edge_fx_fl(Gradients,v,0,1);
MiddleForCompare = 3; BottomForCompare = 2; runscanline(Gradients,&edge1,&edge2);
} else { edge1 = edge_fx_fl(Gradients,v,2,1);
Middle = 2; Bottom = 0; runscanline(Gradients,&edge1,&edge2);
MiddleForCompare = 2; BottomForCompare = 3;
}
} }
} }
gradients_fx_fl Gradients((const VERT**)verts);
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) {
MiddleIsLeft = 0;
pLeft = &TopToBottom; pRight = &TopToMiddle;
} else {
MiddleIsLeft = 1;
pLeft = &TopToMiddle; pRight = &TopToBottom;
}
int Height = TopToMiddle.Height;
while(Height--) {
hecker_DrawScanLine(Gradients,pLeft,pRight);
TopToMiddle.Step(); TopToBottom.Step();
}
Height = MiddleToBottom.Height;
if(MiddleIsLeft) {
pLeft = &MiddleToBottom; pRight = &TopToBottom;
} else {
pLeft = &TopToBottom; pRight = &MiddleToBottom;
}
while(Height--) {
hecker_DrawScanLine(Gradients,pLeft,pRight);
MiddleToBottom.Step(); TopToBottom.Step();
}
} }
//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);