aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/include/IQ3Shader.h
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 17:24:39 +1000
committerDavid Walter Seikel2013-01-13 17:24:39 +1000
commit393b5cd1dc438872af89d334ef6e5fcc59f27d47 (patch)
tree6a14521219942a08a1b95cb2f5a923a9edd60f63 /libraries/irrlicht-1.8/include/IQ3Shader.h
parentAdd a note about rasters suggested start up code. (diff)
downloadSledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.zip
SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.gz
SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.bz2
SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.xz
Added Irrlicht 1.8, but without all the Windows binaries.
Diffstat (limited to 'libraries/irrlicht-1.8/include/IQ3Shader.h')
-rw-r--r--libraries/irrlicht-1.8/include/IQ3Shader.h884
1 files changed, 884 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/include/IQ3Shader.h b/libraries/irrlicht-1.8/include/IQ3Shader.h
new file mode 100644
index 0000000..080471a
--- /dev/null
+++ b/libraries/irrlicht-1.8/include/IQ3Shader.h
@@ -0,0 +1,884 @@
1// Copyright (C) 2006-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#ifndef __I_Q3_LEVEL_SHADER_H_INCLUDED__
6#define __I_Q3_LEVEL_SHADER_H_INCLUDED__
7
8#include "irrArray.h"
9#include "fast_atof.h"
10#include "IFileSystem.h"
11#include "IVideoDriver.h"
12#include "coreutil.h"
13
14namespace irr
15{
16namespace scene
17{
18namespace quake3
19{
20
21 static core::stringc irrEmptyStringc("");
22
23 //! Hold the different Mesh Types used for getMesh
24 enum eQ3MeshIndex
25 {
26 E_Q3_MESH_GEOMETRY = 0,
27 E_Q3_MESH_ITEMS,
28 E_Q3_MESH_BILLBOARD,
29 E_Q3_MESH_FOG,
30 E_Q3_MESH_UNRESOLVED,
31 E_Q3_MESH_SIZE
32 };
33
34 /*! used to customize Quake3 BSP Loader
35 */
36
37 struct Q3LevelLoadParameter
38 {
39 Q3LevelLoadParameter ()
40 :defaultLightMapMaterial ( video::EMT_LIGHTMAP_M4 ),
41 defaultModulate ( video::EMFN_MODULATE_4X ),
42 defaultFilter ( video::EMF_BILINEAR_FILTER ),
43 patchTesselation ( 8 ),
44 verbose ( 0 ),
45 startTime ( 0 ), endTime ( 0 ),
46 mergeShaderBuffer ( 1 ),
47 cleanUnResolvedMeshes ( 1 ),
48 loadAllShaders ( 0 ),
49 loadSkyShader ( 0 ),
50 alpharef ( 1 ),
51 swapLump ( 0 ),
52 #ifdef __BIG_ENDIAN__
53 swapHeader ( 1 )
54 #else
55 swapHeader ( 0 )
56 #endif
57 {
58 memcpy ( scriptDir, "scripts\x0", 8 );
59 }
60
61 video::E_MATERIAL_TYPE defaultLightMapMaterial;
62 video::E_MODULATE_FUNC defaultModulate;
63 video::E_MATERIAL_FLAG defaultFilter;
64 s32 patchTesselation;
65 s32 verbose;
66 u32 startTime;
67 u32 endTime;
68 s32 mergeShaderBuffer;
69 s32 cleanUnResolvedMeshes;
70 s32 loadAllShaders;
71 s32 loadSkyShader;
72 s32 alpharef;
73 s32 swapLump;
74 s32 swapHeader;
75 c8 scriptDir [ 64 ];
76 };
77
78 // some useful typedefs
79 typedef core::array< core::stringc > tStringList;
80 typedef core::array< video::ITexture* > tTexArray;
81
82 // string helper.. TODO: move to generic files
83 inline s16 isEqual ( const core::stringc &string, u32 &pos, const c8 *list[], u16 listSize )
84 {
85 const char * in = string.c_str () + pos;
86
87 for ( u16 i = 0; i != listSize; ++i )
88 {
89 if (string.size() < pos)
90 return -2;
91 u32 len = (u32) strlen ( list[i] );
92 if (string.size() < pos+len)
93 continue;
94 if ( in [len] != 0 && in [len] != ' ' )
95 continue;
96 if ( strncmp ( in, list[i], len ) )
97 continue;
98
99 pos += len + 1;
100 return (s16) i;
101 }
102 return -2;
103 }
104
105 inline f32 getAsFloat ( const core::stringc &string, u32 &pos )
106 {
107 const char * in = string.c_str () + pos;
108
109 f32 value = 0.f;
110 pos += (u32) ( core::fast_atof_move ( in, value ) - in ) + 1;
111 return value;
112 }
113
114 //! get a quake3 vector translated to irrlicht position (x,-z,y )
115 inline core::vector3df getAsVector3df ( const core::stringc &string, u32 &pos )
116 {
117 core::vector3df v;
118
119 v.X = getAsFloat ( string, pos );
120 v.Z = getAsFloat ( string, pos );
121 v.Y = getAsFloat ( string, pos );
122
123 return v;
124 }
125
126
127 /*
128 extract substrings
129 */
130 inline void getAsStringList ( tStringList &list, s32 max, const core::stringc &string, u32 &startPos )
131 {
132 list.clear ();
133
134 s32 finish = 0;
135 s32 endPos;
136 do
137 {
138 endPos = string.findNext ( ' ', startPos );
139 if ( endPos == -1 )
140 {
141 finish = 1;
142 endPos = string.size();
143 }
144
145 list.push_back ( string.subString ( startPos, endPos - startPos ) );
146 startPos = endPos + 1;
147
148 if ( list.size() >= (u32) max )
149 finish = 1;
150
151 } while ( !finish );
152
153 }
154
155 //! A blend function for a q3 shader.
156 struct SBlendFunc
157 {
158 SBlendFunc ( video::E_MODULATE_FUNC mod )
159 : type ( video::EMT_SOLID ), modulate ( mod ),
160 param0( 0.f ),
161 isTransparent ( 0 ) {}
162
163 video::E_MATERIAL_TYPE type;
164 video::E_MODULATE_FUNC modulate;
165
166 f32 param0;
167 u32 isTransparent;
168 };
169
170 // parses the content of Variable cull
171 inline bool getCullingFunction ( const core::stringc &cull )
172 {
173 if ( cull.size() == 0 )
174 return true;
175
176 bool ret = true;
177 static const c8 * funclist[] = { "none", "disable", "twosided" };
178
179 u32 pos = 0;
180 switch ( isEqual ( cull, pos, funclist, 3 ) )
181 {
182 case 0:
183 case 1:
184 case 2:
185 ret = false;
186 break;
187 }
188 return ret;
189 }
190
191 // parses the content of Variable depthfunc
192 // return a z-test
193 inline u8 getDepthFunction ( const core::stringc &string )
194 {
195 u8 ret = video::ECFN_LESSEQUAL;
196
197 if ( string.size() == 0 )
198 return ret;
199
200 static const c8 * funclist[] = { "lequal","equal" };
201
202 u32 pos = 0;
203 switch ( isEqual ( string, pos, funclist, 2 ) )
204 {
205 case 0:
206 ret = video::ECFN_LESSEQUAL;
207 case 1:
208 ret = video::ECFN_EQUAL;
209 break;
210 }
211 return ret;
212 }
213
214
215 /*!
216 parses the content of Variable blendfunc,alphafunc
217 it also make a hint for rendering as transparent or solid node.
218
219 we assume a typical quake scene would look like this..
220 1) Big Static Mesh ( solid )
221 2) static scene item ( may use transparency ) but rendered in the solid pass
222 3) additional transparency item in the transparent pass
223
224 it's not 100% accurate! it just empirical..
225 */
226 inline static void getBlendFunc ( const core::stringc &string, SBlendFunc &blendfunc )
227 {
228 if ( string.size() == 0 )
229 return;
230
231 // maps to E_BLEND_FACTOR
232 static const c8 * funclist[] =
233 {
234 "gl_zero",
235 "gl_one",
236 "gl_dst_color",
237 "gl_one_minus_dst_color",
238 "gl_src_color",
239 "gl_one_minus_src_color",
240 "gl_src_alpha",
241 "gl_one_minus_src_alpha",
242 "gl_dst_alpha",
243 "gl_one_minus_dst_alpha",
244 "gl_src_alpha_sat",
245
246 "add",
247 "filter",
248 "blend",
249
250 "ge128",
251 "gt0",
252 };
253
254
255 u32 pos = 0;
256 s32 srcFact = isEqual ( string, pos, funclist, 16 );
257
258 if ( srcFact < 0 )
259 return;
260
261 u32 resolved = 0;
262 s32 dstFact = isEqual ( string, pos, funclist, 16 );
263
264 switch ( srcFact )
265 {
266 case video::EBF_ZERO:
267 switch ( dstFact )
268 {
269 // gl_zero gl_src_color == gl_dst_color gl_zero
270 case video::EBF_SRC_COLOR:
271 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
272 blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate );
273 blendfunc.isTransparent = 1;
274 resolved = 1;
275 break;
276 } break;
277
278 case video::EBF_ONE:
279 switch ( dstFact )
280 {
281 // gl_one gl_zero
282 case video::EBF_ZERO:
283 blendfunc.type = video::EMT_SOLID;
284 blendfunc.isTransparent = 0;
285 resolved = 1;
286 break;
287
288 // gl_one gl_one
289 case video::EBF_ONE:
290 blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR;
291 blendfunc.isTransparent = 1;
292 resolved = 1;
293 break;
294 } break;
295
296 case video::EBF_SRC_ALPHA:
297 switch ( dstFact )
298 {
299 // gl_src_alpha gl_one_minus_src_alpha
300 case video::EBF_ONE_MINUS_SRC_ALPHA:
301 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
302 blendfunc.param0 = 1.f/255.f;
303 blendfunc.isTransparent = 1;
304 resolved = 1;
305 break;
306 } break;
307
308 case 11:
309 // add
310 blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR;
311 blendfunc.isTransparent = 1;
312 resolved = 1;
313 break;
314 case 12:
315 // filter = gl_dst_color gl_zero or gl_zero gl_src_color
316 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
317 blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate );
318 blendfunc.isTransparent = 1;
319 resolved = 1;
320 break;
321 case 13:
322 // blend = gl_src_alpha gl_one_minus_src_alpha
323 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
324 blendfunc.param0 = 1.f/255.f;
325 blendfunc.isTransparent = 1;
326 resolved = 1;
327 break;
328 case 14:
329 // alphafunc ge128
330 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
331 blendfunc.param0 = 0.5f;
332 blendfunc.isTransparent = 1;
333 resolved = 1;
334 break;
335 case 15:
336 // alphafunc gt0
337 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
338 blendfunc.param0 = 1.f / 255.f;
339 blendfunc.isTransparent = 1;
340 resolved = 1;
341 break;
342
343 }
344
345 // use the generic blender
346 if ( 0 == resolved )
347 {
348 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
349 blendfunc.param0 = video::pack_textureBlendFunc (
350 (video::E_BLEND_FACTOR) srcFact,
351 (video::E_BLEND_FACTOR) dstFact,
352 blendfunc.modulate);
353
354 blendfunc.isTransparent = 1;
355 }
356 }
357
358 // random noise [-1;1]
359 struct Noiser
360 {
361 static f32 get ()
362 {
363 static u32 RandomSeed = 0x69666966;
364 RandomSeed = (RandomSeed * 3631 + 1);
365
366 f32 value = ( (f32) (RandomSeed & 0x7FFF ) * (1.0f / (f32)(0x7FFF >> 1) ) ) - 1.f;
367 return value;
368 }
369 };
370
371 enum eQ3ModifierFunction
372 {
373 TCMOD = 0,
374 DEFORMVERTEXES = 1,
375 RGBGEN = 2,
376 TCGEN = 3,
377 MAP = 4,
378 ALPHAGEN = 5,
379
380 FUNCTION2 = 0x10,
381 SCROLL = FUNCTION2 + 1,
382 SCALE = FUNCTION2 + 2,
383 ROTATE = FUNCTION2 + 3,
384 STRETCH = FUNCTION2 + 4,
385 TURBULENCE = FUNCTION2 + 5,
386 WAVE = FUNCTION2 + 6,
387
388 IDENTITY = FUNCTION2 + 7,
389 VERTEX = FUNCTION2 + 8,
390 TEXTURE = FUNCTION2 + 9,
391 LIGHTMAP = FUNCTION2 + 10,
392 ENVIRONMENT = FUNCTION2 + 11,
393 DOLLAR_LIGHTMAP = FUNCTION2 + 12,
394 BULGE = FUNCTION2 + 13,
395 AUTOSPRITE = FUNCTION2 + 14,
396 AUTOSPRITE2 = FUNCTION2 + 15,
397 TRANSFORM = FUNCTION2 + 16,
398 EXACTVERTEX = FUNCTION2 + 17,
399 CONSTANT = FUNCTION2 + 18,
400 LIGHTINGSPECULAR = FUNCTION2 + 19,
401 MOVE = FUNCTION2 + 20,
402 NORMAL = FUNCTION2 + 21,
403 IDENTITYLIGHTING = FUNCTION2 + 22,
404
405 WAVE_MODIFIER_FUNCTION = 0x30,
406 SINUS = WAVE_MODIFIER_FUNCTION + 1,
407 COSINUS = WAVE_MODIFIER_FUNCTION + 2,
408 SQUARE = WAVE_MODIFIER_FUNCTION + 3,
409 TRIANGLE = WAVE_MODIFIER_FUNCTION + 4,
410 SAWTOOTH = WAVE_MODIFIER_FUNCTION + 5,
411 SAWTOOTH_INVERSE = WAVE_MODIFIER_FUNCTION + 6,
412 NOISE = WAVE_MODIFIER_FUNCTION + 7,
413
414
415 UNKNOWN = -2
416
417 };
418
419 struct SModifierFunction
420 {
421 SModifierFunction ()
422 : masterfunc0 ( UNKNOWN ), masterfunc1( UNKNOWN ), func ( SINUS ),
423 tcgen( TEXTURE ), rgbgen ( IDENTITY ), alphagen ( UNKNOWN ),
424 base ( 0 ), amp ( 1 ), phase ( 0 ), frequency ( 1 ),
425 wave ( 1 ),
426 x ( 0 ), y ( 0 ), z( 0 ), count( 0 ) {}
427
428 // "tcmod","deformvertexes","rgbgen", "tcgen"
429 eQ3ModifierFunction masterfunc0;
430 // depends
431 eQ3ModifierFunction masterfunc1;
432 // depends
433 eQ3ModifierFunction func;
434
435 eQ3ModifierFunction tcgen;
436 eQ3ModifierFunction rgbgen;
437 eQ3ModifierFunction alphagen;
438
439 union
440 {
441 f32 base;
442 f32 bulgewidth;
443 };
444
445 union
446 {
447 f32 amp;
448 f32 bulgeheight;
449 };
450
451 f32 phase;
452
453 union
454 {
455 f32 frequency;
456 f32 bulgespeed;
457 };
458
459 union
460 {
461 f32 wave;
462 f32 div;
463 };
464
465 f32 x;
466 f32 y;
467 f32 z;
468 u32 count;
469
470 f32 evaluate ( f32 dt ) const
471 {
472 // phase in 0 and 1..
473 f32 x = core::fract( (dt + phase ) * frequency );
474 f32 y = 0.f;
475
476 switch ( func )
477 {
478 case SINUS:
479 y = sinf ( x * core::PI * 2.f );
480 break;
481 case COSINUS:
482 y = cosf ( x * core::PI * 2.f );
483 break;
484 case SQUARE:
485 y = x < 0.5f ? 1.f : -1.f;
486 break;
487 case TRIANGLE:
488 y = x < 0.5f ? ( 4.f * x ) - 1.f : ( -4.f * x ) + 3.f;
489 break;
490 case SAWTOOTH:
491 y = x;
492 break;
493 case SAWTOOTH_INVERSE:
494 y = 1.f - x;
495 break;
496 case NOISE:
497 y = Noiser::get();
498 break;
499 default:
500 break;
501 }
502
503 return base + ( y * amp );
504 }
505
506
507 };
508
509 inline core::vector3df getMD3Normal ( u32 i, u32 j )
510 {
511 const f32 lng = i * 2.0f * core::PI / 255.0f;
512 const f32 lat = j * 2.0f * core::PI / 255.0f;
513 return core::vector3df(cosf ( lat ) * sinf ( lng ),
514 sinf ( lat ) * sinf ( lng ),
515 cosf ( lng ));
516 }
517
518 //
519 inline void getModifierFunc ( SModifierFunction& fill, const core::stringc &string, u32 &pos )
520 {
521 if ( string.size() == 0 )
522 return;
523
524 static const c8 * funclist[] =
525 {
526 "sin","cos","square",
527 "triangle", "sawtooth","inversesawtooth", "noise"
528 };
529
530 fill.func = (eQ3ModifierFunction) isEqual ( string,pos, funclist,7 );
531 fill.func = fill.func == UNKNOWN ? SINUS : (eQ3ModifierFunction) ((u32) fill.func + WAVE_MODIFIER_FUNCTION + 1);
532
533 fill.base = getAsFloat ( string, pos );
534 fill.amp = getAsFloat ( string, pos );
535 fill.phase = getAsFloat ( string, pos );
536 fill.frequency = getAsFloat ( string, pos );
537 }
538
539
540 // name = "a b c .."
541 struct SVariable
542 {
543 core::stringc name;
544 core::stringc content;
545
546 SVariable ( const c8 * n, const c8 *c = 0 ) : name ( n ), content (c) {}
547 virtual ~SVariable () {}
548
549 void clear ()
550 {
551 name = "";
552 content = "";
553 }
554
555 s32 isValid () const
556 {
557 return name.size();
558 }
559
560 bool operator == ( const SVariable &other ) const
561 {
562 return 0 == strcmp ( name.c_str(), other.name.c_str () );
563 }
564
565 bool operator < ( const SVariable &other ) const
566 {
567 return 0 > strcmp ( name.c_str(), other.name.c_str () );
568 }
569
570 };
571
572
573 // string database. "a" = "Hello", "b" = "1234.6"
574 struct SVarGroup
575 {
576 SVarGroup () { Variable.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); }
577 virtual ~SVarGroup () {}
578
579 u32 isDefined ( const c8 * name, const c8 * content = 0 ) const
580 {
581 for ( u32 i = 0; i != Variable.size (); ++i )
582 {
583 if ( 0 == strcmp ( Variable[i].name.c_str(), name ) &&
584 ( 0 == content || strstr ( Variable[i].content.c_str(), content ) )
585 )
586 {
587 return i + 1;
588 }
589 }
590 return 0;
591 }
592
593 // searches for Variable name and returns is content
594 // if Variable is not found a reference to an Empty String is returned
595 const core::stringc &get( const c8 * name ) const
596 {
597 SVariable search ( name );
598 s32 index = Variable.linear_search ( search );
599 if ( index < 0 )
600 return irrEmptyStringc;
601
602 return Variable [ index ].content;
603 }
604
605 // set the Variable name
606 void set ( const c8 * name, const c8 * content = 0 )
607 {
608 u32 index = isDefined ( name, 0 );
609 if ( 0 == index )
610 {
611 Variable.push_back ( SVariable ( name, content ) );
612 }
613 else
614 {
615 Variable [ index ].content = content;
616 }
617 }
618
619
620 core::array < SVariable > Variable;
621 };
622
623 //! holding a group a variable
624 struct SVarGroupList: public IReferenceCounted
625 {
626 SVarGroupList ()
627 {
628 VariableGroup.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
629 }
630 virtual ~SVarGroupList () {}
631
632 core::array < SVarGroup > VariableGroup;
633 };
634
635
636 //! A Parsed Shader Holding Variables ordered in Groups
637 struct IShader
638 {
639 IShader ()
640 : ID ( 0 ), VarGroup ( 0 ) {}
641 virtual ~IShader () {}
642
643 void operator = (const IShader &other )
644 {
645 ID = other.ID;
646 VarGroup = other.VarGroup;
647 name = other.name;
648 }
649
650 bool operator == (const IShader &other ) const
651 {
652 return 0 == strcmp ( name.c_str(), other.name.c_str () );
653 //return name == other.name;
654 }
655
656 bool operator < (const IShader &other ) const
657 {
658 return strcmp ( name.c_str(), other.name.c_str () ) < 0;
659 //return name < other.name;
660 }
661
662 u32 getGroupSize () const
663 {
664 if ( 0 == VarGroup )
665 return 0;
666 return VarGroup->VariableGroup.size ();
667 }
668
669 const SVarGroup * getGroup ( u32 stage ) const
670 {
671 if ( 0 == VarGroup || stage >= VarGroup->VariableGroup.size () )
672 return 0;
673
674 return &VarGroup->VariableGroup [ stage ];
675 }
676
677 // id
678 s32 ID;
679 SVarGroupList *VarGroup; // reference
680
681 // Shader: shader name ( also first variable in first Vargroup )
682 // Entity: classname ( variable in Group(1) )
683 core::stringc name;
684 };
685
686 typedef IShader IEntity;
687
688 typedef core::array < IEntity > tQ3EntityList;
689
690 /*
691 dump shader like original layout, regardless of internal data holding
692 no recursive folding..
693 */
694 inline void dumpVarGroup ( core::stringc &dest, const SVarGroup * group, s32 stack )
695 {
696 core::stringc buf;
697 s32 i;
698
699
700 if ( stack > 0 )
701 {
702 buf = "";
703 for ( i = 0; i < stack - 1; ++i )
704 buf += '\t';
705
706 buf += "{\n";
707 dest.append ( buf );
708 }
709
710 for ( u32 g = 0; g != group->Variable.size(); ++g )
711 {
712 buf = "";
713 for ( i = 0; i < stack; ++i )
714 buf += '\t';
715
716 buf += group->Variable[g].name;
717 buf += " ";
718 buf += group->Variable[g].content;
719 buf += "\n";
720 dest.append ( buf );
721 }
722
723 if ( stack > 1 )
724 {
725 buf = "";
726 for ( i = 0; i < stack - 1; ++i )
727 buf += '\t';
728
729 buf += "}\n";
730 dest.append ( buf );
731 }
732
733 }
734
735 /*!
736 dump a Shader or an Entity
737 */
738 inline core::stringc & dumpShader ( core::stringc &dest, const IShader * shader, bool entity = false )
739 {
740 if ( 0 == shader )
741 return dest;
742
743 const SVarGroup * group;
744
745 const u32 size = shader->VarGroup->VariableGroup.size ();
746 for ( u32 i = 0; i != size; ++i )
747 {
748 group = &shader->VarGroup->VariableGroup[ i ];
749 dumpVarGroup ( dest, group, core::clamp( (int)i, 0, 2 ) );
750 }
751
752 if ( !entity )
753 {
754 if ( size <= 1 )
755 {
756 dest.append ( "{\n" );
757 }
758 dest.append ( "}\n" );
759 }
760 return dest;
761 }
762
763
764 /*
765 quake3 doesn't care much about tga & jpg
766 load one or multiple files stored in name started at startPos to the texture array textures
767 if texture is not loaded 0 will be added ( to find missing textures easier)
768 */
769 inline void getTextures(tTexArray &textures,
770 const core::stringc &name, u32 &startPos,
771 io::IFileSystem *fileSystem,
772 video::IVideoDriver* driver)
773 {
774 static const char* extension[] =
775 {
776 ".jpg",
777 ".jpeg",
778 ".png",
779 ".dds",
780 ".tga",
781 ".bmp",
782 ".pcx"
783 };
784
785 tStringList stringList;
786 getAsStringList(stringList, -1, name, startPos);
787
788 textures.clear();
789
790 io::path loadFile;
791 for ( u32 i = 0; i!= stringList.size (); ++i )
792 {
793 video::ITexture* texture = 0;
794 for (u32 g = 0; g != 7 ; ++g)
795 {
796 core::cutFilenameExtension ( loadFile, stringList[i] );
797
798 if ( loadFile == "$whiteimage" )
799 {
800 texture = driver->getTexture( "$whiteimage" );
801 if ( 0 == texture )
802 {
803 core::dimension2du s ( 2, 2 );
804 u32 image[4] = { 0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
805 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
806 texture = driver->addTexture( "$whiteimage", w );
807 w->drop ();
808 }
809
810 }
811 else
812 if ( loadFile == "$redimage" )
813 {
814 texture = driver->getTexture( "$redimage" );
815 if ( 0 == texture )
816 {
817 core::dimension2du s ( 2, 2 );
818 u32 image[4] = { 0xFFFF0000, 0xFFFF0000,0xFFFF0000,0xFFFF0000 };
819 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
820 texture = driver->addTexture( "$redimage", w );
821 w->drop ();
822 }
823 }
824 else
825 if ( loadFile == "$blueimage" )
826 {
827 texture = driver->getTexture( "$blueimage" );
828 if ( 0 == texture )
829 {
830 core::dimension2du s ( 2, 2 );
831 u32 image[4] = { 0xFF0000FF, 0xFF0000FF,0xFF0000FF,0xFF0000FF };
832 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
833 texture = driver->addTexture( "$blueimage", w );
834 w->drop ();
835 }
836 }
837 else
838 if ( loadFile == "$checkerimage" )
839 {
840 texture = driver->getTexture( "$checkerimage" );
841 if ( 0 == texture )
842 {
843 core::dimension2du s ( 2, 2 );
844 u32 image[4] = { 0xFFFFFFFF, 0xFF000000,0xFF000000,0xFFFFFFFF };
845 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
846 texture = driver->addTexture( "$checkerimage", w );
847 w->drop ();
848 }
849 }
850 else
851 if ( loadFile == "$lightmap" )
852 {
853 texture = 0;
854 }
855 else
856 {
857 loadFile.append ( extension[g] );
858 }
859
860 if ( fileSystem->existFile ( loadFile ) )
861 {
862 texture = driver->getTexture( loadFile );
863 if ( texture )
864 break;
865 texture = 0;
866 }
867 }
868 // take 0 Texture
869 textures.push_back(texture);
870 }
871 }
872
873
874 //! Manages various Quake3 Shader Styles
875 class IShaderManager : public IReferenceCounted
876 {
877 };
878
879} // end namespace quake3
880} // end namespace scene
881} // end namespace irr
882
883#endif
884