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