rasterize: quads are now directly supported
This commit is contained in:
parent
222664eb8c
commit
51ed1af70f
|
@ -22,8 +22,9 @@
|
|||
*/
|
||||
|
||||
//nothing in this file should be assumed to be accurate
|
||||
|
||||
//#define USE_HECKER
|
||||
//
|
||||
//the shape rasterizers contained herein are based on code supplied by Chris Hecker from
|
||||
//http://chrishecker.com/Miscellaneous_Technical_Articles
|
||||
|
||||
#include "rasterize.h"
|
||||
|
||||
|
@ -165,16 +166,11 @@ struct Fragment
|
|||
u8 pad[5];
|
||||
};
|
||||
|
||||
static VERT* verts[3];
|
||||
static VERT* verts[4];
|
||||
|
||||
INLINE static void SubmitVertex(int vert_index, VERT* rawvert)
|
||||
{
|
||||
//HACK - reverse winding
|
||||
#ifdef USE_HECKER
|
||||
verts[2-vert_index] = rawvert;
|
||||
#else
|
||||
verts[vert_index] = rawvert;
|
||||
#endif
|
||||
verts[vert_index] = rawvert;
|
||||
}
|
||||
|
||||
static Fragment screen[256*192];
|
||||
|
@ -567,10 +563,25 @@ void scanline(int y, int xstart, int xend,
|
|||
|
||||
typedef int fixed28_4;
|
||||
|
||||
static bool failure;
|
||||
|
||||
// handle floor divides and mods correctly
|
||||
inline void FloorDivMod( long Numerator, long Denominator, long &Floor, long &Mod )
|
||||
{
|
||||
assert(Denominator > 0); // we assume it's positive
|
||||
//These must be caused by invalid or degenerate shapes.. not sure yet.
|
||||
//check it out in the mario face intro of SM64
|
||||
//so, we have to take out the assert.
|
||||
//I do know that we handle SOME invalid shapes without crashing,
|
||||
//since I see them acting poppy in a way that doesnt happen in the HW.. so alas it is also incorrect.
|
||||
//This particular incorrectness is not likely ever to get fixed!
|
||||
|
||||
//assert(Denominator > 0);
|
||||
|
||||
//but we have to bail out since our handling for these cases currently steps scanlines
|
||||
//the wrong way and goes totally nuts (freezes)
|
||||
if(Denominator<=0)
|
||||
failure = true;
|
||||
|
||||
if(Numerator >= 0) {
|
||||
// positive case, C is okay
|
||||
Floor = Numerator / Denominator;
|
||||
|
@ -615,25 +626,8 @@ inline long Ceil28_4( fixed28_4 Value ) {
|
|||
return ReturnValue;
|
||||
}
|
||||
|
||||
|
||||
struct Derivatives {
|
||||
float dx, dy;
|
||||
void calculate(float v0, float v1, float v2, float invdx, float invdy, const VERT** pVertices)
|
||||
{
|
||||
dx = invdx * (
|
||||
((v1 - v2) * Fixed28_4ToFloat(pVertices[0]->y - pVertices[2]->y))
|
||||
- ((v0 - v2) * Fixed28_4ToFloat(pVertices[1]->y - pVertices[2]->y))
|
||||
);
|
||||
|
||||
dy = invdy * (
|
||||
((v1 - v2) * Fixed28_4ToFloat(pVertices[0]->x - pVertices[2]->x))
|
||||
- ((v0 - v2) * Fixed28_4ToFloat(pVertices[1]->x - pVertices[2]->x))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct edge_fx_fl {
|
||||
edge_fx_fl() {}
|
||||
edge_fx_fl(VERT **pVertices, int Top, int Bottom );
|
||||
inline int Step( void );
|
||||
|
||||
|
@ -652,12 +646,6 @@ struct edge_fx_fl {
|
|||
step = XStep * dx + dy;
|
||||
stepExtra = dx;
|
||||
}
|
||||
void old_initialize(float val, long XStep, float XPrestep, float YPrestep, const Derivatives& gradient) {
|
||||
curr = val + YPrestep * gradient.dy
|
||||
+ XPrestep * gradient.dx;
|
||||
step = XStep * gradient.dx + gradient.dy;
|
||||
stepExtra = gradient.dx;
|
||||
}
|
||||
};
|
||||
|
||||
static const int NUM_INTERPOLANTS = 7;
|
||||
|
@ -716,18 +704,12 @@ inline int edge_fx_fl::Step( void ) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void hecker_DrawScanLine( edge_fx_fl *pLeft, edge_fx_fl *pRight )
|
||||
void hecker_DrawScanLine(edge_fx_fl *pLeft, edge_fx_fl *pRight)
|
||||
{
|
||||
int XStart = pLeft->X;
|
||||
int Width = pRight->X - XStart;
|
||||
|
||||
//char unsigned *pDestBits = Dest.pBits;
|
||||
//char unsigned * const pTextureBits = Texture.pBits;
|
||||
//pDestBits += pLeft->Y * Dest.DeltaScan + XStart;
|
||||
//long TextureDeltaScan = Texture.DeltaScan;
|
||||
int width = pRight->X - XStart;
|
||||
|
||||
//these are the starting values, taken from the left edge
|
||||
float invw = pLeft->invw.curr;
|
||||
float u = pLeft->u.curr;
|
||||
float v = pLeft->v.curr;
|
||||
|
@ -737,7 +719,8 @@ void hecker_DrawScanLine( edge_fx_fl *pLeft, edge_fx_fl *pRight )
|
|||
pLeft->color[1].curr,
|
||||
pLeft->color[2].curr };
|
||||
|
||||
float invWidth = 1.0f / Width;
|
||||
//our dx values are taken from the steps up until the right edge
|
||||
float invWidth = 1.0f / width;
|
||||
float dinvw_dx = (pRight->invw.curr - invw) * invWidth;
|
||||
float du_dx = (pRight->u.curr - u) * invWidth;
|
||||
float dv_dx = (pRight->v.curr - v) * invWidth;
|
||||
|
@ -748,11 +731,9 @@ void hecker_DrawScanLine( edge_fx_fl *pLeft, edge_fx_fl *pRight )
|
|||
(pRight->color[2].curr - color[2]) * invWidth };
|
||||
|
||||
|
||||
//scanline(pLeft->Y,pLeft->X,pRight->X,31,31,31,0,0,0,1/pLeft->OneOverZ,31,31,31,0,0,
|
||||
|
||||
int adr = (pLeft->Y<<8)+XStart;
|
||||
|
||||
while(Width-- > 0)
|
||||
while(width-- > 0)
|
||||
{
|
||||
pixel(adr,color[0],color[1],color[2],u,v,invw,z);
|
||||
adr++;
|
||||
|
@ -761,12 +742,14 @@ void hecker_DrawScanLine( edge_fx_fl *pLeft, edge_fx_fl *pRight )
|
|||
u += du_dx;
|
||||
v += dv_dx;
|
||||
z += dz_dx;
|
||||
for(int i=0;i<3;i++) color[i] += dc_dx[i];
|
||||
for(int i=0;i<3;i++)
|
||||
color[i] += dc_dx[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void runscanline(edge_fx_fl *left, edge_fx_fl *right)
|
||||
{
|
||||
//do not overstep either of the edges
|
||||
int Height = min(left->Height,right->Height);
|
||||
while(Height--) {
|
||||
hecker_DrawScanLine(left,right);
|
||||
|
@ -775,237 +758,62 @@ static void runscanline(edge_fx_fl *left, edge_fx_fl *right)
|
|||
}
|
||||
}
|
||||
|
||||
//http://chrishecker.com/Miscellaneous_Technical_Articles
|
||||
static void triangle_from_hecker()
|
||||
//This function can handle a quad or a triangle. A triangle is just a quad with a duped vert.
|
||||
//verts must be clockwise.
|
||||
//The algorithm used here is of my own devising... as far as I know.
|
||||
static void shape_engine()
|
||||
{
|
||||
VERT* v[3] = {verts[0],verts[1],verts[2]};
|
||||
failure = false;
|
||||
|
||||
VERT* v[4] = {verts[0],verts[1],verts[2],verts[3]};
|
||||
|
||||
//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) {
|
||||
while(v[0]->y > v[1]->y || v[0]->y > v[2]->y || v[0]->y > v[3]->y) {
|
||||
swap(v[0],v[1]);
|
||||
swap(v[1],v[2]);
|
||||
swap(v[2],v[3]);
|
||||
}
|
||||
while(v[0]->y == v[1]->y && v[0]->x > v[1]->x) {
|
||||
swap(v[0],v[1]);
|
||||
swap(v[1],v[2]);
|
||||
swap(v[2],v[3]);
|
||||
}
|
||||
|
||||
//wants clockwise
|
||||
//we are going to step around the polygon in both directions starting from vert 0.
|
||||
//right edges will be stepped over clockwise and left edges stepped over counterclockwise.
|
||||
//these variables track that stepping, but in order to facilitate wrapping we start extra high
|
||||
//for the counter we're decrementing.
|
||||
int lv = 4, rv = 0;
|
||||
|
||||
fixed28_4 Y0 = v[0]->y, Y1 = v[1]->y, Y2 = v[2]->y;
|
||||
edge_fx_fl left, right;
|
||||
bool step_left = true, step_right = true;
|
||||
for(;;) {
|
||||
//generate new edges if necessary. we must avoid regenerating edges when they are incomplete
|
||||
//so that they can be continued on down the shape
|
||||
if(step_left) left = edge_fx_fl(v,lv&3,lv-1);
|
||||
if(step_right) right = edge_fx_fl(v,rv&3,rv+1);
|
||||
step_left = step_right = false;
|
||||
|
||||
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(v,0,2);
|
||||
edge_fx_fl edge2 = edge_fx_fl(v,1,2);
|
||||
runscanline(&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(v,0,2);
|
||||
edge_fx_fl edge2 = edge_fx_fl(v,0,1);
|
||||
runscanline(&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(v,0,2);
|
||||
edge_fx_fl edge2 = edge_fx_fl(v,0,1);
|
||||
runscanline(&edge1,&edge2);
|
||||
edge2 = edge_fx_fl(v,1,2);
|
||||
runscanline(&edge1,&edge2);
|
||||
}
|
||||
else
|
||||
{
|
||||
//a triangle like
|
||||
// 0
|
||||
//2
|
||||
// 1
|
||||
edge_fx_fl edge1 = edge_fx_fl(v,0,2);
|
||||
edge_fx_fl edge2 = edge_fx_fl(v,0,1);
|
||||
runscanline(&edge1,&edge2);
|
||||
edge1 = edge_fx_fl(v,2,1);
|
||||
runscanline(&edge1,&edge2);
|
||||
}
|
||||
}
|
||||
//handle a failure in the edge setup.
|
||||
if(failure)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//http://www.devmaster.net/forums/showthread.php?t=1884&page=1
|
||||
static void triangle_from_devmaster()
|
||||
{
|
||||
#ifdef USE_HECKER
|
||||
{
|
||||
triangle_from_hecker();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 28.4 fixed-point coordinates
|
||||
const int Y1 = iround(16.0f * verts[0]->coord[1]);
|
||||
const int Y2 = iround(16.0f * verts[1]->coord[1]);
|
||||
const int Y3 = iround(16.0f * verts[2]->coord[1]);
|
||||
|
||||
const int X1 = iround(16.0f * verts[0]->coord[0]);
|
||||
const int X2 = iround(16.0f * verts[1]->coord[0]);
|
||||
const int X3 = iround(16.0f * verts[2]->coord[0]);
|
||||
|
||||
// Deltas
|
||||
const int DX12 = X1 - X2;
|
||||
const int DX23 = X2 - X3;
|
||||
const int DX31 = X3 - X1;
|
||||
|
||||
const int DY12 = Y1 - Y2;
|
||||
const int DY23 = Y2 - Y3;
|
||||
const int DY31 = Y3 - Y1;
|
||||
|
||||
// Fixed-point deltas
|
||||
const int FDX12 = DX12 << 4;
|
||||
const int FDX23 = DX23 << 4;
|
||||
const int FDX31 = DX31 << 4;
|
||||
|
||||
const int FDY12 = DY12 << 4;
|
||||
const int FDY23 = DY23 << 4;
|
||||
const int FDY31 = DY31 << 4;
|
||||
|
||||
// Bounding rectangle
|
||||
int minx = (_min(X1, X2, X3) + 0xF) >> 4;
|
||||
int maxx = (_max(X1, X2, X3) + 0xF) >> 4;
|
||||
int miny = (_min(Y1, Y2, Y3) + 0xF) >> 4;
|
||||
int maxy = (_max(Y1, Y2, Y3) + 0xF) >> 4;
|
||||
|
||||
int desty = miny;
|
||||
|
||||
// Half-edge constants
|
||||
int C1 = DY12 * X1 - DX12 * Y1;
|
||||
int C2 = DY23 * X2 - DX23 * Y2;
|
||||
int C3 = DY31 * X3 - DX31 * Y3;
|
||||
|
||||
// Correct for fill convention
|
||||
if(DY12 < 0 || (DY12 == 0 && DX12 > 0)) C1++;
|
||||
if(DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++;
|
||||
if(DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++;
|
||||
|
||||
int CY1 = C1 + DX12 * (miny << 4) - DY12 * (minx << 4);
|
||||
int CY2 = C2 + DX23 * (miny << 4) - DY23 * (minx << 4);
|
||||
int CY3 = C3 + DX31 * (miny << 4) - DY31 * (minx << 4);
|
||||
|
||||
float fx1 = verts[0]->coord[0], fy1 = verts[0]->coord[1], fz1 = verts[0]->coord[2];
|
||||
float fx2 = verts[1]->coord[0], fy2 = verts[1]->coord[1], fz2 = verts[1]->coord[2];
|
||||
float fx3 = verts[2]->coord[0], fy3 = verts[2]->coord[1], fz3 = verts[2]->coord[2];
|
||||
float r1 = verts[0]->fcolor[0], g1 = verts[0]->fcolor[1], b1 = verts[0]->fcolor[2];
|
||||
float r2 = verts[1]->fcolor[0], g2 = verts[1]->fcolor[1], b2 = verts[1]->fcolor[2];
|
||||
float r3 = verts[2]->fcolor[0], g3 = verts[2]->fcolor[1], b3 = verts[2]->fcolor[2];
|
||||
float u1 = verts[0]->texcoord[0], v1 = verts[0]->texcoord[1];
|
||||
float u2 = verts[1]->texcoord[0], v2 = verts[1]->texcoord[1];
|
||||
float u3 = verts[2]->texcoord[0], v3 = verts[2]->texcoord[1];
|
||||
float w1 = verts[0]->coord[3], w2 = verts[1]->coord[3], w3 = verts[2]->coord[3];
|
||||
|
||||
|
||||
Interpolator i_color_r(fx1,fx2,fx3,fy1,fy2,fy3,r1,r2,r3);
|
||||
Interpolator i_color_g(fx1,fx2,fx3,fy1,fy2,fy3,g1,g2,g3);
|
||||
Interpolator i_color_b(fx1,fx2,fx3,fy1,fy2,fy3,b1,b2,b3);
|
||||
Interpolator i_tex_invu(fx1,fx2,fx3,fy1,fy2,fy3,u1,u2,u3);
|
||||
Interpolator i_tex_invv(fx1,fx2,fx3,fy1,fy2,fy3,v1,v2,v3);
|
||||
Interpolator i_z(fx1,fx2,fx3,fy1,fy2,fy3,fz1,fz2,fz3);
|
||||
Interpolator i_invw(fx1,fx2,fx3,fy1,fy2,fy3,1.0f/w1,1.0f/w2,1.0f/w3);
|
||||
|
||||
|
||||
i_color_r.init(minx,miny);
|
||||
i_color_g.init(minx,miny);
|
||||
i_color_b.init(minx,miny);
|
||||
i_tex_invu.init(minx,miny);
|
||||
i_tex_invv.init(minx,miny);
|
||||
i_z.init(minx,miny);
|
||||
i_invw.init(minx,miny);
|
||||
|
||||
for(int y = miny; y < maxy; y++)
|
||||
{
|
||||
int CX1 = CY1;
|
||||
int CX2 = CY2;
|
||||
int CX3 = CY3;
|
||||
|
||||
bool done = false;
|
||||
i_color_r.push(); i_color_g.push(); i_color_b.push();
|
||||
i_tex_invu.push(); i_tex_invv.push();
|
||||
i_invw.push(); i_z.push();
|
||||
|
||||
assert(y>=0 && y<192); //I dont think we need this bounds check, so it is only here as an assert
|
||||
int adr = (y<<8)+minx;
|
||||
|
||||
int xstart = -1, xend;
|
||||
|
||||
//determine the current scanline, which will be in xstart <= x < xend
|
||||
for(int x = minx; x < maxx; x++, adr++)
|
||||
{
|
||||
if(CX1 > 0 && CX2 > 0 && CX3 > 0)
|
||||
{
|
||||
xend = x;
|
||||
if(!done)
|
||||
xstart = x;
|
||||
done = true;
|
||||
|
||||
} else if(done) break;
|
||||
runscanline(&left,&right);
|
||||
|
||||
CX1 -= FDY12;
|
||||
CX2 -= FDY23;
|
||||
CX3 -= FDY31;
|
||||
if(right.Height == 0) {
|
||||
step_right = true;
|
||||
rv++;
|
||||
}
|
||||
if(left.Height == 0) {
|
||||
step_left = true;
|
||||
lv--;
|
||||
}
|
||||
|
||||
//---------
|
||||
//render the scanline
|
||||
if(xstart != -1)
|
||||
{
|
||||
//seed the interpolators with the distance to the start of this scanline
|
||||
//this is crappy and we need to redo it now that we've changing the main interpolation method to bilinear
|
||||
int xaccum = xstart-minx;
|
||||
i_color_r.incx(xaccum); i_color_g.incx(xaccum); i_color_b.incx(xaccum);
|
||||
i_tex_invu.incx(xaccum); i_tex_invv.incx(xaccum);
|
||||
i_invw.incx(xaccum); i_z.incx(xaccum);
|
||||
float rr = i_color_r.Z;
|
||||
float gg = i_color_g.Z;
|
||||
float bb = i_color_b.Z;
|
||||
float uu = i_tex_invu.Z;
|
||||
float vv = i_tex_invv.Z;
|
||||
float ww = i_invw.Z;
|
||||
float zz = i_z.Z;
|
||||
//now boost the interpolators to the end of this scanline
|
||||
i_color_r.pop();i_color_g.pop();i_color_b.pop();
|
||||
i_tex_invu.pop();i_tex_invv.pop();
|
||||
i_z.pop();i_invw.pop();
|
||||
xaccum = xend-minx;
|
||||
i_color_r.incx(xaccum); i_color_g.incx(xaccum); i_color_b.incx(xaccum);
|
||||
i_tex_invu.incx(xaccum); i_tex_invv.incx(xaccum);
|
||||
i_invw.incx(xaccum); i_z.incx(xaccum);
|
||||
scanline(y, xstart, xend, rr,gg,bb,uu,vv,ww,zz,i_color_r.Z, i_color_g.Z, i_color_b.Z, i_tex_invu.Z, i_tex_invv.Z, i_invw.Z, i_z.Z);
|
||||
}
|
||||
//----------
|
||||
//this is our completion condition: when our stepped edges meet in the middle
|
||||
if(lv<=rv+1) break;
|
||||
}
|
||||
|
||||
i_color_r.pop(); i_color_r.incy();
|
||||
i_color_g.pop(); i_color_g.incy();
|
||||
i_color_b.pop(); i_color_b.incy();
|
||||
i_tex_invu.pop(); i_tex_invu.incy();
|
||||
i_tex_invv.pop(); i_tex_invv.incy();
|
||||
i_z.pop(); i_z.incy();
|
||||
i_invw.pop(); i_invw.incy();
|
||||
|
||||
|
||||
CY1 += FDX12;
|
||||
CY2 += FDX23;
|
||||
CY3 += FDX31;
|
||||
|
||||
desty++;
|
||||
}
|
||||
}
|
||||
|
||||
static char SoftRastInit(void)
|
||||
|
@ -1344,6 +1152,7 @@ static void SoftRastRender()
|
|||
//this should be moved to gfx3d, but first we need to redo the way the lists are built
|
||||
//because it is too convoluted right now.
|
||||
//(must we throw out verts if a poly gets backface culled? if not, then it might be easier)
|
||||
//TODO - is this good enough for quads? we think so.
|
||||
float ab[2], ac[2];
|
||||
Vector2Copy(ab, verts[1]->coord);
|
||||
Vector2Copy(ac, verts[2]->coord);
|
||||
|
@ -1367,11 +1176,12 @@ static void SoftRastRender()
|
|||
needInitTexture = false;
|
||||
}
|
||||
|
||||
#ifdef USE_HECKER
|
||||
for(int i=0;i<type;i++)
|
||||
for(int j=0;j<2;j++)
|
||||
verts[i]->coord[j] = iround(16.0f * verts[i]->coord[j]);
|
||||
#endif
|
||||
//here is a hack which needs to be removed.
|
||||
//at some point our shape engine needs these to be converted to "fixed point"
|
||||
//which is currently just a float
|
||||
for(int i=0;i<type;i++)
|
||||
for(int j=0;j<2;j++)
|
||||
verts[i]->coord[j] = iround(16.0f * verts[i]->coord[j]);
|
||||
|
||||
//hmm... shader gets setup every time because it depends on sampler which may have just changed
|
||||
shader.setup(poly->polyAttr);
|
||||
|
@ -1383,44 +1193,39 @@ static void SoftRastRender()
|
|||
{
|
||||
if(backfacing)
|
||||
{
|
||||
SubmitVertex(0,verts[0]);
|
||||
SubmitVertex(1,verts[1]);
|
||||
SubmitVertex(2,verts[2]);
|
||||
triangle_from_devmaster();polynum++;
|
||||
|
||||
SubmitVertex(0,verts[2]);
|
||||
SubmitVertex(1,verts[3]);
|
||||
SubmitVertex(2,verts[0]);
|
||||
triangle_from_devmaster();polynum++;
|
||||
SubmitVertex(3,verts[0]);
|
||||
SubmitVertex(2,verts[1]);
|
||||
SubmitVertex(1,verts[2]);
|
||||
SubmitVertex(0,verts[3]);
|
||||
shape_engine();polynum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
SubmitVertex(0,verts[2]);
|
||||
SubmitVertex(1,verts[1]);
|
||||
SubmitVertex(2,verts[0]);
|
||||
triangle_from_devmaster();polynum++;
|
||||
|
||||
SubmitVertex(0,verts[0]);
|
||||
SubmitVertex(1,verts[3]);
|
||||
SubmitVertex(3,verts[3]);
|
||||
SubmitVertex(2,verts[2]);
|
||||
triangle_from_devmaster();polynum++;
|
||||
SubmitVertex(1,verts[1]);
|
||||
SubmitVertex(0,verts[0]);
|
||||
shape_engine();polynum++;
|
||||
|
||||
}
|
||||
}
|
||||
else if(type == 3)
|
||||
{
|
||||
if(backfacing)
|
||||
{
|
||||
SubmitVertex(0,verts[0]);
|
||||
SubmitVertex(3,verts[0]);
|
||||
SubmitVertex(2,verts[0]);
|
||||
SubmitVertex(1,verts[1]);
|
||||
SubmitVertex(2,verts[2]);
|
||||
triangle_from_devmaster();polynum++;
|
||||
SubmitVertex(0,verts[2]);
|
||||
shape_engine();polynum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
SubmitVertex(0,verts[2]);
|
||||
SubmitVertex(3,verts[2]);
|
||||
SubmitVertex(2,verts[2]);
|
||||
SubmitVertex(1,verts[1]);
|
||||
SubmitVertex(2,verts[0]);
|
||||
triangle_from_devmaster();polynum++;
|
||||
SubmitVertex(0,verts[0]);
|
||||
shape_engine();polynum++;
|
||||
}
|
||||
} else printf("skipping type %d\n",type);
|
||||
|
||||
|
|
Loading…
Reference in New Issue