aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp1154
1 files changed, 1154 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp
new file mode 100644
index 0000000..989a915
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp
@@ -0,0 +1,1154 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "IrrCompileConfig.h"
6#include "IBurningShader.h"
7
8#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
9
10// compile flag for this file
11#undef USE_ZBUFFER
12#undef IPOL_Z
13#undef CMP_Z
14#undef WRITE_Z
15
16#undef IPOL_W
17#undef CMP_W
18#undef WRITE_W
19
20#undef SUBTEXEL
21#undef INVERSE_W
22
23#undef IPOL_C0
24#undef IPOL_T0
25#undef IPOL_T1
26
27// define render case
28#define SUBTEXEL
29#define INVERSE_W
30
31#define USE_ZBUFFER
32#define IPOL_W
33#define CMP_W
34#define WRITE_W
35
36//#define IPOL_C0
37#define IPOL_T0
38#define IPOL_T1
39
40// apply global override
41#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
42 #undef INVERSE_W
43#endif
44
45#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
46 #undef SUBTEXEL
47#endif
48
49#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
50 #undef IPOL_C0
51#endif
52
53#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
54 #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
55 #undef IPOL_W
56 #endif
57 #define IPOL_Z
58
59 #ifdef CMP_W
60 #undef CMP_W
61 #define CMP_Z
62 #endif
63
64 #ifdef WRITE_W
65 #undef WRITE_W
66 #define WRITE_Z
67 #endif
68
69#endif
70
71namespace irr
72{
73
74namespace video
75{
76
77class CTRTextureLightMap2_M4 : public IBurningShader
78{
79public:
80
81 //! constructor
82 CTRTextureLightMap2_M4(CBurningVideoDriver* driver);
83
84 //! draws an indexed triangle list
85 virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
86
87
88private:
89
90 void drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
91 void drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
92
93 void scanline_bilinear ();
94 void scanline_bilinear2_mag ();
95 void scanline_bilinear2_min ();
96
97 sScanLineData line;
98
99};
100
101//! constructor
102CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(CBurningVideoDriver* driver)
103: IBurningShader(driver)
104{
105 #ifdef _DEBUG
106 setDebugName("CTRTextureLightMap2_M4");
107 #endif
108}
109
110/*!
111*/
112REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
113{
114 tVideoSample *dst;
115 fp24 *z;
116
117 // apply top-left fill-convention, left
118 const s32 xStart = irr::core::ceil32( line.x[0] );
119 const s32 xEnd = irr::core::ceil32( line.x[1] ) - 1;
120 s32 dx;
121 s32 i;
122
123
124 dx = xEnd - xStart;
125 if ( dx < 0 )
126 return;
127
128 // slopes
129 const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
130
131 // search z-buffer for first not occulled pixel
132 i = ( line.y * RenderTarget->getDimension().Width ) + xStart;
133 z = (fp24*) DepthBuffer->lock() + i;
134 dst = (tVideoSample*)RenderTarget->lock() + i;
135
136 // subTexel
137 const f32 subPixel = ( (f32) xStart ) - line.x[0];
138
139#ifdef IPOL_W
140 const fp24 b = (line.w[1] - line.w[0]) * invDeltaX;
141 fp24 a = line.w[0] + ( b * subPixel );
142
143 i = 0;
144
145 while ( a < z[i] )
146 {
147 a += b;
148
149 i += 1;
150 if ( i > dx )
151 return;
152
153 }
154
155 // lazy setup rest of scanline
156
157 line.w[0] = a;
158 line.w[1] = b;
159#else
160 const f32 b = (line.z[1] - line.z[0]) * invDeltaX;
161 f32 a = line.z[0] + ( b * subPixel );
162
163 i = 0;
164
165 while ( a > z[i] )
166 {
167 a += b;
168
169 i += 1;
170 if ( i > dx )
171 return;
172
173 }
174
175 // lazy setup rest of scanline
176
177 line.z[0] = a;
178 line.z[1] = b;
179#endif
180
181 a = (f32) i + subPixel;
182
183 line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
184 line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
185
186 line.t[0][0] += line.t[0][1] * a;
187 line.t[1][0] += line.t[1][1] * a;
188
189
190#ifdef BURNINGVIDEO_RENDERER_FAST
191 u32 dIndex = ( line.y & 3 ) << 2;
192
193 tFixPoint r0, g0, b0;
194 tFixPoint r1, g1, b1;
195
196#else
197 //
198 tFixPoint r0, g0, b0;
199 tFixPoint r1, g1, b1;
200#endif
201
202
203 for ( ;i <= dx; i++ )
204 {
205#ifdef IPOL_W
206 if ( line.w[0] >= z[i] )
207 {
208 z[i] = line.w[0];
209#else
210 if ( line.z[0] < z[i] )
211 {
212 z[i] = line.z[0];
213#endif
214
215#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
216 f32 inversew = fix_inverse32 ( line.w[0] );
217#else
218 f32 inversew = FIX_POINT_F32_MUL;
219#endif
220
221
222
223#ifdef BURNINGVIDEO_RENDERER_FAST
224
225 const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
226
227 getSample_texture ( r0, g0, b0, &IT[0], d + tofix ( line.t[0][0].x,inversew), d + tofix ( line.t[0][0].y,inversew) );
228 getSample_texture ( r1, g1, b1, &IT[1], d + tofix ( line.t[1][0].x,inversew), d + tofix ( line.t[1][0].y,inversew) );
229#else
230 getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
231 getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
232
233#endif
234
235 dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),
236 clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),
237 clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )
238 );
239 }
240
241#ifdef IPOL_W
242 line.w[0] += line.w[1];
243#else
244 line.z[0] += line.z[1];
245#endif
246 line.t[0][0] += line.t[0][1];
247 line.t[1][0] += line.t[1][1];
248 }
249
250}
251
252/*!
253*/
254REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
255{
256 tVideoSample *dst;
257 fp24 *z;
258
259 s32 xStart;
260 s32 xEnd;
261 s32 dx;
262 s32 i;
263
264
265 // apply top-left fill-convention, left
266 xStart = core::ceil32( line.x[0] );
267 xEnd = core::ceil32( line.x[1] ) - 1;
268
269 dx = xEnd - xStart;
270 if ( dx < 0 )
271 return;
272
273 // slopes
274 const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
275
276 // search z-buffer for first not occulled pixel
277 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
278
279 // subTexel
280 const f32 subPixel = ( (f32) xStart ) - line.x[0];
281
282#ifdef IPOL_W
283 const f32 b = (line.w[1] - line.w[0]) * invDeltaX;
284 f32 a = line.w[0] + ( b * subPixel );
285
286 i = 0;
287
288 while ( a <= z[i] )
289 {
290 a += b;
291
292 i += 1;
293 if ( i > dx )
294 return;
295
296 }
297
298 // lazy setup rest of scanline
299
300 line.w[0] = a;
301 line.w[1] = b;
302#else
303 const f32 b = (line.z[1] - line.z[0]) * invDeltaX;
304 f32 a = line.z[0] + ( b * subPixel );
305
306 i = 0;
307
308 while ( a > z[i] )
309 {
310 a += b;
311
312 i += 1;
313 if ( i > dx )
314 return;
315
316 }
317
318 // lazy setup rest of scanline
319
320 line.z[0] = a;
321 line.z[1] = b;
322#endif
323 dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
324
325 a = (f32) i + subPixel;
326
327 line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
328 line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
329
330 line.t[0][0] += line.t[0][1] * a;
331 line.t[1][0] += line.t[1][1] * a;
332
333
334 tFixPoint r0, g0, b0;
335 tFixPoint r1, g1, b1;
336
337
338 for ( ;i <= dx; i++ )
339 {
340#ifdef IPOL_W
341 if ( line.w[0] >= z[i] )
342 {
343 z[i] = line.w[0];
344#else
345 if ( line.z[0] < z[i] )
346 {
347 z[i] = line.z[0];
348#endif
349
350#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
351 f32 inversew = fix_inverse32 ( line.w[0] );
352#else
353 f32 inversew = FIX_POINT_F32_MUL;
354#endif
355
356
357 getTexel_fix ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
358 getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
359
360 dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),
361 clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),
362 clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )
363 );
364 }
365
366#ifdef IPOL_W
367 line.w[0] += line.w[1];
368#else
369 line.z[0] += line.z[1];
370#endif
371 line.t[0][0] += line.t[0][1];
372 line.t[1][0] += line.t[1][1];
373 }
374
375}
376
377//#ifdef BURNINGVIDEO_RENDERER_FAST
378#if 1
379
380void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
381{
382 if ( IT[0].lodLevel <= 2 )
383 drawTriangle_Mag ( a, b, c );
384 else
385 drawTriangle_Min ( a, b, c );
386}
387
388void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
389{
390 sScanConvertData scan;
391
392 // sort on height, y
393 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
394 if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
395 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
396
397 const f32 ca = c->Pos.y - a->Pos.y;
398 const f32 ba = b->Pos.y - a->Pos.y;
399 const f32 cb = c->Pos.y - b->Pos.y;
400 // calculate delta y of the edges
401 scan.invDeltaY[0] = core::reciprocal( ca );
402 scan.invDeltaY[1] = core::reciprocal( ba );
403 scan.invDeltaY[2] = core::reciprocal( cb );
404
405 if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
406 return;
407
408 // find if the major edge is left or right aligned
409 f32 temp[4];
410
411 temp[0] = a->Pos.x - c->Pos.x;
412 temp[1] = -ca;
413 temp[2] = b->Pos.x - a->Pos.x;
414 temp[3] = ba;
415
416 scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
417 scan.right = 1 - scan.left;
418
419 // calculate slopes for the major edge
420 scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
421 scan.x[0] = a->Pos.x;
422
423#ifdef IPOL_Z
424 scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
425 scan.z[0] = a->Pos.z;
426#endif
427
428#ifdef IPOL_W
429 scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
430 scan.w[0] = a->Pos.w;
431#endif
432
433#ifdef IPOL_C0
434 scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
435 scan.c[0] = a->Color[0];
436#endif
437
438#ifdef IPOL_T0
439 scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
440 scan.t[0][0] = a->Tex[0];
441#endif
442
443#ifdef IPOL_T1
444 scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
445 scan.t[1][0] = a->Tex[1];
446#endif
447
448 // top left fill convention y run
449 s32 yStart;
450 s32 yEnd;
451
452#ifdef SUBTEXEL
453 f32 subPixel;
454#endif
455
456 // rasterize upper sub-triangle
457 if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
458 {
459 // calculate slopes for top edge
460 scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
461 scan.x[1] = a->Pos.x;
462
463#ifdef IPOL_Z
464 scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
465 scan.z[1] = a->Pos.z;
466#endif
467
468#ifdef IPOL_W
469 scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
470 scan.w[1] = a->Pos.w;
471#endif
472
473#ifdef IPOL_C0
474 scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
475 scan.c[1] = a->Color[0];
476#endif
477
478#ifdef IPOL_T0
479 scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
480 scan.t[0][1] = a->Tex[0];
481#endif
482
483#ifdef IPOL_T1
484 scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
485 scan.t[1][1] = a->Tex[1];
486#endif
487
488 // apply top-left fill convention, top part
489 yStart = core::ceil32( a->Pos.y );
490 yEnd = core::ceil32( b->Pos.y ) - 1;
491
492#ifdef SUBTEXEL
493 subPixel = ( (f32) yStart ) - a->Pos.y;
494
495 // correct to pixel center
496 scan.x[0] += scan.slopeX[0] * subPixel;
497 scan.x[1] += scan.slopeX[1] * subPixel;
498
499#ifdef IPOL_Z
500 scan.z[0] += scan.slopeZ[0] * subPixel;
501 scan.z[1] += scan.slopeZ[1] * subPixel;
502#endif
503
504#ifdef IPOL_W
505 scan.w[0] += scan.slopeW[0] * subPixel;
506 scan.w[1] += scan.slopeW[1] * subPixel;
507#endif
508
509#ifdef IPOL_C0
510 scan.c[0] += scan.slopeC[0] * subPixel;
511 scan.c[1] += scan.slopeC[1] * subPixel;
512#endif
513
514#ifdef IPOL_T0
515 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
516 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
517#endif
518
519#ifdef IPOL_T1
520 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
521 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
522#endif
523
524#endif
525
526 // rasterize the edge scanlines
527 for( line.y = yStart; line.y <= yEnd; ++line.y)
528 {
529 line.x[scan.left] = scan.x[0];
530 line.x[scan.right] = scan.x[1];
531
532#ifdef IPOL_Z
533 line.z[scan.left] = scan.z[0];
534 line.z[scan.right] = scan.z[1];
535#endif
536
537#ifdef IPOL_W
538 line.w[scan.left] = scan.w[0];
539 line.w[scan.right] = scan.w[1];
540#endif
541
542#ifdef IPOL_C0
543 line.c[scan.left] = scan.c[0];
544 line.c[scan.right] = scan.c[1];
545#endif
546
547#ifdef IPOL_T0
548 line.t[0][scan.left] = scan.t[0][0];
549 line.t[0][scan.right] = scan.t[0][1];
550#endif
551
552#ifdef IPOL_T1
553 line.t[1][scan.left] = scan.t[1][0];
554 line.t[1][scan.right] = scan.t[1][1];
555#endif
556
557 // render a scanline
558 scanline_bilinear2_min ();
559
560 scan.x[0] += scan.slopeX[0];
561 scan.x[1] += scan.slopeX[1];
562
563#ifdef IPOL_Z
564 scan.z[0] += scan.slopeZ[0];
565 scan.z[1] += scan.slopeZ[1];
566#endif
567
568#ifdef IPOL_W
569 scan.w[0] += scan.slopeW[0];
570 scan.w[1] += scan.slopeW[1];
571#endif
572
573#ifdef IPOL_C0
574 scan.c[0] += scan.slopeC[0];
575 scan.c[1] += scan.slopeC[1];
576#endif
577
578#ifdef IPOL_T0
579 scan.t[0][0] += scan.slopeT[0][0];
580 scan.t[0][1] += scan.slopeT[0][1];
581#endif
582
583#ifdef IPOL_T1
584 scan.t[1][0] += scan.slopeT[1][0];
585 scan.t[1][1] += scan.slopeT[1][1];
586#endif
587
588 }
589 }
590
591 // rasterize lower sub-triangle
592 //if ( (f32) 0.0 != scan.invDeltaY[2] )
593 if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
594 {
595 // advance to middle point
596 if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
597 {
598 temp[0] = b->Pos.y - a->Pos.y; // dy
599
600 scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
601#ifdef IPOL_Z
602 scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
603#endif
604#ifdef IPOL_W
605 scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
606#endif
607#ifdef IPOL_C0
608 scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
609#endif
610#ifdef IPOL_T0
611 scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
612#endif
613#ifdef IPOL_T1
614 scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
615#endif
616
617 }
618
619 // calculate slopes for bottom edge
620 scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
621 scan.x[1] = b->Pos.x;
622
623#ifdef IPOL_Z
624 scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
625 scan.z[1] = b->Pos.z;
626#endif
627
628#ifdef IPOL_W
629 scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
630 scan.w[1] = b->Pos.w;
631#endif
632
633#ifdef IPOL_C0
634 scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
635 scan.c[1] = b->Color[0];
636#endif
637
638#ifdef IPOL_T0
639 scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
640 scan.t[0][1] = b->Tex[0];
641#endif
642
643#ifdef IPOL_T1
644 scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
645 scan.t[1][1] = b->Tex[1];
646#endif
647
648 // apply top-left fill convention, top part
649 yStart = core::ceil32( b->Pos.y );
650 yEnd = core::ceil32( c->Pos.y ) - 1;
651
652#ifdef SUBTEXEL
653
654 subPixel = ( (f32) yStart ) - b->Pos.y;
655
656 // correct to pixel center
657 scan.x[0] += scan.slopeX[0] * subPixel;
658 scan.x[1] += scan.slopeX[1] * subPixel;
659
660#ifdef IPOL_Z
661 scan.z[0] += scan.slopeZ[0] * subPixel;
662 scan.z[1] += scan.slopeZ[1] * subPixel;
663#endif
664
665#ifdef IPOL_W
666 scan.w[0] += scan.slopeW[0] * subPixel;
667 scan.w[1] += scan.slopeW[1] * subPixel;
668#endif
669
670#ifdef IPOL_C0
671 scan.c[0] += scan.slopeC[0] * subPixel;
672 scan.c[1] += scan.slopeC[1] * subPixel;
673#endif
674
675#ifdef IPOL_T0
676 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
677 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
678#endif
679
680#ifdef IPOL_T1
681 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
682 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
683#endif
684
685#endif
686
687 // rasterize the edge scanlines
688 for( line.y = yStart; line.y <= yEnd; ++line.y)
689 {
690 line.x[scan.left] = scan.x[0];
691 line.x[scan.right] = scan.x[1];
692
693#ifdef IPOL_Z
694 line.z[scan.left] = scan.z[0];
695 line.z[scan.right] = scan.z[1];
696#endif
697
698#ifdef IPOL_W
699 line.w[scan.left] = scan.w[0];
700 line.w[scan.right] = scan.w[1];
701#endif
702
703#ifdef IPOL_C0
704 line.c[scan.left] = scan.c[0];
705 line.c[scan.right] = scan.c[1];
706#endif
707
708#ifdef IPOL_T0
709 line.t[0][scan.left] = scan.t[0][0];
710 line.t[0][scan.right] = scan.t[0][1];
711#endif
712
713#ifdef IPOL_T1
714 line.t[1][scan.left] = scan.t[1][0];
715 line.t[1][scan.right] = scan.t[1][1];
716#endif
717
718 // render a scanline
719 scanline_bilinear2_min ();
720
721 scan.x[0] += scan.slopeX[0];
722 scan.x[1] += scan.slopeX[1];
723
724#ifdef IPOL_Z
725 scan.z[0] += scan.slopeZ[0];
726 scan.z[1] += scan.slopeZ[1];
727#endif
728
729#ifdef IPOL_W
730 scan.w[0] += scan.slopeW[0];
731 scan.w[1] += scan.slopeW[1];
732#endif
733
734#ifdef IPOL_C0
735 scan.c[0] += scan.slopeC[0];
736 scan.c[1] += scan.slopeC[1];
737#endif
738
739#ifdef IPOL_T0
740 scan.t[0][0] += scan.slopeT[0][0];
741 scan.t[0][1] += scan.slopeT[0][1];
742#endif
743
744#ifdef IPOL_T1
745 scan.t[1][0] += scan.slopeT[1][0];
746 scan.t[1][1] += scan.slopeT[1][1];
747#endif
748
749 }
750 }
751
752}
753
754void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
755
756#else
757
758void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
759
760#endif
761
762{
763 sScanConvertData scan;
764
765 // sort on height, y
766 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
767 if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
768 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
769
770 const f32 ca = c->Pos.y - a->Pos.y;
771 const f32 ba = b->Pos.y - a->Pos.y;
772 const f32 cb = c->Pos.y - b->Pos.y;
773 // calculate delta y of the edges
774 scan.invDeltaY[0] = core::reciprocal( ca );
775 scan.invDeltaY[1] = core::reciprocal( ba );
776 scan.invDeltaY[2] = core::reciprocal( cb );
777
778 if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
779 return;
780
781 // find if the major edge is left or right aligned
782 f32 temp[4];
783
784 temp[0] = a->Pos.x - c->Pos.x;
785 temp[1] = -ca;
786 temp[2] = b->Pos.x - a->Pos.x;
787 temp[3] = ba;
788
789 scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
790 scan.right = 1 - scan.left;
791
792 // calculate slopes for the major edge
793 scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
794 scan.x[0] = a->Pos.x;
795
796#ifdef IPOL_Z
797 scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
798 scan.z[0] = a->Pos.z;
799#endif
800
801#ifdef IPOL_W
802 scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
803 scan.w[0] = a->Pos.w;
804#endif
805
806#ifdef IPOL_C0
807 scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
808 scan.c[0] = a->Color[0];
809#endif
810
811#ifdef IPOL_T0
812 scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
813 scan.t[0][0] = a->Tex[0];
814#endif
815
816#ifdef IPOL_T1
817 scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
818 scan.t[1][0] = a->Tex[1];
819#endif
820
821 // top left fill convention y run
822 s32 yStart;
823 s32 yEnd;
824
825#ifdef SUBTEXEL
826 f32 subPixel;
827#endif
828
829
830 // rasterize upper sub-triangle
831 if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
832 {
833 // calculate slopes for top edge
834 scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
835 scan.x[1] = a->Pos.x;
836
837#ifdef IPOL_Z
838 scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
839 scan.z[1] = a->Pos.z;
840#endif
841
842#ifdef IPOL_W
843 scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
844 scan.w[1] = a->Pos.w;
845#endif
846
847#ifdef IPOL_C0
848 scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
849 scan.c[1] = a->Color[0];
850#endif
851
852#ifdef IPOL_T0
853 scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
854 scan.t[0][1] = a->Tex[0];
855#endif
856
857#ifdef IPOL_T1
858 scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
859 scan.t[1][1] = a->Tex[1];
860#endif
861
862 // apply top-left fill convention, top part
863 yStart = core::ceil32( a->Pos.y );
864 yEnd = core::ceil32( b->Pos.y ) - 1;
865
866#ifdef SUBTEXEL
867 subPixel = ( (f32) yStart ) - a->Pos.y;
868
869 // correct to pixel center
870 scan.x[0] += scan.slopeX[0] * subPixel;
871 scan.x[1] += scan.slopeX[1] * subPixel;
872
873#ifdef IPOL_Z
874 scan.z[0] += scan.slopeZ[0] * subPixel;
875 scan.z[1] += scan.slopeZ[1] * subPixel;
876#endif
877
878#ifdef IPOL_W
879 scan.w[0] += scan.slopeW[0] * subPixel;
880 scan.w[1] += scan.slopeW[1] * subPixel;
881#endif
882
883#ifdef IPOL_C0
884 scan.c[0] += scan.slopeC[0] * subPixel;
885 scan.c[1] += scan.slopeC[1] * subPixel;
886#endif
887
888#ifdef IPOL_T0
889 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
890 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
891#endif
892
893#ifdef IPOL_T1
894 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
895 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
896#endif
897
898#endif
899
900 // rasterize the edge scanlines
901 for( line.y = yStart; line.y <= yEnd; ++line.y)
902 {
903 line.x[scan.left] = scan.x[0];
904 line.x[scan.right] = scan.x[1];
905
906#ifdef IPOL_Z
907 line.z[scan.left] = scan.z[0];
908 line.z[scan.right] = scan.z[1];
909#endif
910
911#ifdef IPOL_W
912 line.w[scan.left] = scan.w[0];
913 line.w[scan.right] = scan.w[1];
914#endif
915
916#ifdef IPOL_C0
917 line.c[scan.left] = scan.c[0];
918 line.c[scan.right] = scan.c[1];
919#endif
920
921#ifdef IPOL_T0
922 line.t[0][scan.left] = scan.t[0][0];
923 line.t[0][scan.right] = scan.t[0][1];
924#endif
925
926#ifdef IPOL_T1
927 line.t[1][scan.left] = scan.t[1][0];
928 line.t[1][scan.right] = scan.t[1][1];
929#endif
930
931 // render a scanline
932 scanline_bilinear2_mag ();
933
934 scan.x[0] += scan.slopeX[0];
935 scan.x[1] += scan.slopeX[1];
936
937#ifdef IPOL_Z
938 scan.z[0] += scan.slopeZ[0];
939 scan.z[1] += scan.slopeZ[1];
940#endif
941
942#ifdef IPOL_W
943 scan.w[0] += scan.slopeW[0];
944 scan.w[1] += scan.slopeW[1];
945#endif
946
947#ifdef IPOL_C0
948 scan.c[0] += scan.slopeC[0];
949 scan.c[1] += scan.slopeC[1];
950#endif
951
952#ifdef IPOL_T0
953 scan.t[0][0] += scan.slopeT[0][0];
954 scan.t[0][1] += scan.slopeT[0][1];
955#endif
956
957#ifdef IPOL_T1
958 scan.t[1][0] += scan.slopeT[1][0];
959 scan.t[1][1] += scan.slopeT[1][1];
960#endif
961
962 }
963 }
964
965 // rasterize lower sub-triangle
966 //if ( (f32) 0.0 != scan.invDeltaY[2] )
967 if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
968 {
969 // advance to middle point
970 if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
971 {
972 temp[0] = b->Pos.y - a->Pos.y; // dy
973
974 scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
975#ifdef IPOL_Z
976 scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
977#endif
978#ifdef IPOL_W
979 scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
980#endif
981#ifdef IPOL_C0
982 scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
983#endif
984#ifdef IPOL_T0
985 scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
986#endif
987#ifdef IPOL_T1
988 scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
989#endif
990
991 }
992
993 // calculate slopes for bottom edge
994 scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
995 scan.x[1] = b->Pos.x;
996
997#ifdef IPOL_Z
998 scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
999 scan.z[1] = b->Pos.z;
1000#endif
1001
1002#ifdef IPOL_W
1003 scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
1004 scan.w[1] = b->Pos.w;
1005#endif
1006
1007#ifdef IPOL_C0
1008 scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
1009 scan.c[1] = b->Color[0];
1010#endif
1011
1012#ifdef IPOL_T0
1013 scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
1014 scan.t[0][1] = b->Tex[0];
1015#endif
1016
1017#ifdef IPOL_T1
1018 scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
1019 scan.t[1][1] = b->Tex[1];
1020#endif
1021
1022 // apply top-left fill convention, top part
1023 yStart = core::ceil32( b->Pos.y );
1024 yEnd = core::ceil32( c->Pos.y ) - 1;
1025
1026#ifdef SUBTEXEL
1027
1028 subPixel = ( (f32) yStart ) - b->Pos.y;
1029
1030 // correct to pixel center
1031 scan.x[0] += scan.slopeX[0] * subPixel;
1032 scan.x[1] += scan.slopeX[1] * subPixel;
1033
1034#ifdef IPOL_Z
1035 scan.z[0] += scan.slopeZ[0] * subPixel;
1036 scan.z[1] += scan.slopeZ[1] * subPixel;
1037#endif
1038
1039#ifdef IPOL_W
1040 scan.w[0] += scan.slopeW[0] * subPixel;
1041 scan.w[1] += scan.slopeW[1] * subPixel;
1042#endif
1043
1044#ifdef IPOL_C0
1045 scan.c[0] += scan.slopeC[0] * subPixel;
1046 scan.c[1] += scan.slopeC[1] * subPixel;
1047#endif
1048
1049#ifdef IPOL_T0
1050 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
1051 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
1052#endif
1053
1054#ifdef IPOL_T1
1055 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
1056 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
1057#endif
1058
1059#endif
1060
1061 // rasterize the edge scanlines
1062 for( line.y = yStart; line.y <= yEnd; ++line.y)
1063 {
1064 line.x[scan.left] = scan.x[0];
1065 line.x[scan.right] = scan.x[1];
1066
1067#ifdef IPOL_Z
1068 line.z[scan.left] = scan.z[0];
1069 line.z[scan.right] = scan.z[1];
1070#endif
1071
1072#ifdef IPOL_W
1073 line.w[scan.left] = scan.w[0];
1074 line.w[scan.right] = scan.w[1];
1075#endif
1076
1077#ifdef IPOL_C0
1078 line.c[scan.left] = scan.c[0];
1079 line.c[scan.right] = scan.c[1];
1080#endif
1081
1082#ifdef IPOL_T0
1083 line.t[0][scan.left] = scan.t[0][0];
1084 line.t[0][scan.right] = scan.t[0][1];
1085#endif
1086
1087#ifdef IPOL_T1
1088 line.t[1][scan.left] = scan.t[1][0];
1089 line.t[1][scan.right] = scan.t[1][1];
1090#endif
1091
1092 // render a scanline
1093 scanline_bilinear2_mag ();
1094
1095 scan.x[0] += scan.slopeX[0];
1096 scan.x[1] += scan.slopeX[1];
1097
1098#ifdef IPOL_Z
1099 scan.z[0] += scan.slopeZ[0];
1100 scan.z[1] += scan.slopeZ[1];
1101#endif
1102
1103#ifdef IPOL_W
1104 scan.w[0] += scan.slopeW[0];
1105 scan.w[1] += scan.slopeW[1];
1106#endif
1107
1108#ifdef IPOL_C0
1109 scan.c[0] += scan.slopeC[0];
1110 scan.c[1] += scan.slopeC[1];
1111#endif
1112
1113#ifdef IPOL_T0
1114 scan.t[0][0] += scan.slopeT[0][0];
1115 scan.t[0][1] += scan.slopeT[0][1];
1116#endif
1117
1118#ifdef IPOL_T1
1119 scan.t[1][0] += scan.slopeT[1][0];
1120 scan.t[1][1] += scan.slopeT[1][1];
1121#endif
1122
1123 }
1124 }
1125
1126}
1127
1128} // end namespace video
1129} // end namespace irr
1130
1131#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
1132
1133namespace irr
1134{
1135namespace video
1136{
1137
1138
1139//! creates a flat triangle renderer
1140IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver)
1141{
1142 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
1143 return new CTRTextureLightMap2_M4(driver);
1144 #else
1145 return 0;
1146 #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
1147}
1148
1149
1150} // end namespace video
1151} // end namespace irr
1152
1153
1154