aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp680
1 files changed, 680 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp
new file mode 100644
index 0000000..1738f33
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp
@@ -0,0 +1,680 @@
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
71
72
73namespace irr
74{
75
76namespace video
77{
78
79class CTRTextureGouraudAdd2 : public IBurningShader
80{
81public:
82
83 //! constructor
84 CTRTextureGouraudAdd2(CBurningVideoDriver* driver);
85
86 //! draws an indexed triangle list
87 virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
88
89
90private:
91 void scanline_bilinear ();
92 sScanLineData line;
93
94};
95
96//! constructor
97CTRTextureGouraudAdd2::CTRTextureGouraudAdd2(CBurningVideoDriver* driver)
98: IBurningShader(driver)
99{
100 #ifdef _DEBUG
101 setDebugName("CTRTextureGouraudAdd2");
102 #endif
103}
104
105
106
107/*!
108*/
109void CTRTextureGouraudAdd2::scanline_bilinear ()
110{
111 tVideoSample *dst;
112
113#ifdef USE_ZBUFFER
114 fp24 *z;
115#endif
116
117 s32 xStart;
118 s32 xEnd;
119 s32 dx;
120
121
122#ifdef SUBTEXEL
123 f32 subPixel;
124#endif
125
126#ifdef IPOL_Z
127 f32 slopeZ;
128#endif
129#ifdef IPOL_W
130 fp24 slopeW;
131#endif
132#ifdef IPOL_C0
133 sVec4 slopeC;
134#endif
135#ifdef IPOL_T0
136 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
137#endif
138
139 // apply top-left fill-convention, left
140 xStart = core::ceil32( line.x[0] );
141 xEnd = core::ceil32( line.x[1] ) - 1;
142
143 dx = xEnd - xStart;
144
145 if ( dx < 0 )
146 return;
147
148 // slopes
149 const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
150
151#ifdef IPOL_Z
152 slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
153#endif
154#ifdef IPOL_W
155 slopeW = (line.w[1] - line.w[0]) * invDeltaX;
156#endif
157#ifdef IPOL_C0
158 slopeC = (line.c[1] - line.c[0]) * invDeltaX;
159#endif
160#ifdef IPOL_T0
161 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
162#endif
163#ifdef IPOL_T1
164 slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
165#endif
166
167#ifdef SUBTEXEL
168 subPixel = ( (f32) xStart ) - line.x[0];
169#ifdef IPOL_Z
170 line.z[0] += slopeZ * subPixel;
171#endif
172#ifdef IPOL_W
173 line.w[0] += slopeW * subPixel;
174#endif
175#ifdef IPOL_C0
176 line.c[0] += slopeC * subPixel;
177#endif
178#ifdef IPOL_T0
179 line.t[0][0] += slopeT[0] * subPixel;
180#endif
181#ifdef IPOL_T1
182 line.t[1][0] += slopeT[1] * subPixel;
183#endif
184#endif
185
186 dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
187
188#ifdef USE_ZBUFFER
189 z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
190#endif
191
192
193#ifdef INVERSE_W
194 f32 inversew;
195#endif
196
197
198#ifdef BURNINGVIDEO_RENDERER_FAST
199 u32 dIndex = ( line.y & 3 ) << 2;
200
201#else
202 tFixPoint tx0;
203 tFixPoint ty0;
204
205 tFixPoint r0, g0, b0;
206 tFixPoint r1, g1, b1;
207#endif
208
209
210 for ( s32 i = 0; i <= dx; ++i )
211 {
212#ifdef CMP_Z
213 if ( line.z[0] < z[i] )
214#endif
215#ifdef CMP_W
216 if ( line.w[0] >= z[i] )
217#endif
218
219 {
220
221
222#ifdef BURNINGVIDEO_RENDERER_FAST
223
224 const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
225
226
227#ifdef INVERSE_W
228 inversew = fix_inverse32 ( line.w[0] );
229
230 dst[i] = PixelAdd32 (
231 dst[i],
232 getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
233 d + tofix ( line.t[0][0].y,inversew) )
234 );
235#else
236 dst[i] = PixelAdd32 (
237 dst[i],
238 getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x),
239 d + tofix ( line.t[0][0].y) )
240 );
241
242#endif
243#else
244
245#ifdef INVERSE_W
246 inversew = fix_inverse32 ( line.w[0] );
247
248 tx0 = tofix ( line.t[0][0].x,inversew);
249 ty0 = tofix ( line.t[0][0].y,inversew);
250#else
251 tx0 = tofix ( line.t[0][0].x );
252 ty0 = tofix ( line.t[0][0].y );
253#endif
254 getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
255
256 color_to_fix ( r1, g1, b1, dst[i] );
257
258 dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + r0 ),
259 clampfix_maxcolor ( g1 + g0 ),
260 clampfix_maxcolor ( b1 + b0 )
261 );
262#endif
263
264#ifdef WRITE_Z
265 z[i] = line.z[0];
266#endif
267#ifdef WRITE_W
268 z[i] = line.w[0];
269#endif
270
271 }
272
273#ifdef IPOL_Z
274 line.z[0] += slopeZ;
275#endif
276#ifdef IPOL_W
277 line.w[0] += slopeW;
278#endif
279#ifdef IPOL_C0
280 line.c[0] += slopeC;
281#endif
282#ifdef IPOL_T0
283 line.t[0][0] += slopeT[0];
284#endif
285#ifdef IPOL_T1
286 line.t[1][0] += slopeT[1];
287#endif
288 }
289
290}
291
292void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
293{
294 sScanConvertData scan;
295
296 // sort on height, y
297 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
298 if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
299 if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
300
301 const f32 ca = c->Pos.y - a->Pos.y;
302 const f32 ba = b->Pos.y - a->Pos.y;
303 const f32 cb = c->Pos.y - b->Pos.y;
304 // calculate delta y of the edges
305 scan.invDeltaY[0] = core::reciprocal( ca );
306 scan.invDeltaY[1] = core::reciprocal( ba );
307 scan.invDeltaY[2] = core::reciprocal( cb );
308
309 // find if the major edge is left or right aligned
310 f32 temp[4];
311
312 temp[0] = a->Pos.x - c->Pos.x;
313 temp[1] = -ca;
314 temp[2] = b->Pos.x - a->Pos.x;
315 temp[3] = ba;
316
317 scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
318 scan.right = 1 - scan.left;
319
320 // calculate slopes for the major edge
321 scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
322 scan.x[0] = a->Pos.x;
323
324#ifdef IPOL_Z
325 scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
326 scan.z[0] = a->Pos.z;
327#endif
328
329#ifdef IPOL_W
330 scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
331 scan.w[0] = a->Pos.w;
332#endif
333
334#ifdef IPOL_C0
335 scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
336 scan.c[0] = a->Color[0];
337#endif
338
339#ifdef IPOL_T0
340 scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
341 scan.t[0][0] = a->Tex[0];
342#endif
343
344#ifdef IPOL_T1
345 scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
346 scan.t[1][0] = a->Tex[1];
347#endif
348
349 // top left fill convention y run
350 s32 yStart;
351 s32 yEnd;
352
353#ifdef SUBTEXEL
354 f32 subPixel;
355#endif
356
357 // rasterize upper sub-triangle
358 if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
359 {
360 // calculate slopes for top edge
361 scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
362 scan.x[1] = a->Pos.x;
363
364#ifdef IPOL_Z
365 scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
366 scan.z[1] = a->Pos.z;
367#endif
368
369#ifdef IPOL_W
370 scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
371 scan.w[1] = a->Pos.w;
372#endif
373
374#ifdef IPOL_C0
375 scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
376 scan.c[1] = a->Color[0];
377#endif
378
379#ifdef IPOL_T0
380 scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
381 scan.t[0][1] = a->Tex[0];
382#endif
383
384#ifdef IPOL_T1
385 scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
386 scan.t[1][1] = a->Tex[1];
387#endif
388
389 // apply top-left fill convention, top part
390 yStart = core::ceil32( a->Pos.y );
391 yEnd = core::ceil32( b->Pos.y ) - 1;
392
393#ifdef SUBTEXEL
394 subPixel = ( (f32) yStart ) - a->Pos.y;
395
396 // correct to pixel center
397 scan.x[0] += scan.slopeX[0] * subPixel;
398 scan.x[1] += scan.slopeX[1] * subPixel;
399
400#ifdef IPOL_Z
401 scan.z[0] += scan.slopeZ[0] * subPixel;
402 scan.z[1] += scan.slopeZ[1] * subPixel;
403#endif
404
405#ifdef IPOL_W
406 scan.w[0] += scan.slopeW[0] * subPixel;
407 scan.w[1] += scan.slopeW[1] * subPixel;
408#endif
409
410#ifdef IPOL_C0
411 scan.c[0] += scan.slopeC[0] * subPixel;
412 scan.c[1] += scan.slopeC[1] * subPixel;
413#endif
414
415#ifdef IPOL_T0
416 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
417 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
418#endif
419
420#ifdef IPOL_T1
421 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
422 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
423#endif
424
425#endif
426
427 // rasterize the edge scanlines
428 for( line.y = yStart; line.y <= yEnd; ++line.y)
429 {
430 line.x[scan.left] = scan.x[0];
431 line.x[scan.right] = scan.x[1];
432
433#ifdef IPOL_Z
434 line.z[scan.left] = scan.z[0];
435 line.z[scan.right] = scan.z[1];
436#endif
437
438#ifdef IPOL_W
439 line.w[scan.left] = scan.w[0];
440 line.w[scan.right] = scan.w[1];
441#endif
442
443#ifdef IPOL_C0
444 line.c[scan.left] = scan.c[0];
445 line.c[scan.right] = scan.c[1];
446#endif
447
448#ifdef IPOL_T0
449 line.t[0][scan.left] = scan.t[0][0];
450 line.t[0][scan.right] = scan.t[0][1];
451#endif
452
453#ifdef IPOL_T1
454 line.t[1][scan.left] = scan.t[1][0];
455 line.t[1][scan.right] = scan.t[1][1];
456#endif
457
458 // render a scanline
459 scanline_bilinear ();
460
461 scan.x[0] += scan.slopeX[0];
462 scan.x[1] += scan.slopeX[1];
463
464#ifdef IPOL_Z
465 scan.z[0] += scan.slopeZ[0];
466 scan.z[1] += scan.slopeZ[1];
467#endif
468
469#ifdef IPOL_W
470 scan.w[0] += scan.slopeW[0];
471 scan.w[1] += scan.slopeW[1];
472#endif
473
474#ifdef IPOL_C0
475 scan.c[0] += scan.slopeC[0];
476 scan.c[1] += scan.slopeC[1];
477#endif
478
479#ifdef IPOL_T0
480 scan.t[0][0] += scan.slopeT[0][0];
481 scan.t[0][1] += scan.slopeT[0][1];
482#endif
483
484#ifdef IPOL_T1
485 scan.t[1][0] += scan.slopeT[1][0];
486 scan.t[1][1] += scan.slopeT[1][1];
487#endif
488
489 }
490 }
491
492 // rasterize lower sub-triangle
493 if ( (f32) 0.0 != scan.invDeltaY[2] )
494 {
495 // advance to middle point
496 if( (f32) 0.0 != scan.invDeltaY[1] )
497 {
498 temp[0] = b->Pos.y - a->Pos.y; // dy
499
500 scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
501#ifdef IPOL_Z
502 scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
503#endif
504#ifdef IPOL_W
505 scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
506#endif
507#ifdef IPOL_C0
508 scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
509#endif
510#ifdef IPOL_T0
511 scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
512#endif
513#ifdef IPOL_T1
514 scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
515#endif
516
517 }
518
519 // calculate slopes for bottom edge
520 scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
521 scan.x[1] = b->Pos.x;
522
523#ifdef IPOL_Z
524 scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
525 scan.z[1] = b->Pos.z;
526#endif
527
528#ifdef IPOL_W
529 scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
530 scan.w[1] = b->Pos.w;
531#endif
532
533#ifdef IPOL_C0
534 scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
535 scan.c[1] = b->Color[0];
536#endif
537
538#ifdef IPOL_T0
539 scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
540 scan.t[0][1] = b->Tex[0];
541#endif
542
543#ifdef IPOL_T1
544 scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
545 scan.t[1][1] = b->Tex[1];
546#endif
547
548 // apply top-left fill convention, top part
549 yStart = core::ceil32( b->Pos.y );
550 yEnd = core::ceil32( c->Pos.y ) - 1;
551
552#ifdef SUBTEXEL
553
554 subPixel = ( (f32) yStart ) - b->Pos.y;
555
556 // correct to pixel center
557 scan.x[0] += scan.slopeX[0] * subPixel;
558 scan.x[1] += scan.slopeX[1] * subPixel;
559
560#ifdef IPOL_Z
561 scan.z[0] += scan.slopeZ[0] * subPixel;
562 scan.z[1] += scan.slopeZ[1] * subPixel;
563#endif
564
565#ifdef IPOL_W
566 scan.w[0] += scan.slopeW[0] * subPixel;
567 scan.w[1] += scan.slopeW[1] * subPixel;
568#endif
569
570#ifdef IPOL_C0
571 scan.c[0] += scan.slopeC[0] * subPixel;
572 scan.c[1] += scan.slopeC[1] * subPixel;
573#endif
574
575#ifdef IPOL_T0
576 scan.t[0][0] += scan.slopeT[0][0] * subPixel;
577 scan.t[0][1] += scan.slopeT[0][1] * subPixel;
578#endif
579
580#ifdef IPOL_T1
581 scan.t[1][0] += scan.slopeT[1][0] * subPixel;
582 scan.t[1][1] += scan.slopeT[1][1] * subPixel;
583#endif
584
585#endif
586
587 // rasterize the edge scanlines
588 for( line.y = yStart; line.y <= yEnd; ++line.y)
589 {
590 line.x[scan.left] = scan.x[0];
591 line.x[scan.right] = scan.x[1];
592
593#ifdef IPOL_Z
594 line.z[scan.left] = scan.z[0];
595 line.z[scan.right] = scan.z[1];
596#endif
597
598#ifdef IPOL_W
599 line.w[scan.left] = scan.w[0];
600 line.w[scan.right] = scan.w[1];
601#endif
602
603#ifdef IPOL_C0
604 line.c[scan.left] = scan.c[0];
605 line.c[scan.right] = scan.c[1];
606#endif
607
608#ifdef IPOL_T0
609 line.t[0][scan.left] = scan.t[0][0];
610 line.t[0][scan.right] = scan.t[0][1];
611#endif
612
613#ifdef IPOL_T1
614 line.t[1][scan.left] = scan.t[1][0];
615 line.t[1][scan.right] = scan.t[1][1];
616#endif
617
618 // render a scanline
619 scanline_bilinear ();
620
621 scan.x[0] += scan.slopeX[0];
622 scan.x[1] += scan.slopeX[1];
623
624#ifdef IPOL_Z
625 scan.z[0] += scan.slopeZ[0];
626 scan.z[1] += scan.slopeZ[1];
627#endif
628
629#ifdef IPOL_W
630 scan.w[0] += scan.slopeW[0];
631 scan.w[1] += scan.slopeW[1];
632#endif
633
634#ifdef IPOL_C0
635 scan.c[0] += scan.slopeC[0];
636 scan.c[1] += scan.slopeC[1];
637#endif
638
639#ifdef IPOL_T0
640 scan.t[0][0] += scan.slopeT[0][0];
641 scan.t[0][1] += scan.slopeT[0][1];
642#endif
643
644#ifdef IPOL_T1
645 scan.t[1][0] += scan.slopeT[1][0];
646 scan.t[1][1] += scan.slopeT[1][1];
647#endif
648
649 }
650 }
651
652}
653
654
655} // end namespace video
656} // end namespace irr
657
658#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
659
660namespace irr
661{
662namespace video
663{
664
665//! creates a flat triangle renderer
666IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver)
667{
668 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
669 return new CTRTextureGouraudAdd2(driver);
670 #else
671 return 0;
672 #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
673}
674
675
676} // end namespace video
677} // end namespace irr
678
679
680