diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index 515d0d931..9ee2d3ebb 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -23,7 +23,7 @@ //nothing in this file should be assumed to be accurate -const bool USE_HECKER = false; +//#define USE_HECKER #include "rasterize.h" @@ -170,10 +170,11 @@ static VERT* verts[3]; INLINE static void SubmitVertex(int vert_index, VERT* rawvert) { //HACK - reverse winding - if(USE_HECKER) + #ifdef USE_HECKER verts[2-vert_index] = rawvert; - else + #else verts[vert_index] = rawvert; + #endif } 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 static void triangle_from_hecker() { - int Top, Middle, Bottom, MiddleForCompare, BottomForCompare; - fixed28_4 Y0 = verts[0]->y, Y1 = verts[1]->y, Y2 = verts[2]->y; + VERT* v[3] = {verts[0],verts[1],verts[2]}; - // sort vertices in y - if(Y0 < Y1) { - if(Y2 < Y0) { - Top = 2; Middle = 0; Bottom = 1; - MiddleForCompare = 0; BottomForCompare = 1; - } else { - Top = 0; - if(Y1 < Y2) { - Middle = 1; Bottom = 2; - MiddleForCompare = 1; BottomForCompare = 2; - } else { - Middle = 2; Bottom = 1; - MiddleForCompare = 2; BottomForCompare = 1; - } + //rotate verts until vert0.y is minimum, and then vert0.x is minimum in case of ties + //this will reduce the complexity of our logic + while(v[0]->y > v[1]->y || v[0]->y > v[2]->y) { + swap(v[0],v[1]); + swap(v[1],v[2]); + } + while(v[0]->y == v[1]->y && v[0]->x > v[1]->x) { + swap(v[0],v[1]); + swap(v[1],v[2]); + } + + //wants clockwise + + 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 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 static void triangle_from_devmaster() { - if(USE_HECKER) +#ifdef USE_HECKER { triangle_from_hecker(); return; } +#endif // 28.4 fixed-point coordinates const int Y1 = iround(16.0f * verts[0]->coord[1]); @@ -1381,10 +1385,11 @@ static void SoftRastRender() needInitTexture = false; } - if(USE_HECKER) +#ifdef USE_HECKER for(int i=0;icoord[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 shader.setup(poly->polyAttr);