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