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