\r
//! draws an indexed triangle list\r
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
-\r
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
\r
private:\r
- void scanline_bilinear ();\r
\r
+ // fragment shader\r
+ typedef void (CTRTextureGouraudNoZ2::* tFragmentShader) ();\r
+ void fragment_bilinear();\r
+ void fragment_no_filter();\r
+\r
+ tFragmentShader fragmentShader;\r
};\r
\r
//! constructor\r
#ifdef _DEBUG\r
setDebugName("CTRTextureGouraudNoZ2");\r
#endif\r
+\r
+ fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear;\r
}\r
\r
+/*!\r
+*/\r
+void CTRTextureGouraudNoZ2::OnSetMaterial(const SBurningShaderMaterial& material)\r
+{\r
+\r
+ if (material.org.TextureLayer[0].BilinearFilter ||\r
+ material.org.TextureLayer[0].TrilinearFilter ||\r
+ material.org.TextureLayer[0].AnisotropicFilter\r
+ )\r
+ {\r
+ fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear;\r
+ }\r
+ else\r
+ {\r
+ fragmentShader = &CTRTextureGouraudNoZ2::fragment_no_filter;\r
+ }\r
\r
+}\r
\r
/*!\r
*/\r
-void CTRTextureGouraudNoZ2::scanline_bilinear ( )\r
+void CTRTextureGouraudNoZ2::fragment_bilinear()\r
{\r
tVideoSample *dst;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
\r
#ifdef SUBTEXEL\r
- subPixel = ( (f32) xStart ) - line.x[0];\r
+ subPixel = ((f32) xStart) - line.x[0];\r
#ifdef IPOL_Z\r
line.z[0] += slopeZ * subPixel;\r
#endif\r
tFixPoint ty0;\r
tFixPoint r0, g0, b0;\r
\r
- for ( s32 i = 0; i <= dx; ++i )\r
+ for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)\r
{\r
#ifdef CMP_Z\r
if ( line.z[0] < z[i] )\r
#ifdef CMP_W\r
if ( line.w[0] >= z[i] )\r
#endif\r
-\r
+ scissor_test_x\r
{\r
#ifdef INVERSE_W\r
inversew = fix_inverse32 ( line.w[0] );\r
\r
}\r
\r
+/*!\r
+*/\r
+void CTRTextureGouraudNoZ2::fragment_no_filter()\r
+{\r
+ tVideoSample* dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+ fp24* z;\r
+#endif\r
+\r
+ s32 xStart;\r
+ s32 xEnd;\r
+ s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+ f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+ // apply top-left fill-convention, left\r
+ xStart = fill_convention_left(line.x[0]);\r
+ xEnd = fill_convention_right(line.x[1]);\r
+\r
+ dx = xEnd - xStart;\r
+ if (dx < 0)\r
+ return;\r
+\r
+ // slopes\r
+ const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+ slopeC = (line.c[1] - line.c[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0] += slopeC * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+ z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+ tFixPoint tx0;\r
+ tFixPoint ty0;\r
+ //tFixPoint r0, g0, b0;\r
+\r
+ for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)\r
+ {\r
+#ifdef CMP_Z\r
+ if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+ if (line.w[0] >= z[i])\r
+#endif\r
+ //scissor_test_x\r
+ {\r
+ #ifdef INVERSE_W\r
+ inversew = fix_inverse32(line.w[0]);\r
+ #endif\r
+ tx0 = tofix(line.t[0][0].x,inversew);\r
+ ty0 = tofix(line.t[0][0].y,inversew);\r
+ //skybox\r
+ dst[i] = getTexel_plain(&IT[0], tx0, ty0);\r
+\r
+ //getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 );\r
+ //dst[i] = fix_to_sample( r0, g0, b0 );\r
+\r
+ #ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+ #endif\r
+ #ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+ #endif\r
+ }\r
+\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1];\r
+#endif\r
+ }\r
+\r
+}\r
+\r
void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
const f32 ca = c->Pos.y - a->Pos.y;\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
+\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = reciprocal_zero( ca );\r
- scan.invDeltaY[1] = reciprocal_zero( ba );\r
- scan.invDeltaY[2] = reciprocal_zero( cb );\r
+ scan.invDeltaY[0] = fill_step_y( ca );\r
+ scan.invDeltaY[1] = fill_step_y( ba );\r
+ scan.invDeltaY[2] = fill_step_y( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// rasterize upper sub-triangle\r
- if ( (f32) 0.0 != scan.invDeltaY[1] )\r
+ if (F32_GREATER_0(scan.invDeltaY[1]) )\r
{\r
// calculate slopes for top edge\r
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
#endif\r
\r
// rasterize the edge scanlines\r
- for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+ for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)\r
{\r
line.x[scan.left] = scan.x[0];\r
line.x[scan.right] = scan.x[1];\r
line.t[1][scan.right] = scan.t[1][1];\r
#endif\r
\r
+\r
// render a scanline\r
- scanline_bilinear ( );\r
+ interlace_scanline\r
+ scissor_test_y\r
+ (this->*fragmentShader) ();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
}\r
\r
// rasterize lower sub-triangle\r
- if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+ if (F32_GREATER_0(scan.invDeltaY[2]) )\r
{\r
// advance to middle point\r
- if( (f32) 0.0 != scan.invDeltaY[1] )\r
+ if(F32_GREATER_0(scan.invDeltaY[1]) )\r
{\r
temp[0] = b->Pos.y - a->Pos.y; // dy\r
\r
#endif\r
\r
// rasterize the edge scanlines\r
- for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+ for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)\r
{\r
line.x[scan.left] = scan.x[0];\r
line.x[scan.right] = scan.x[1];\r
#endif\r
\r
// render a scanline\r
- scanline_bilinear ();\r
+ interlace_scanline\r
+ scissor_test_y\r
+ (this->*fragmentShader) ();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r