void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) { // sort on height, y if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); const f32 ca = c->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y; const f32 cb = c->Pos.y - b->Pos.y; // calculate delta y of the edges scan.invDeltaY[0] = core::reciprocal( ca ); scan.invDeltaY[1] = core::reciprocal( ba ); scan.invDeltaY[2] = core::reciprocal( cb ); if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) return; // find if the major edge is left or right aligned f32 temp[4]; temp[0] = a->Pos.x - c->Pos.x; temp[1] = -ca; temp[2] = b->Pos.x - a->Pos.x; temp[3] = ba; scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.right = 1 - scan.left; // calculate slopes for the major edge scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; scan.x[0] = a->Pos.x; #ifdef IPOL_Z scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; scan.z[0] = a->Pos.z; #endif #ifdef IPOL_W scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; scan.w[0] = a->Pos.w; #endif #ifdef IPOL_C0 scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; scan.c[0] = a->Color[0]; #endif #ifdef IPOL_T0 scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; scan.t[0][0] = a->Tex[0]; #endif #ifdef IPOL_T1 scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; scan.t[1][0] = a->Tex[1]; #endif // top left fill convention y run s32 yStart; s32 yEnd; #ifdef SUBTEXEL f32 subPixel; #endif // rasterize upper sub-triangle if ( (f32) 0.0 != scan.invDeltaY[1] ) { // calculate slopes for top edge scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; scan.x[1] = a->Pos.x; #ifdef IPOL_Z scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; scan.z[1] = a->Pos.z; #endif #ifdef IPOL_W scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; scan.w[1] = a->Pos.w; #endif #ifdef IPOL_C0 scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; scan.c[1] = a->Color[0]; #endif #ifdef IPOL_T0 scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; scan.t[0][1] = a->Tex[0]; #endif #ifdef IPOL_T1 scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; scan.t[1][1] = a->Tex[1]; #endif // apply top-left fill convention, top part yStart = core::ceil32( a->Pos.y ); yEnd = core::ceil32( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; // correct to pixel center scan.x[0] += scan.slopeX[0] * subPixel; scan.x[1] += scan.slopeX[1] * subPixel; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0] * subPixel; scan.z[1] += scan.slopeZ[1] * subPixel; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0] * subPixel; scan.w[1] += scan.slopeW[1] * subPixel; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0] * subPixel; scan.c[1] += scan.slopeC[1] * subPixel; #endif #ifdef IPOL_T0 scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel; #endif #ifdef IPOL_T1 scan.t[1][0] += scan.slopeT[1][0] * subPixel; scan.t[1][1] += scan.slopeT[1][1] * subPixel; #endif #endif // rasterize the edge scanlines for( line.y = yStart; line.y <= yEnd; ++line.y) { line.x[scan.left] = scan.x[0]; line.x[scan.right] = scan.x[1]; #ifdef IPOL_Z line.z[scan.left] = scan.z[0]; line.z[scan.right] = scan.z[1]; #endif #ifdef IPOL_W line.w[scan.left] = scan.w[0]; line.w[scan.right] = scan.w[1]; #endif #ifdef IPOL_C0 line.c[scan.left] = scan.c[0]; line.c[scan.right] = scan.c[1]; #endif #ifdef IPOL_T0 line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.right] = scan.t[0][1]; #endif #ifdef IPOL_T1 line.t[1][scan.left] = scan.t[1][0]; line.t[1][scan.right] = scan.t[1][1]; #endif // render a scanline scanline_bilinear (); scan.x[0] += scan.slopeX[0]; scan.x[1] += scan.slopeX[1]; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0]; scan.z[1] += scan.slopeZ[1]; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0]; scan.w[1] += scan.slopeW[1]; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0]; scan.c[1] += scan.slopeC[1]; #endif #ifdef IPOL_T0 scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][1] += scan.slopeT[0][1]; #endif #ifdef IPOL_T1 scan.t[1][0] += scan.slopeT[1][0]; scan.t[1][1] += scan.slopeT[1][1]; #endif } } // rasterize lower sub-triangle if ( (f32) 0.0 != scan.invDeltaY[2] ) { // advance to middle point if( (f32) 0.0 != scan.invDeltaY[1] ) { temp[0] = b->Pos.y - a->Pos.y; // dy scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; #ifdef IPOL_Z scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; #endif #ifdef IPOL_W scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; #endif #ifdef IPOL_C0 scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; #endif #ifdef IPOL_T0 scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; #endif #ifdef IPOL_T1 scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; #endif } // calculate slopes for bottom edge scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; scan.x[1] = b->Pos.x; #ifdef IPOL_Z scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; scan.z[1] = b->Pos.z; #endif #ifdef IPOL_W scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; scan.w[1] = b->Pos.w; #endif #ifdef IPOL_C0 scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; scan.c[1] = b->Color[0]; #endif #ifdef IPOL_T0 scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; scan.t[0][1] = b->Tex[0]; #endif #ifdef IPOL_T1 scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; scan.t[1][1] = b->Tex[1]; #endif // apply top-left fill convention, top part yStart = core::ceil32( b->Pos.y ); yEnd = core::ceil32( c->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - b->Pos.y; // correct to pixel center scan.x[0] += scan.slopeX[0] * subPixel; scan.x[1] += scan.slopeX[1] * subPixel; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0] * subPixel; scan.z[1] += scan.slopeZ[1] * subPixel; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0] * subPixel; scan.w[1] += scan.slopeW[1] * subPixel; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0] * subPixel; scan.c[1] += scan.slopeC[1] * subPixel; #endif #ifdef IPOL_T0 scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel; #endif #ifdef IPOL_T1 scan.t[1][0] += scan.slopeT[1][0] * subPixel; scan.t[1][1] += scan.slopeT[1][1] * subPixel; #endif #endif // rasterize the edge scanlines for( line.y = yStart; line.y <= yEnd; ++line.y) { line.x[scan.left] = scan.x[0]; line.x[scan.right] = scan.x[1]; #ifdef IPOL_Z line.z[scan.left] = scan.z[0]; line.z[scan.right] = scan.z[1]; #endif #ifdef IPOL_W line.w[scan.left] = scan.w[0]; line.w[scan.right] = scan.w[1]; #endif #ifdef IPOL_C0 line.c[scan.left] = scan.c[0]; line.c[scan.right] = scan.c[1]; #endif #ifdef IPOL_T0 line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.right] = scan.t[0][1]; #endif #ifdef IPOL_T1 line.t[1][scan.left] = scan.t[1][0]; line.t[1][scan.right] = scan.t[1][1]; #endif // render a scanline scanline_bilinear ( ); scan.x[0] += scan.slopeX[0]; scan.x[1] += scan.slopeX[1]; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0]; scan.z[1] += scan.slopeZ[1]; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0]; scan.w[1] += scan.slopeW[1]; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0]; scan.c[1] += scan.slopeC[1]; #endif #ifdef IPOL_T0 scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][1] += scan.slopeT[0][1]; #endif #ifdef IPOL_T1 scan.t[1][0] += scan.slopeT[1][0]; scan.t[1][1] += scan.slopeT[1][1]; #endif } } }
void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) { // sort on height, y if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); // calculate delta y of the edges scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) return; // find if the major edge is left or right aligned f32 temp[4]; temp[0] = a->Pos.x - c->Pos.x; temp[1] = a->Pos.y - c->Pos.y; temp[2] = b->Pos.x - a->Pos.x; temp[3] = b->Pos.y - a->Pos.y; scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; scan.right = 1 - scan.left; // calculate slopes for the major edge scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; scan.x[0] = a->Pos.x; #ifdef IPOL_Z scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; scan.z[0] = a->Pos.z; #endif #ifdef IPOL_W scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; scan.w[0] = a->Pos.w; #endif #ifdef IPOL_C0 scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; scan.c[0] = a->Color[0]; #endif #ifdef IPOL_T0 scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; scan.t0[0] = a->Tex[0]; #endif #ifdef IPOL_T1 scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; scan.t1[0] = a->Tex[1]; #endif // top left fill convention y run s32 yStart; s32 yEnd; #ifdef SUBTEXEL f32 subPixel; #endif // query access to TexMaps lockedSurface = (tVideoSample*)RenderTarget->lock(); #ifdef USE_ZBUFFER lockedZBuffer = ZBuffer->lock(); #endif #ifdef IPOL_T0 IT[0].data = (tVideoSample*)IT[0].Texture->lock(); #endif #ifdef IPOL_T1 IT[1].data = (tVideoSample*)IT[1].Texture->lock(); #endif // rasterize upper sub-triangle if ( (f32) 0.0 != scan.invDeltaY[1] ) { // calculate slopes for top edge scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; scan.x[1] = a->Pos.x; #ifdef IPOL_Z scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; scan.z[1] = a->Pos.z; #endif #ifdef IPOL_W scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; scan.w[1] = a->Pos.w; #endif #ifdef IPOL_C0 scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; scan.c[1] = a->Color[0]; #endif #ifdef IPOL_T0 scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; scan.t0[1] = a->Tex[0]; #endif #ifdef IPOL_T1 scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; scan.t1[1] = a->Tex[1]; #endif // apply top-left fill convention, top part yStart = core::ceil32( a->Pos.y ); yEnd = core::ceil32( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; // correct to pixel center scan.x[0] += scan.slopeX[0] * subPixel; scan.x[1] += scan.slopeX[1] * subPixel; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0] * subPixel; scan.z[1] += scan.slopeZ[1] * subPixel; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0] * subPixel; scan.w[1] += scan.slopeW[1] * subPixel; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0] * subPixel; scan.c[1] += scan.slopeC[1] * subPixel; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0] * subPixel; scan.t0[1] += scan.slopeT0[1] * subPixel; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0] * subPixel; scan.t1[1] += scan.slopeT1[1] * subPixel; #endif #endif // rasterize the edge scanlines for( line.y = yStart; line.y <= yEnd; ++line.y) { line.x[scan.left] = scan.x[0]; line.x[scan.right] = scan.x[1]; #ifdef IPOL_Z line.z[scan.left] = scan.z[0]; line.z[scan.right] = scan.z[1]; #endif #ifdef IPOL_W line.w[scan.left] = scan.w[0]; line.w[scan.right] = scan.w[1]; #endif #ifdef IPOL_C0 line.c[scan.left] = scan.c[0]; line.c[scan.right] = scan.c[1]; #endif #ifdef IPOL_T0 line.t0[scan.left] = scan.t0[0]; line.t0[scan.right] = scan.t0[1]; #endif #ifdef IPOL_T1 line.t1[scan.left] = scan.t1[0]; line.t1[scan.right] = scan.t1[1]; #endif // render a scanline scanline_bilinear (); scan.x[0] += scan.slopeX[0]; scan.x[1] += scan.slopeX[1]; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0]; scan.z[1] += scan.slopeZ[1]; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0]; scan.w[1] += scan.slopeW[1]; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0]; scan.c[1] += scan.slopeC[1]; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0]; scan.t0[1] += scan.slopeT0[1]; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0]; scan.t1[1] += scan.slopeT1[1]; #endif } } // rasterize lower sub-triangle if ( (f32) 0.0 != scan.invDeltaY[2] ) { // advance to middle point if( (f32) 0.0 != scan.invDeltaY[1] ) { temp[0] = b->Pos.y - a->Pos.y; // dy scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; #ifdef IPOL_Z scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; #endif #ifdef IPOL_W scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; #endif #ifdef IPOL_C0 scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; #endif #ifdef IPOL_T0 scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; #endif #ifdef IPOL_T1 scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; #endif } // calculate slopes for bottom edge scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; scan.x[1] = b->Pos.x; #ifdef IPOL_Z scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; scan.z[1] = b->Pos.z; #endif #ifdef IPOL_W scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; scan.w[1] = b->Pos.w; #endif #ifdef IPOL_C0 scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; scan.c[1] = b->Color[0]; #endif #ifdef IPOL_T0 scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; scan.t0[1] = b->Tex[0]; #endif #ifdef IPOL_T1 scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; scan.t1[1] = b->Tex[1]; #endif // apply top-left fill convention, top part yStart = core::ceil32( b->Pos.y ); yEnd = core::ceil32( c->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - b->Pos.y; // correct to pixel center scan.x[0] += scan.slopeX[0] * subPixel; scan.x[1] += scan.slopeX[1] * subPixel; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0] * subPixel; scan.z[1] += scan.slopeZ[1] * subPixel; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0] * subPixel; scan.w[1] += scan.slopeW[1] * subPixel; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0] * subPixel; scan.c[1] += scan.slopeC[1] * subPixel; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0] * subPixel; scan.t0[1] += scan.slopeT0[1] * subPixel; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0] * subPixel; scan.t1[1] += scan.slopeT1[1] * subPixel; #endif #endif // rasterize the edge scanlines for( line.y = yStart; line.y <= yEnd; ++line.y) { line.x[scan.left] = scan.x[0]; line.x[scan.right] = scan.x[1]; #ifdef IPOL_Z line.z[scan.left] = scan.z[0]; line.z[scan.right] = scan.z[1]; #endif #ifdef IPOL_W line.w[scan.left] = scan.w[0]; line.w[scan.right] = scan.w[1]; #endif #ifdef IPOL_C0 line.c[scan.left] = scan.c[0]; line.c[scan.right] = scan.c[1]; #endif #ifdef IPOL_T0 line.t0[scan.left] = scan.t0[0]; line.t0[scan.right] = scan.t0[1]; #endif #ifdef IPOL_T1 line.t1[scan.left] = scan.t1[0]; line.t1[scan.right] = scan.t1[1]; #endif // render a scanline scanline_bilinear (); scan.x[0] += scan.slopeX[0]; scan.x[1] += scan.slopeX[1]; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0]; scan.z[1] += scan.slopeZ[1]; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0]; scan.w[1] += scan.slopeW[1]; #endif #ifdef IPOL_C0 scan.c[0] += scan.slopeC[0]; scan.c[1] += scan.slopeC[1]; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0]; scan.t0[1] += scan.slopeT0[1]; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0]; scan.t1[1] += scan.slopeT1[1]; #endif } } RenderTarget->unlock(); #ifdef USE_ZBUFFER ZBuffer->unlock(); #endif #ifdef IPOL_T0 IT[0].Texture->unlock(); #endif #ifdef IPOL_T1 IT[1].Texture->unlock(); #endif }
void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) { sScanConvertData scan; sScanLineData line; // sort on height, y if ( a->Pos.y > b->Pos.y ) swapVertices(&a, &b); if ( a->Pos.y > c->Pos.y ) swapVertices(&a, &c); if ( b->Pos.y > c->Pos.y ) swapVertices(&b, &c); // calculate delta y of the edges scan.invDeltaY[0] = c->Pos.y - a->Pos.y; scan.invDeltaY[1] = b->Pos.y - a->Pos.y; scan.invDeltaY[2] = c->Pos.y - b->Pos.y; scan.invDeltaY[0] = inverse32 ( scan.invDeltaY[0] ); scan.invDeltaY[1] = inverse32 ( scan.invDeltaY[1] ); scan.invDeltaY[2] = inverse32 ( scan.invDeltaY[2] ); if ( (f32) 0.0 == scan.invDeltaY[0] ) return; // find if the major edge is left or right aligned f32 temp[4]; temp[0] = a->Pos.x - c->Pos.x; temp[1] = a->Pos.y - c->Pos.y; temp[2] = b->Pos.x - a->Pos.x; temp[3] = b->Pos.y - a->Pos.y; scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; scan.right = 1 - scan.left; // calculate slopes for the major edge scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; scan.x[0] = a->Pos.x; #ifdef IPOL_Z scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; scan.z[0] = a->Pos.z; #endif #ifdef IPOL_W scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; scan.w[0] = a->Pos.w; #endif #ifdef IPOL_C scan.slopeC[0] = (c->Color - a->Color) * scan.invDeltaY[0]; scan.c[0] = a->Color; #endif #ifdef IPOL_T0 scan.slopeT0[0] = (c->Tex0 - a->Tex0) * scan.invDeltaY[0]; scan.t0[0] = a->Tex0; #endif #ifdef IPOL_T1 scan.slopeT1[0] = (c->Tex1 - a->Tex1) * scan.invDeltaY[0]; scan.t1[0] = a->Tex1; #endif // top left fill convention y run s32 yStart; s32 yEnd; s32 y; #ifdef SUBTEXEL f32 subPixel; #endif lockedSurface = (tVideoSample*)RenderTarget->lock(); #ifdef IPOL_Z lockedZBuffer = ZBuffer->lock(); #endif #ifdef IPOL_T0 IT[0].data = (tVideoSample*)IT[0].Texture->lock(); #endif #ifdef IPOL_T1 IT[1].data = (tVideoSample*)IT[1].Texture->lock(); #endif // rasterize upper sub-triangle if ( (f32) 0.0 != scan.invDeltaY[1] ) { // calculate slopes for top edge scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; scan.x[1] = a->Pos.x; #ifdef IPOL_Z scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; scan.z[1] = a->Pos.z; #endif #ifdef IPOL_W scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; scan.w[1] = a->Pos.w; #endif #ifdef IPOL_C scan.slopeC[1] = (b->Color - a->Color) * scan.invDeltaY[1]; scan.c[1] = a->Color; #endif #ifdef IPOL_T0 scan.slopeT0[1] = (b->Tex0 - a->Tex0) * scan.invDeltaY[1]; scan.t0[1] = a->Tex0; #endif #ifdef IPOL_T1 scan.slopeT1[1] = (b->Tex1 - a->Tex1) * scan.invDeltaY[1]; scan.t1[1] = a->Tex1; #endif // apply top-left fill convention, top part yStart = ceil32( a->Pos.y ); yEnd = ceil32( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; // correct to pixel center scan.x[0] += scan.slopeX[0] * subPixel; scan.x[1] += scan.slopeX[1] * subPixel; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0] * subPixel; scan.z[1] += scan.slopeZ[1] * subPixel; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0] * subPixel; scan.w[1] += scan.slopeW[1] * subPixel; #endif #ifdef IPOL_C scan.c[0] += scan.slopeC[0] * subPixel; scan.c[1] += scan.slopeC[1] * subPixel; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0] * subPixel; scan.t0[1] += scan.slopeT0[1] * subPixel; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0] * subPixel; scan.t1[1] += scan.slopeT1[1] * subPixel; #endif #endif // rasterize the edge scanlines for( y = yStart; y <= yEnd; ++y) { line.y = y; line.x[scan.left] = scan.x[0]; line.x[scan.right] = scan.x[1]; #ifdef IPOL_Z line.z[scan.left] = scan.z[0]; line.z[scan.right] = scan.z[1]; #endif #ifdef IPOL_W line.w[scan.left] = scan.w[0]; line.w[scan.right] = scan.w[1]; #endif #ifdef IPOL_C line.c[scan.left] = scan.c[0]; line.c[scan.right] = scan.c[1]; #endif #ifdef IPOL_T0 line.t0[scan.left] = scan.t0[0]; line.t0[scan.right] = scan.t0[1]; #endif #ifdef IPOL_T1 line.t1[scan.left] = scan.t1[0]; line.t1[scan.right] = scan.t1[1]; #endif // render a scanline scanline_bilinear ( &line ); scan.x[0] += scan.slopeX[0]; scan.x[1] += scan.slopeX[1]; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0]; scan.z[1] += scan.slopeZ[1]; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0]; scan.w[1] += scan.slopeW[1]; #endif #ifdef IPOL_C scan.c[0] += scan.slopeC[0]; scan.c[1] += scan.slopeC[1]; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0]; scan.t0[1] += scan.slopeT0[1]; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0]; scan.t1[1] += scan.slopeT1[1]; #endif } } // rasterize lower sub-triangle if ( (f32) 0.0 != scan.invDeltaY[2] ) { // advance to middle point if( (f32) 0.0 != scan.invDeltaY[1] ) { temp[0] = b->Pos.y - a->Pos.y; // dy scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; #ifdef IPOL_Z scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; #endif #ifdef IPOL_W scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; #endif #ifdef IPOL_C scan.c[0] = a->Color + scan.slopeC[0] * temp[0]; #endif #ifdef IPOL_T0 scan.t0[0] = a->Tex0 + scan.slopeT0[0] * temp[0]; #endif #ifdef IPOL_T1 scan.t1[0] = a->Tex1 + scan.slopeT1[0] * temp[0]; #endif } // calculate slopes for bottom edge scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; scan.x[1] = b->Pos.x; #ifdef IPOL_Z scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; scan.z[1] = b->Pos.z; #endif #ifdef IPOL_W scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; scan.w[1] = b->Pos.w; #endif #ifdef IPOL_C scan.slopeC[1] = (c->Color - b->Color) * scan.invDeltaY[2]; scan.c[1] = b->Color; #endif #ifdef IPOL_T0 scan.slopeT0[1] = (c->Tex0 - b->Tex0) * scan.invDeltaY[2]; scan.t0[1] = b->Tex0; #endif #ifdef IPOL_T1 scan.slopeT1[1] = (c->Tex1 - b->Tex1) * scan.invDeltaY[2]; scan.t1[1] = b->Tex1; #endif // apply top-left fill convention, top part yStart = ceil32( b->Pos.y ); yEnd = ceil32( c->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - b->Pos.y; // correct to pixel center scan.x[0] += scan.slopeX[0] * subPixel; scan.x[1] += scan.slopeX[1] * subPixel; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0] * subPixel; scan.z[1] += scan.slopeZ[1] * subPixel; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0] * subPixel; scan.w[1] += scan.slopeW[1] * subPixel; #endif #ifdef IPOL_C scan.c[0] += scan.slopeC[0] * subPixel; scan.c[1] += scan.slopeC[1] * subPixel; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0] * subPixel; scan.t0[1] += scan.slopeT0[1] * subPixel; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0] * subPixel; scan.t1[1] += scan.slopeT1[1] * subPixel; #endif #endif // rasterize the edge scanlines for( y = yStart; y <= yEnd; ++y) { line.y = y; line.x[scan.left] = scan.x[0]; line.x[scan.right] = scan.x[1]; #ifdef IPOL_Z line.z[scan.left] = scan.z[0]; line.z[scan.right] = scan.z[1]; #endif #ifdef IPOL_W line.w[scan.left] = scan.w[0]; line.w[scan.right] = scan.w[1]; #endif #ifdef IPOL_C line.c[scan.left] = scan.c[0]; line.c[scan.right] = scan.c[1]; #endif #ifdef IPOL_T0 line.t0[scan.left] = scan.t0[0]; line.t0[scan.right] = scan.t0[1]; #endif #ifdef IPOL_T1 line.t1[scan.left] = scan.t1[0]; line.t1[scan.right] = scan.t1[1]; #endif // render a scanline scanline_bilinear ( &line ); scan.x[0] += scan.slopeX[0]; scan.x[1] += scan.slopeX[1]; #ifdef IPOL_Z scan.z[0] += scan.slopeZ[0]; scan.z[1] += scan.slopeZ[1]; #endif #ifdef IPOL_W scan.w[0] += scan.slopeW[0]; scan.w[1] += scan.slopeW[1]; #endif #ifdef IPOL_C scan.c[0] += scan.slopeC[0]; scan.c[1] += scan.slopeC[1]; #endif #ifdef IPOL_T0 scan.t0[0] += scan.slopeT0[0]; scan.t0[1] += scan.slopeT0[1]; #endif #ifdef IPOL_T1 scan.t1[0] += scan.slopeT1[0]; scan.t1[1] += scan.slopeT1[1]; #endif } } RenderTarget->unlock(); #ifdef IPOL_Z ZBuffer->unlock(); #endif #ifdef IPOL_T0 IT[0].Texture->unlock(); #endif #ifdef IPOL_T1 IT[1].Texture->unlock(); #endif }