void SoftwareRasterizer::draw(const F32* verts, U vertCount, U stride, Bool backfaceCulling) { ANKI_ASSERT(verts && vertCount > 0 && (vertCount % 3) == 0); ANKI_ASSERT(stride >= sizeof(F32) * 3 && (stride % sizeof(F32)) == 0); U floatStride = stride / sizeof(F32); const F32* vertsEnd = verts + vertCount * floatStride; while(verts != vertsEnd) { // Convert triangle to view space Array<Vec4, 3> triVspace; for(U j = 0; j < 3; ++j) { triVspace[j] = m_mv * Vec4(verts[0], verts[1], verts[2], 1.0); verts += floatStride; } // Cull if backfacing if(backfaceCulling) { Vec4 norm = (triVspace[1] - triVspace[0]).cross(triVspace[2] - triVspace[1]); ANKI_ASSERT(norm.w() == 0.0f); Vec4 eye = triVspace[0].xyz0(); if(norm.dot(eye) >= 0.0f) { continue; } } // Clip it Array<Vec4, 6> clippedTrisVspace; U clippedCount = 0; clipTriangle(&triVspace[0], &clippedTrisVspace[0], clippedCount); if(clippedCount == 0) { // Outside view continue; } // Rasterize Array<Vec4, 3> clip; for(U j = 0; j < clippedCount; j += 3) { for(U k = 0; k < 3; k++) { clip[k] = m_p * clippedTrisVspace[j + k].xyz1(); ANKI_ASSERT(clip[k].w() > 0.0f); } rasterizeTriangle(&clip[0]); } } }
static void clip(double x1,double y1,double z1,double u1,double v1,double w1, double x2,double y2,double z2,double u2,double v2,double w2, double x3,double y3,double z3,double u3,double v3,double w3) { //TODO: FIX CLIPPING ERROR int w1N = w1 < pseudoNear, w2N = w2 < pseudoNear, w3N = w3 < pseudoNear; if(w1N && !w2N && !w3N) { clipQuad(x1,y1,z1,u1,v1,w1, x2,y2,z2,u2,v2,w2, x3,y3,z3,u3,v3,w3); } else if(!w1N && w2N && !w3N) { clipQuad(x2,y2,z2,u2,v2,w2, x3,y3,z3,u3,v3,w3, x1,y1,z1,u1,v1,w1); } else if(!w1N && !w2N && w3N) { clipQuad(x3,y3,z3,u3,v3,w3, x1,y1,z1,u1,v1,w1, x2,y2,z2,u2,v2,w2); } else if(!w1N) { clipTriangle(x1,y1,z1,u1,v1,w1, x2,y2,z2,u2,v2,w2, x3,y3,z3,u3,v3,w3); } else if(!w2N) { clipTriangle(x2,y2,z2,u2,v2,w2, x3,y3,z3,u3,v3,w3, x1,y1,z1,u1,v1,w1); } else if(!w3N) { clipTriangle(x3,y3,z3,u3,v3,w3, x1,y1,z1,u1,v1,w1, x2,y2,z2,u2,v2,w2); } }