1 // Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #include "IrrCompileConfig.h"
\r
6 #include "IBurningShader.h"
\r
8 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
\r
10 // compile flag for this file
\r
27 // define render case
\r
40 // apply global override
\r
41 #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
\r
45 #ifndef SOFTWARE_DRIVER_2_SUBTEXEL
\r
49 #if BURNING_MATERIAL_MAX_COLORS < 1
\r
53 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
\r
54 #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
\r
79 class CTRTextureBlend : public IBurningShader
\r
84 CTRTextureBlend(CBurningVideoDriver* driver);
\r
86 //! draws an indexed triangle list
\r
87 virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
\r
88 virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
\r
92 typedef void (CTRTextureBlend::*tFragmentShader) ();
\r
93 void fragment_dst_color_zero ();
\r
94 void fragment_dst_color_one ();
\r
95 void fragment_dst_color_src_alpha ();
\r
96 void fragment_dst_color_one_minus_dst_alpha ();
\r
97 void fragment_zero_one_minus_scr_color ();
\r
98 void fragment_src_color_src_alpha ();
\r
99 void fragment_one_one_minus_src_alpha ();
\r
100 void fragment_one_minus_dst_alpha_one();
\r
101 void fragment_src_alpha_one();
\r
102 void fragment_src_alpha_one_minus_src_alpha();
\r
104 tFragmentShader fragmentShader;
\r
106 E_COMPARISON_FUNC depth_func;
\r
110 CTRTextureBlend::CTRTextureBlend(CBurningVideoDriver* driver)
\r
111 : IBurningShader(driver)
\r
114 setDebugName("CTRTextureBlend");
\r
117 depth_func = ECFN_LESSEQUAL;
\r
118 fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;
\r
123 void CTRTextureBlend::OnSetMaterial(const SBurningShaderMaterial& material)
\r
127 depth_func = (E_COMPARISON_FUNC)material.org.ZBuffer;
\r
128 AlphaRef = 0; // tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
\r
130 E_BLEND_FACTOR srcFact,dstFact;
\r
131 E_MODULATE_FUNC modulate;
\r
133 unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, material.org.MaterialTypeParam);
\r
135 fragmentShader = 0;
\r
137 if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ZERO )
\r
139 fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;
\r
141 else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE )
\r
143 fragmentShader = &CTRTextureBlend::fragment_dst_color_one;
\r
145 else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA)
\r
147 fragmentShader = &CTRTextureBlend::fragment_dst_color_src_alpha;
\r
149 else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA)
\r
151 fragmentShader = &CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha;
\r
153 else if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR )
\r
155 fragmentShader = &CTRTextureBlend::fragment_zero_one_minus_scr_color;
\r
157 else if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA)
\r
159 fragmentShader = &CTRTextureBlend::fragment_one_one_minus_src_alpha;
\r
161 else if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE )
\r
163 fragmentShader = &CTRTextureBlend::fragment_one_minus_dst_alpha_one;
\r
165 else if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE )
\r
167 fragmentShader = &CTRTextureBlend::fragment_src_alpha_one;
\r
169 else if (srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE_MINUS_SRC_ALPHA)
\r
171 fragmentShader = &CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha;
\r
173 else if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA )
\r
175 fragmentShader = &CTRTextureBlend::fragment_src_color_src_alpha;
\r
180 fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;
\r
183 static const c8 *n[] =
\r
188 "gl_one_minus_dst_color",
\r
190 "gl_one_minus_src_color",
\r
192 "gl_one_minus_src_alpha",
\r
194 "gl_one_minus_dst_alpha",
\r
195 "gl_src_alpha_saturate"
\r
198 static E_BLEND_FACTOR lsrcFact = EBF_ZERO;
\r
199 static E_BLEND_FACTOR ldstFact = EBF_ZERO;
\r
201 if ( showname && ( lsrcFact != srcFact || ldstFact != dstFact ) )
\r
204 snprintf_irr ( buf, 128, "missing shader: %s %s",n[srcFact], n[dstFact] );
\r
205 os::Printer::log( buf, ELL_WARNING);
\r
207 lsrcFact = srcFact;
\r
208 ldstFact = dstFact;
\r
216 void CTRTextureBlend::fragment_dst_color_src_alpha ()
\r
240 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
243 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
246 // apply top-left fill-convention, left
\r
247 xStart = fill_convention_left( line.x[0] );
\r
248 xEnd = fill_convention_right( line.x[1] );
\r
250 dx = xEnd - xStart;
\r
256 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
259 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
262 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
265 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
268 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
271 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
275 subPixel = ( (f32) xStart ) - line.x[0];
\r
277 line.z[0] += slopeZ * subPixel;
\r
280 line.w[0] += slopeW * subPixel;
\r
283 line.c[0][0] += slopeC[0] * subPixel;
\r
286 line.t[0][0] += slopeT[0] * subPixel;
\r
289 line.t[1][0] += slopeT[1] * subPixel;
\r
293 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
294 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
297 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
301 f32 iw = FIX_POINT_F32_MUL;
\r
303 tFixPoint a0, r0, g0, b0;
\r
304 tFixPoint r1, g1, b1;
\r
308 switch (depth_func)
\r
311 case ECFN_LESSEQUAL:
\r
312 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
315 if ( line.w[0] >= z[i] )
\r
325 iw = fix_inverse32 ( line.w[0] );
\r
328 getSample_texture ( a0,r0,g0,b0,
\r
330 tofix(line.t[0][0].x, iw),
\r
331 tofix(line.t[0][0].y, iw)
\r
334 color_to_fix ( r1, g1, b1, dst[i] );
\r
336 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
\r
337 clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
\r
338 clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
\r
343 line.w[0] += slopeW;
\r
346 line.t[0][0] += slopeT[0];
\r
349 line.c[0][0] += slopeC[0];
\r
355 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
358 if ( line.w[0] == z[i] )
\r
368 iw = fix_inverse32 ( line.w[0] );
\r
371 getSample_texture ( a0,r0,g0,b0,
\r
373 tofix ( line.t[0][0].x,iw),
\r
374 tofix ( line.t[0][0].y,iw)
\r
377 color_to_fix ( r1, g1, b1, dst[i] );
\r
379 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
\r
380 clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
\r
381 clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
\r
387 line.w[0] += slopeW;
\r
390 line.t[0][0] += slopeT[0];
\r
393 line.c[0][0] += slopeC[0];
\r
402 void CTRTextureBlend::fragment_src_color_src_alpha ()
\r
426 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
429 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
432 // apply top-left fill-convention, left
\r
433 xStart = fill_convention_left( line.x[0] );
\r
434 xEnd = fill_convention_right( line.x[1] );
\r
436 dx = xEnd - xStart;
\r
441 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
444 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
447 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
450 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
453 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
456 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
460 subPixel = ( (f32) xStart ) - line.x[0];
\r
462 line.z[0] += slopeZ * subPixel;
\r
465 line.w[0] += slopeW * subPixel;
\r
468 line.c[0][0] += slopeC[0] * subPixel;
\r
471 line.t[0][0] += slopeT[0] * subPixel;
\r
474 line.t[1][0] += slopeT[1] * subPixel;
\r
478 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
479 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
482 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
486 f32 iw = FIX_POINT_F32_MUL;
\r
488 tFixPoint a0, r0, g0, b0;
\r
489 tFixPoint r1, g1, b1;
\r
492 tFixPoint a2,r2, g2, b2;
\r
497 switch (depth_func)
\r
500 case ECFN_LESSEQUAL:
\r
501 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
504 if ( line.w[0] >= z[i] )
\r
508 //solves example 08. todo: depth_write.
\r
510 //z[i] = line.w[0];
\r
514 iw = fix_inverse32 ( line.w[0] );
\r
517 getSample_texture ( a0, r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,iw), tofix ( line.t[0][0].y,iw) );
\r
520 vec4_to_fix(a2,r2, g2, b2, line.c[0][0], iw);
\r
521 //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?
\r
522 r0 = imulFix_simple(r0, r2);
\r
523 g0 = imulFix_simple(g0, g2);
\r
524 b0 = imulFix_simple(b0, b2);
\r
527 color_to_fix ( r1, g1, b1, dst[i] );
\r
528 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1( r0, r0 ) + imulFix_tex1( r1, a0 ) ),
\r
529 clampfix_maxcolor ( imulFix_tex1( g0, g0 ) + imulFix_tex1( g1, a0 ) ),
\r
530 clampfix_maxcolor ( imulFix_tex1( b0, b0 ) + imulFix_tex1( b1, a0 ) )
\r
536 line.w[0] += slopeW;
\r
539 line.t[0][0] += slopeT[0];
\r
542 line.c[0][0] += slopeC[0];
\r
548 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
551 if ( line.w[0] == z[i] )
\r
561 iw = fix_inverse32 ( line.w[0] );
\r
564 getSample_texture ( a0,r0,g0,b0,
\r
566 tofix ( line.t[0][0].x,iw),
\r
567 tofix ( line.t[0][0].y,iw)
\r
570 color_to_fix ( r1, g1, b1, dst[i] );
\r
572 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
\r
573 clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
\r
574 clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
\r
580 line.w[0] += slopeW;
\r
583 line.t[0][0] += slopeT[0];
\r
586 line.c[0][0] += slopeC[0];
\r
596 void CTRTextureBlend::fragment_one_one_minus_src_alpha()
\r
620 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
623 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
626 // apply top-left fill-convention, left
\r
627 xStart = fill_convention_left( line.x[0] );
\r
628 xEnd = fill_convention_right( line.x[1] );
\r
630 dx = xEnd - xStart;
\r
636 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
639 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
642 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
645 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
648 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
651 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
655 subPixel = ( (f32) xStart ) - line.x[0];
\r
657 line.z[0] += slopeZ * subPixel;
\r
660 line.w[0] += slopeW * subPixel;
\r
663 line.c[0][0] += slopeC[0] * subPixel;
\r
666 line.t[0][0] += slopeT[0] * subPixel;
\r
669 line.t[1][0] += slopeT[1] * subPixel;
\r
673 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
674 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
677 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
681 f32 iw = FIX_POINT_F32_MUL;
\r
683 tFixPoint a0,r0, g0, b0;
\r
684 tFixPoint r1, g1, b1;
\r
686 tFixPoint r2, g2, b2;
\r
690 switch (depth_func)
\r
693 case ECFN_LESSEQUAL:
\r
694 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
697 if ( line.w[0] >= z[i] )
\r
707 iw = fix_inverse32 ( line.w[0] );
\r
710 getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
711 a0 = FIX_POINT_ONE - a0;
\r
713 color_to_fix1 ( r1, g1, b1, dst[i] );
\r
715 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
717 dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),
\r
718 imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),
\r
719 imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )
\r
722 dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),
\r
723 g0 + imulFix_simple( g1, a0 ),
\r
724 b0 + imulFix_simple( b1, a0 )
\r
732 line.w[0] += slopeW;
\r
735 line.t[0][0] += slopeT[0];
\r
738 line.c[0][0] += slopeC[0];
\r
744 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
747 if ( line.w[0] == z[i] )
\r
757 iw = fix_inverse32 ( line.w[0] );
\r
759 getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
760 a0 = FIX_POINT_ONE - a0;
\r
762 color_to_fix1 ( r1, g1, b1, dst[i] );
\r
764 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
766 dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),
\r
767 imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),
\r
768 imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )
\r
771 dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),
\r
772 g0 + imulFix_simple( g1, a0 ),
\r
773 b0 + imulFix_simple( b1, a0 )
\r
781 line.w[0] += slopeW;
\r
784 line.t[0][0] += slopeT[0];
\r
787 line.c[0][0] += slopeC[0];
\r
797 void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
\r
821 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
824 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
827 // apply top-left fill-convention, left
\r
828 xStart = fill_convention_left( line.x[0] );
\r
829 xEnd = fill_convention_right( line.x[1] );
\r
831 dx = xEnd - xStart;
\r
837 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
840 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
843 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
846 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
849 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
852 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
856 subPixel = ( (f32) xStart ) - line.x[0];
\r
858 line.z[0] += slopeZ * subPixel;
\r
861 line.w[0] += slopeW * subPixel;
\r
864 line.c[0][0] += slopeC[0] * subPixel;
\r
867 line.t[0][0] += slopeT[0] * subPixel;
\r
870 line.t[1][0] += slopeT[1] * subPixel;
\r
874 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
875 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
878 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
882 f32 iw = FIX_POINT_F32_MUL;
\r
884 tFixPoint r0, g0, b0;
\r
885 tFixPoint a1, r1, g1, b1;
\r
887 tFixPoint r2, g2, b2;
\r
891 switch (depth_func)
\r
894 case ECFN_LESSEQUAL:
\r
895 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
898 if ( line.w[0] >= z[i] )
\r
908 iw = fix_inverse32 ( line.w[0] );
\r
911 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
912 color_to_fix1 ( a1, r1, g1, b1, dst[i] );
\r
914 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
916 a1 = FIX_POINT_ONE - a1;
\r
917 dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),
\r
918 imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),
\r
919 imulFix (imulFix_simple( b0, a1 ) + b1, b2 )
\r
922 dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,
\r
923 imulFix_simple( g0, a1) + g0,
\r
924 imulFix_simple( b0, a1) + b0
\r
932 line.w[0] += slopeW;
\r
935 line.t[0][0] += slopeT[0];
\r
938 line.c[0][0] += slopeC[0];
\r
944 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
947 if ( line.w[0] == z[i] )
\r
957 iw = fix_inverse32 ( line.w[0] );
\r
959 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
960 color_to_fix1 ( a1, r1, g1, b1, dst[i] );
\r
963 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
965 a1 = FIX_POINT_ONE - a1;
\r
966 dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),
\r
967 imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),
\r
968 imulFix (imulFix_simple( b0, a1 ) + b1, b2 )
\r
971 dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,
\r
972 imulFix_simple( g0, a1) + g0,
\r
973 imulFix_simple( b0, a1) + b0
\r
981 line.w[0] += slopeW;
\r
984 line.t[0][0] += slopeT[0];
\r
987 line.c[0][0] += slopeC[0];
\r
997 void CTRTextureBlend::fragment_src_alpha_one ()
\r
1001 #ifdef USE_ZBUFFER
\r
1021 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
1024 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
1027 // apply top-left fill-convention, left
\r
1028 xStart = fill_convention_left( line.x[0] );
\r
1029 xEnd = fill_convention_right( line.x[1] );
\r
1031 dx = xEnd - xStart;
\r
1037 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
1040 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
1043 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
1046 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
1049 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
1052 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
1056 subPixel = ( (f32) xStart ) - line.x[0];
\r
1058 line.z[0] += slopeZ * subPixel;
\r
1061 line.w[0] += slopeW * subPixel;
\r
1064 line.c[0][0] += slopeC[0] * subPixel;
\r
1067 line.t[0][0] += slopeT[0] * subPixel;
\r
1070 line.t[1][0] += slopeT[1] * subPixel;
\r
1074 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
1075 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1077 #ifdef USE_ZBUFFER
\r
1078 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1082 f32 iw = FIX_POINT_F32_MUL;
\r
1084 tFixPoint a0, r0, g0, b0;
\r
1085 tFixPoint r1, g1, b1;
\r
1087 tFixPoint r2, g2, b2;
\r
1091 switch (depth_func)
\r
1094 case ECFN_LESSEQUAL:
\r
1095 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1098 if ( line.w[0] >= z[i] )
\r
1105 iw = fix_inverse32 ( line.w[0] );
\r
1108 getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1111 fix_color_norm(a0);
\r
1113 color_to_fix ( r1, g1, b1, dst[i] );
\r
1116 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1118 dst[i] = fix4_to_sample( a0,
\r
1119 clampfix_maxcolor (imulFix_simple(r0,a0) + r1),
\r
1120 clampfix_maxcolor (imulFix_simple(g0,a0) + g1),
\r
1121 clampfix_maxcolor (imulFix_simple(b0,a0) + b1)
\r
1125 fix_color_norm(a0);
\r
1126 dst[i] = fix4_to_sample ( a0,
\r
1127 imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),
\r
1128 imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),
\r
1129 imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )
\r
1133 dst[i] = fix4_to_sample( a0,
\r
1134 clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),
\r
1135 clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),
\r
1136 clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )
\r
1142 //z[i] = line.w[0];
\r
1149 line.w[0] += slopeW;
\r
1152 line.t[0][0] += slopeT[0];
\r
1155 line.c[0][0] += slopeC[0];
\r
1161 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1164 if ( line.w[0] == z[i] )
\r
1169 iw = fix_inverse32 ( line.w[0] );
\r
1172 getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1175 fix_color_norm(a0);
\r
1177 color_to_fix ( r1, g1, b1, dst[i] );
\r
1180 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1182 dst[i] = fix4_to_sample( a0,
\r
1183 clampfix_maxcolor ( imulFix (imulFix_simple(r0,a0 ) + r1, r2 ) ),
\r
1184 clampfix_maxcolor ( imulFix (imulFix_simple(g0,a0 ) + g1, g2 ) ),
\r
1185 clampfix_maxcolor ( imulFix (imulFix_simple(b0,a0 ) + b1, b2 ) )
\r
1189 fix_color_norm(a0);
\r
1190 dst[i] = fix4_to_sample ( a0,
\r
1191 imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),
\r
1192 imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),
\r
1193 imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )
\r
1197 dst[i] = fix4_to_sample( a0,
\r
1198 clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),
\r
1199 clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),
\r
1200 clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )
\r
1211 line.w[0] += slopeW;
\r
1214 line.t[0][0] += slopeT[0];
\r
1217 line.c[0][0] += slopeC[0];
\r
1228 void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()
\r
1230 tVideoSample *dst;
\r
1232 #ifdef USE_ZBUFFER
\r
1252 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
1255 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
1258 // apply top-left fill-convention, left
\r
1259 xStart = fill_convention_left(line.x[0]);
\r
1260 xEnd = fill_convention_right(line.x[1]);
\r
1262 dx = xEnd - xStart;
\r
1267 const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
\r
1270 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
1273 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
1276 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
1279 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
1282 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
1286 subPixel = ((f32)xStart) - line.x[0];
\r
1288 line.z[0] += slopeZ * subPixel;
\r
1291 line.w[0] += slopeW * subPixel;
\r
1294 line.c[0][0] += slopeC[0] * subPixel;
\r
1297 line.t[0][0] += slopeT[0] * subPixel;
\r
1300 line.t[1][0] += slopeT[1] * subPixel;
\r
1304 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
1305 dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
\r
1307 #ifdef USE_ZBUFFER
\r
1308 z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
\r
1312 f32 iw = FIX_POINT_F32_MUL;
\r
1314 tFixPoint a0, r0, g0, b0;
\r
1315 tFixPoint r1, g1, b1;
\r
1316 tFixPoint a2, r2, g2, b2;
\r
1320 switch (depth_func)
\r
1323 case ECFN_LESSEQUAL:
\r
1324 for (i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1327 if (line.w[0] >= z[i])
\r
1332 //z[i] = line.w[0];
\r
1336 iw = fix_inverse32(line.w[0]);
\r
1339 getSample_texture(a0, r0, g0, b0, &IT[0], tofix(line.t[0][0].x, iw), tofix(line.t[0][0].y, iw));
\r
1340 if (a0 > AlphaRef)
\r
1343 vec4_to_fix(a2, r2, g2, b2, line.c[0][0], iw);
\r
1344 //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?
\r
1345 r0 = imulFix_simple(r0, r2);
\r
1346 g0 = imulFix_simple(g0, g2);
\r
1347 b0 = imulFix_simple(b0, b2);
\r
1350 color_to_fix(r1, g1, b1, dst[i]);
\r
1352 fix_color_norm(a0);
\r
1354 r2 = r1 + imulFix(a0, r0 - r1);
\r
1355 g2 = g1 + imulFix(a0, g0 - g1);
\r
1356 b2 = b1 + imulFix(a0, b0 - b1);
\r
1357 dst[i] = fix4_to_sample(a0, r2, g2, b2);
\r
1363 line.w[0] += slopeW;
\r
1366 line.t[0][0] += slopeT[0];
\r
1369 line.c[0][0] += slopeC[0];
\r
1381 void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
\r
1383 tVideoSample *dst;
\r
1385 #ifdef USE_ZBUFFER
\r
1405 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
1408 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
1411 // apply top-left fill-convention, left
\r
1412 xStart = fill_convention_left( line.x[0] );
\r
1413 xEnd = fill_convention_right( line.x[1] );
\r
1415 dx = xEnd - xStart;
\r
1421 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
1424 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
1427 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
1430 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
1433 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
1436 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
1440 subPixel = ( (f32) xStart ) - line.x[0];
\r
1442 line.z[0] += slopeZ * subPixel;
\r
1445 line.w[0] += slopeW * subPixel;
\r
1448 line.c[0][0] += slopeC[0] * subPixel;
\r
1451 line.t[0][0] += slopeT[0] * subPixel;
\r
1454 line.t[1][0] += slopeT[1] * subPixel;
\r
1458 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
1459 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1461 #ifdef USE_ZBUFFER
\r
1462 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1466 f32 iw = FIX_POINT_F32_MUL;
\r
1468 tFixPoint r0, g0, b0;
\r
1469 tFixPoint a1, r1, g1, b1;
\r
1471 tFixPoint r2, g2, b2;
\r
1475 switch (depth_func)
\r
1478 case ECFN_LESSEQUAL:
\r
1479 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1482 if ( line.w[0] >= z[i] )
\r
1492 iw = fix_inverse32 ( line.w[0] );
\r
1495 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1496 color_to_fix1 ( a1, r1, g1, b1, dst[i] );
\r
1498 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1500 a1 = FIX_POINT_ONE - a1;
\r
1501 dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),
\r
1502 imulFix ( imulFix ( g1, g0 + a1 ), g2 ),
\r
1503 imulFix ( imulFix ( b1, b0 + a1 ), b2 )
\r
1506 dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),
\r
1507 imulFix ( g1, g0 + a1 ),
\r
1508 imulFix ( b1, b0 + a1 )
\r
1516 line.w[0] += slopeW;
\r
1519 line.t[0][0] += slopeT[0];
\r
1522 line.c[0][0] += slopeC[0];
\r
1528 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1531 if ( line.w[0] == z[i] )
\r
1541 iw = fix_inverse32 ( line.w[0] );
\r
1543 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1544 color_to_fix1 ( a1, r1, g1, b1, dst[i] );
\r
1547 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1549 a1 = FIX_POINT_ONE - a1;
\r
1550 dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),
\r
1551 imulFix ( imulFix ( g1, g0 + a1 ), g2 ),
\r
1552 imulFix ( imulFix ( b1, b0 + a1 ), b2 )
\r
1555 dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),
\r
1556 imulFix ( g1, g0 + a1 ),
\r
1557 imulFix ( b1, b0 + a1 )
\r
1565 line.w[0] += slopeW;
\r
1568 line.t[0][0] += slopeT[0];
\r
1571 line.c[0][0] += slopeC[0];
\r
1580 void CTRTextureBlend::fragment_dst_color_zero ()
\r
1582 tVideoSample *dst;
\r
1584 #ifdef USE_ZBUFFER
\r
1604 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
1607 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
1610 // apply top-left fill-convention, left
\r
1611 xStart = fill_convention_left( line.x[0] );
\r
1612 xEnd = fill_convention_right( line.x[1] );
\r
1614 dx = xEnd - xStart;
\r
1620 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
1623 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
1626 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
1629 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
1632 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
1635 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
1639 subPixel = ( (f32) xStart ) - line.x[0];
\r
1641 line.z[0] += slopeZ * subPixel;
\r
1644 line.w[0] += slopeW * subPixel;
\r
1647 line.c[0][0] += slopeC[0] * subPixel;
\r
1650 line.t[0][0] += slopeT[0] * subPixel;
\r
1653 line.t[1][0] += slopeT[1] * subPixel;
\r
1657 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
1658 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1660 #ifdef USE_ZBUFFER
\r
1661 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1665 f32 iw = FIX_POINT_F32_MUL;
\r
1667 tFixPoint r0, g0, b0;
\r
1668 tFixPoint r1, g1, b1;
\r
1670 tFixPoint r2, g2, b2;
\r
1674 switch (depth_func)
\r
1677 case ECFN_LESSEQUAL:
\r
1678 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1681 if ( line.w[0] >= z[i] )
\r
1691 iw = fix_inverse32 ( line.w[0] );
\r
1694 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1695 color_to_fix1 ( r1, g1, b1, dst[i] );
\r
1698 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1700 dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),
\r
1701 imulFix (imulFix_simple( g0, g1 ), g2 ),
\r
1702 imulFix (imulFix_simple( b0, b1 ), b2 ) );
\r
1704 dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),
\r
1705 imulFix_simple( g0, g1 ),
\r
1706 imulFix_simple( b0, b1 )
\r
1714 line.w[0] += slopeW;
\r
1717 line.t[0][0] += slopeT[0];
\r
1720 line.c[0][0] += slopeC[0];
\r
1726 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1729 if ( line.w[0] == z[i] )
\r
1739 iw = fix_inverse32 ( line.w[0] );
\r
1741 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1742 color_to_fix1 ( r1, g1, b1, dst[i] );
\r
1745 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1747 dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),
\r
1748 imulFix (imulFix_simple( g0, g1 ), g2 ),
\r
1749 imulFix (imulFix_simple( b0, b1 ), b2 )
\r
1752 dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),
\r
1753 imulFix_simple( g0, g1 ),
\r
1754 imulFix_simple( b0, b1 )
\r
1762 line.w[0] += slopeW;
\r
1765 line.t[0][0] += slopeT[0];
\r
1768 line.c[0][0] += slopeC[0];
\r
1777 void CTRTextureBlend::fragment_dst_color_one ()
\r
1779 tVideoSample *dst;
\r
1781 #ifdef USE_ZBUFFER
\r
1801 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
1804 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
1807 // apply top-left fill-convention, left
\r
1808 xStart = fill_convention_left( line.x[0] );
\r
1809 xEnd = fill_convention_right( line.x[1] );
\r
1811 dx = xEnd - xStart;
\r
1817 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
1820 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
1823 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
1826 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
1829 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
1832 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
1836 subPixel = ( (f32) xStart ) - line.x[0];
\r
1838 line.z[0] += slopeZ * subPixel;
\r
1841 line.w[0] += slopeW * subPixel;
\r
1844 line.c[0][0] += slopeC[0] * subPixel;
\r
1847 line.t[0][0] += slopeT[0] * subPixel;
\r
1850 line.t[1][0] += slopeT[1] * subPixel;
\r
1854 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
1855 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1857 #ifdef USE_ZBUFFER
\r
1858 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
1862 f32 iw = FIX_POINT_F32_MUL;
\r
1864 tFixPoint r0, g0, b0;
\r
1865 tFixPoint r1, g1, b1;
\r
1867 tFixPoint r2, g2, b2;
\r
1871 switch (depth_func)
\r
1874 case ECFN_LESSEQUAL:
\r
1875 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1878 if ( line.w[0] >= z[i] )
\r
1888 iw = fix_inverse32 ( line.w[0] );
\r
1891 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1892 color_to_fix ( r1, g1, b1, dst[i] );
\r
1894 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1896 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
\r
1897 clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
\r
1898 clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
\r
1902 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
\r
1903 clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
\r
1904 clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
\r
1912 line.w[0] += slopeW;
\r
1915 line.t[0][0] += slopeT[0];
\r
1918 line.c[0][0] += slopeC[0];
\r
1924 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
1927 if ( line.w[0] == z[i] )
\r
1937 iw = fix_inverse32 ( line.w[0] );
\r
1939 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
1940 color_to_fix ( r1, g1, b1, dst[i] );
\r
1943 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
1945 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
\r
1946 clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
\r
1947 clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
\r
1951 dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
\r
1952 clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
\r
1953 clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
\r
1962 line.w[0] += slopeW;
\r
1965 line.t[0][0] += slopeT[0];
\r
1968 line.c[0][0] += slopeC[0];
\r
1977 void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
\r
1979 tVideoSample *dst;
\r
1981 #ifdef USE_ZBUFFER
\r
2001 sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
\r
2004 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
\r
2007 // apply top-left fill-convention, left
\r
2008 xStart = fill_convention_left( line.x[0] );
\r
2009 xEnd = fill_convention_right( line.x[1] );
\r
2011 dx = xEnd - xStart;
\r
2017 const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
\r
2020 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
\r
2023 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
\r
2026 slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
\r
2029 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
\r
2032 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
\r
2036 subPixel = ( (f32) xStart ) - line.x[0];
\r
2038 line.z[0] += slopeZ * subPixel;
\r
2041 line.w[0] += slopeW * subPixel;
\r
2044 line.c[0][0] += slopeC[0] * subPixel;
\r
2047 line.t[0][0] += slopeT[0] * subPixel;
\r
2050 line.t[1][0] += slopeT[1] * subPixel;
\r
2054 SOFTWARE_DRIVER_2_CLIPCHECK;
\r
2055 dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
2057 #ifdef USE_ZBUFFER
\r
2058 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
\r
2062 f32 iw = FIX_POINT_F32_MUL;
\r
2064 tFixPoint r0, g0, b0;
\r
2065 tFixPoint r1, g1, b1;
\r
2067 tFixPoint r2, g2, b2;
\r
2071 switch (depth_func)
\r
2074 case ECFN_LESSEQUAL:
\r
2075 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
2078 if ( line.w[0] >= z[i] )
\r
2088 iw = fix_inverse32 ( line.w[0] );
\r
2091 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
2092 color_to_fix1 ( r1, g1, b1, dst[i] );
\r
2094 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
2096 dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
\r
2097 imulFix( FIX_POINT_ONE - g0, g1 ),
\r
2098 imulFix( FIX_POINT_ONE - b0, b1 )
\r
2102 dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
\r
2103 imulFix( FIX_POINT_ONE - g0, g1 ),
\r
2104 imulFix( FIX_POINT_ONE - b0, b1 )
\r
2112 line.w[0] += slopeW;
\r
2115 line.t[0][0] += slopeT[0];
\r
2118 line.c[0][0] += slopeC[0];
\r
2124 for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
\r
2127 if ( line.w[0] == z[i] )
\r
2137 iw = fix_inverse32 ( line.w[0] );
\r
2139 getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );
\r
2140 color_to_fix1 ( r1, g1, b1, dst[i] );
\r
2142 vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
\r
2144 dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
\r
2145 imulFix( FIX_POINT_ONE - g0, g1 ),
\r
2146 imulFix( FIX_POINT_ONE - b0, b1 )
\r
2150 dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
\r
2151 imulFix( FIX_POINT_ONE - g0, g1 ),
\r
2152 imulFix( FIX_POINT_ONE - b0, b1 )
\r
2160 line.w[0] += slopeW;
\r
2163 line.t[0][0] += slopeT[0];
\r
2166 line.c[0][0] += slopeC[0];
\r
2175 void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
\r
2177 if ( 0 == fragmentShader )
\r
2180 // sort on height, y
\r
2181 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
\r
2182 if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
\r
2183 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
\r
2185 const f32 ca = c->Pos.y - a->Pos.y;
\r
2186 const f32 ba = b->Pos.y - a->Pos.y;
\r
2187 const f32 cb = c->Pos.y - b->Pos.y;
\r
2188 // calculate delta y of the edges
\r
2189 scan.invDeltaY[0] = fill_step_y( ca );
\r
2190 scan.invDeltaY[1] = fill_step_y( ba );
\r
2191 scan.invDeltaY[2] = fill_step_y( cb );
\r
2193 if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
\r
2196 // find if the major edge is left or right aligned
\r
2199 temp[0] = a->Pos.x - c->Pos.x;
\r
2201 temp[2] = b->Pos.x - a->Pos.x;
\r
2204 scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
\r
2205 scan.right = 1 - scan.left;
\r
2207 // calculate slopes for the major edge
\r
2208 scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
\r
2209 scan.x[0] = a->Pos.x;
\r
2212 scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
\r
2213 scan.z[0] = a->Pos.z;
\r
2217 scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
\r
2218 scan.w[0] = a->Pos.w;
\r
2222 scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
\r
2223 scan.c[0][0] = a->Color[0];
\r
2227 scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
\r
2228 scan.t[0][0] = a->Tex[0];
\r
2232 scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
\r
2233 scan.t[1][0] = a->Tex[1];
\r
2236 // top left fill convention y run
\r
2244 // rasterize upper sub-triangle
\r
2245 if ( (f32) 0.0 != scan.invDeltaY[1] )
\r
2247 // calculate slopes for top edge
\r
2248 scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
\r
2249 scan.x[1] = a->Pos.x;
\r
2252 scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
\r
2253 scan.z[1] = a->Pos.z;
\r
2257 scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
\r
2258 scan.w[1] = a->Pos.w;
\r
2262 scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
\r
2263 scan.c[0][1] = a->Color[0];
\r
2267 scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
\r
2268 scan.t[0][1] = a->Tex[0];
\r
2272 scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
\r
2273 scan.t[1][1] = a->Tex[1];
\r
2276 // apply top-left fill convention, top part
\r
2277 yStart = fill_convention_left( a->Pos.y );
\r
2278 yEnd = fill_convention_right( b->Pos.y );
\r
2281 subPixel = ( (f32) yStart ) - a->Pos.y;
\r
2283 // correct to pixel center
\r
2284 scan.x[0] += scan.slopeX[0] * subPixel;
\r
2285 scan.x[1] += scan.slopeX[1] * subPixel;
\r
2288 scan.z[0] += scan.slopeZ[0] * subPixel;
\r
2289 scan.z[1] += scan.slopeZ[1] * subPixel;
\r
2293 scan.w[0] += scan.slopeW[0] * subPixel;
\r
2294 scan.w[1] += scan.slopeW[1] * subPixel;
\r
2298 scan.c[0][0] += scan.slopeC[0][0] * subPixel;
\r
2299 scan.c[0][1] += scan.slopeC[0][1] * subPixel;
\r
2303 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
\r
2304 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
\r
2308 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
\r
2309 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
\r
2314 // rasterize the edge scanlines
\r
2315 for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
\r
2317 line.x[scan.left] = scan.x[0];
\r
2318 line.x[scan.right] = scan.x[1];
\r
2321 line.z[scan.left] = scan.z[0];
\r
2322 line.z[scan.right] = scan.z[1];
\r
2326 line.w[scan.left] = scan.w[0];
\r
2327 line.w[scan.right] = scan.w[1];
\r
2331 line.c[0][scan.left] = scan.c[0][0];
\r
2332 line.c[0][scan.right] = scan.c[0][1];
\r
2336 line.t[0][scan.left] = scan.t[0][0];
\r
2337 line.t[0][scan.right] = scan.t[0][1];
\r
2341 line.t[1][scan.left] = scan.t[1][0];
\r
2342 line.t[1][scan.right] = scan.t[1][1];
\r
2345 // render a scanline
\r
2346 interlace_scanline (this->*fragmentShader) ();
\r
2348 scan.x[0] += scan.slopeX[0];
\r
2349 scan.x[1] += scan.slopeX[1];
\r
2352 scan.z[0] += scan.slopeZ[0];
\r
2353 scan.z[1] += scan.slopeZ[1];
\r
2357 scan.w[0] += scan.slopeW[0];
\r
2358 scan.w[1] += scan.slopeW[1];
\r
2362 scan.c[0][0] += scan.slopeC[0][0];
\r
2363 scan.c[0][1] += scan.slopeC[0][1];
\r
2367 scan.t[0][0] += scan.slopeT[0][0];
\r
2368 scan.t[0][1] += scan.slopeT[0][1];
\r
2372 scan.t[1][0] += scan.slopeT[1][0];
\r
2373 scan.t[1][1] += scan.slopeT[1][1];
\r
2379 // rasterize lower sub-triangle
\r
2380 if ( (f32) 0.0 != scan.invDeltaY[2] )
\r
2382 // advance to middle point
\r
2383 if( (f32) 0.0 != scan.invDeltaY[1] )
\r
2385 temp[0] = b->Pos.y - a->Pos.y; // dy
\r
2387 scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
\r
2389 scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
\r
2392 scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
\r
2395 scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
\r
2398 scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
\r
2401 scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
\r
2406 // calculate slopes for bottom edge
\r
2407 scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
\r
2408 scan.x[1] = b->Pos.x;
\r
2411 scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
\r
2412 scan.z[1] = b->Pos.z;
\r
2416 scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
\r
2417 scan.w[1] = b->Pos.w;
\r
2421 scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
\r
2422 scan.c[0][1] = b->Color[0];
\r
2426 scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
\r
2427 scan.t[0][1] = b->Tex[0];
\r
2431 scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
\r
2432 scan.t[1][1] = b->Tex[1];
\r
2435 // apply top-left fill convention, top part
\r
2436 yStart = fill_convention_left( b->Pos.y );
\r
2437 yEnd = fill_convention_right( c->Pos.y );
\r
2440 subPixel = ( (f32) yStart ) - b->Pos.y;
\r
2442 // correct to pixel center
\r
2443 scan.x[0] += scan.slopeX[0] * subPixel;
\r
2444 scan.x[1] += scan.slopeX[1] * subPixel;
\r
2447 scan.z[0] += scan.slopeZ[0] * subPixel;
\r
2448 scan.z[1] += scan.slopeZ[1] * subPixel;
\r
2452 scan.w[0] += scan.slopeW[0] * subPixel;
\r
2453 scan.w[1] += scan.slopeW[1] * subPixel;
\r
2457 scan.c[0][0] += scan.slopeC[0][0] * subPixel;
\r
2458 scan.c[0][1] += scan.slopeC[0][1] * subPixel;
\r
2462 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
\r
2463 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
\r
2467 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
\r
2468 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
\r
2473 // rasterize the edge scanlines
\r
2474 for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
\r
2476 line.x[scan.left] = scan.x[0];
\r
2477 line.x[scan.right] = scan.x[1];
\r
2480 line.z[scan.left] = scan.z[0];
\r
2481 line.z[scan.right] = scan.z[1];
\r
2485 line.w[scan.left] = scan.w[0];
\r
2486 line.w[scan.right] = scan.w[1];
\r
2490 line.c[0][scan.left] = scan.c[0][0];
\r
2491 line.c[0][scan.right] = scan.c[0][1];
\r
2495 line.t[0][scan.left] = scan.t[0][0];
\r
2496 line.t[0][scan.right] = scan.t[0][1];
\r
2500 line.t[1][scan.left] = scan.t[1][0];
\r
2501 line.t[1][scan.right] = scan.t[1][1];
\r
2504 // render a scanline
\r
2505 interlace_scanline (this->*fragmentShader) ();
\r
2507 scan.x[0] += scan.slopeX[0];
\r
2508 scan.x[1] += scan.slopeX[1];
\r
2511 scan.z[0] += scan.slopeZ[0];
\r
2512 scan.z[1] += scan.slopeZ[1];
\r
2516 scan.w[0] += scan.slopeW[0];
\r
2517 scan.w[1] += scan.slopeW[1];
\r
2521 scan.c[0][0] += scan.slopeC[0][0];
\r
2522 scan.c[0][1] += scan.slopeC[0][1];
\r
2526 scan.t[0][0] += scan.slopeT[0][0];
\r
2527 scan.t[0][1] += scan.slopeT[0][1];
\r
2531 scan.t[1][0] += scan.slopeT[1][0];
\r
2532 scan.t[1][1] += scan.slopeT[1][1];
\r
2542 } // end namespace video
\r
2543 } // end namespace irr
\r
2545 #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
\r
2552 //! creates a flat triangle renderer
\r
2553 IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver)
\r
2555 // EMT_ONETEXTURE_BLEND
\r
2556 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
\r
2557 return new CTRTextureBlend(driver);
\r
2560 #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
\r
2564 } // end namespace video
\r
2565 } // end namespace irr
\r