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