00001
00002
00003
00004
00005 #ifndef __I_Q3_LEVEL_SHADER_H_INCLUDED__
00006 #define __I_Q3_LEVEL_SHADER_H_INCLUDED__
00007
00008 #include "irrArray.h"
00009 #include "fast_atof.h"
00010 #include "IFileSystem.h"
00011 #include "IVideoDriver.h"
00012 #include "coreutil.h"
00013
00014 namespace irr
00015 {
00016 namespace scene
00017 {
00018 namespace quake3
00019 {
00020
00021 static core::stringc irrEmptyStringc("");
00022
00024 enum eQ3MeshIndex
00025 {
00026 E_Q3_MESH_GEOMETRY = 0,
00027 E_Q3_MESH_ITEMS,
00028 E_Q3_MESH_BILLBOARD,
00029 E_Q3_MESH_FOG,
00030 E_Q3_MESH_UNRESOLVED,
00031 E_Q3_MESH_SIZE
00032 };
00033
00037 struct Q3LevelLoadParameter
00038 {
00039 Q3LevelLoadParameter ()
00040 :defaultLightMapMaterial ( video::EMT_LIGHTMAP_M4 ),
00041 defaultModulate ( video::EMFN_MODULATE_4X ),
00042 defaultFilter ( video::EMF_BILINEAR_FILTER ),
00043 patchTesselation ( 8 ),
00044 verbose ( 0 ),
00045 startTime ( 0 ), endTime ( 0 ),
00046 mergeShaderBuffer ( 1 ),
00047 cleanUnResolvedMeshes ( 1 ),
00048 loadAllShaders ( 0 ),
00049 loadSkyShader ( 0 ),
00050 alpharef ( 1 ),
00051 swapLump ( 0 ),
00052 #ifdef __BIG_ENDIAN__
00053 swapHeader ( 1 )
00054 #else
00055 swapHeader ( 0 )
00056 #endif
00057 {
00058 memcpy ( scriptDir, "scripts\x0", 8 );
00059 }
00060
00061 video::E_MATERIAL_TYPE defaultLightMapMaterial;
00062 video::E_MODULATE_FUNC defaultModulate;
00063 video::E_MATERIAL_FLAG defaultFilter;
00064 s32 patchTesselation;
00065 s32 verbose;
00066 u32 startTime;
00067 u32 endTime;
00068 s32 mergeShaderBuffer;
00069 s32 cleanUnResolvedMeshes;
00070 s32 loadAllShaders;
00071 s32 loadSkyShader;
00072 s32 alpharef;
00073 s32 swapLump;
00074 s32 swapHeader;
00075 c8 scriptDir [ 64 ];
00076 };
00077
00078
00079 typedef core::array< core::stringc > tStringList;
00080 typedef core::array< video::ITexture* > tTexArray;
00081
00082
00083 inline s16 isEqual ( const core::stringc &string, u32 &pos, const c8 *list[], u16 listSize )
00084 {
00085 const char * in = string.c_str () + pos;
00086
00087 for ( u16 i = 0; i != listSize; ++i )
00088 {
00089 if (string.size() < pos)
00090 return -2;
00091 u32 len = (u32) strlen ( list[i] );
00092 if (string.size() < pos+len)
00093 continue;
00094 if ( in [len] != 0 && in [len] != ' ' )
00095 continue;
00096 if ( strncmp ( in, list[i], len ) )
00097 continue;
00098
00099 pos += len + 1;
00100 return (s16) i;
00101 }
00102 return -2;
00103 }
00104
00105 inline f32 getAsFloat ( const core::stringc &string, u32 &pos )
00106 {
00107 const char * in = string.c_str () + pos;
00108
00109 f32 value = 0.f;
00110 pos += (u32) ( core::fast_atof_move ( in, value ) - in ) + 1;
00111 return value;
00112 }
00113
00115 inline core::vector3df getAsVector3df ( const core::stringc &string, u32 &pos )
00116 {
00117 core::vector3df v;
00118
00119 v.X = getAsFloat ( string, pos );
00120 v.Z = getAsFloat ( string, pos );
00121 v.Y = getAsFloat ( string, pos );
00122
00123 return v;
00124 }
00125
00126
00127
00128
00129
00130 inline void getAsStringList ( tStringList &list, s32 max, const core::stringc &string, u32 &startPos )
00131 {
00132 list.clear ();
00133
00134 s32 finish = 0;
00135 s32 endPos;
00136 do
00137 {
00138 endPos = string.findNext ( ' ', startPos );
00139 if ( endPos == -1 )
00140 {
00141 finish = 1;
00142 endPos = string.size();
00143 }
00144
00145 list.push_back ( string.subString ( startPos, endPos - startPos ) );
00146 startPos = endPos + 1;
00147
00148 if ( list.size() >= (u32) max )
00149 finish = 1;
00150
00151 } while ( !finish );
00152
00153 }
00154
00156 struct SBlendFunc
00157 {
00158 SBlendFunc ( video::E_MODULATE_FUNC mod )
00159 : type ( video::EMT_SOLID ), modulate ( mod ),
00160 param0( 0.f ),
00161 isTransparent ( 0 ) {}
00162
00163 video::E_MATERIAL_TYPE type;
00164 video::E_MODULATE_FUNC modulate;
00165
00166 f32 param0;
00167 u32 isTransparent;
00168 };
00169
00170
00171 inline bool getCullingFunction ( const core::stringc &cull )
00172 {
00173 if ( cull.size() == 0 )
00174 return true;
00175
00176 bool ret = true;
00177 static const c8 * funclist[] = { "none", "disable", "twosided" };
00178
00179 u32 pos = 0;
00180 switch ( isEqual ( cull, pos, funclist, 3 ) )
00181 {
00182 case 0:
00183 case 1:
00184 case 2:
00185 ret = false;
00186 break;
00187 }
00188 return ret;
00189 }
00190
00191
00192
00193 inline u8 getDepthFunction ( const core::stringc &string )
00194 {
00195 u8 ret = video::ECFN_LESSEQUAL;
00196
00197 if ( string.size() == 0 )
00198 return ret;
00199
00200 static const c8 * funclist[] = { "lequal","equal" };
00201
00202 u32 pos = 0;
00203 switch ( isEqual ( string, pos, funclist, 2 ) )
00204 {
00205 case 0:
00206 ret = video::ECFN_LESSEQUAL;
00207 case 1:
00208 ret = video::ECFN_EQUAL;
00209 break;
00210 }
00211 return ret;
00212 }
00213
00214
00226 inline static void getBlendFunc ( const core::stringc &string, SBlendFunc &blendfunc )
00227 {
00228 if ( string.size() == 0 )
00229 return;
00230
00231
00232 static const c8 * funclist[] =
00233 {
00234 "gl_zero",
00235 "gl_one",
00236 "gl_dst_color",
00237 "gl_one_minus_dst_color",
00238 "gl_src_color",
00239 "gl_one_minus_src_color",
00240 "gl_src_alpha",
00241 "gl_one_minus_src_alpha",
00242 "gl_dst_alpha",
00243 "gl_one_minus_dst_alpha",
00244 "gl_src_alpha_sat",
00245
00246 "add",
00247 "filter",
00248 "blend",
00249
00250 "ge128",
00251 "gt0",
00252 };
00253
00254
00255 u32 pos = 0;
00256 s32 srcFact = isEqual ( string, pos, funclist, 16 );
00257
00258 if ( srcFact < 0 )
00259 return;
00260
00261 u32 resolved = 0;
00262 s32 dstFact = isEqual ( string, pos, funclist, 16 );
00263
00264 switch ( srcFact )
00265 {
00266 case video::EBF_ZERO:
00267 switch ( dstFact )
00268 {
00269
00270 case video::EBF_SRC_COLOR:
00271 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00272 blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate );
00273 blendfunc.isTransparent = 1;
00274 resolved = 1;
00275 break;
00276 } break;
00277
00278 case video::EBF_ONE:
00279 switch ( dstFact )
00280 {
00281
00282 case video::EBF_ZERO:
00283 blendfunc.type = video::EMT_SOLID;
00284 blendfunc.isTransparent = 0;
00285 resolved = 1;
00286 break;
00287
00288
00289 case video::EBF_ONE:
00290 blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR;
00291 blendfunc.isTransparent = 1;
00292 resolved = 1;
00293 break;
00294 } break;
00295
00296 case video::EBF_SRC_ALPHA:
00297 switch ( dstFact )
00298 {
00299
00300 case video::EBF_ONE_MINUS_SRC_ALPHA:
00301 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00302 blendfunc.param0 = 1.f/255.f;
00303 blendfunc.isTransparent = 1;
00304 resolved = 1;
00305 break;
00306 } break;
00307
00308 case 11:
00309
00310 blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR;
00311 blendfunc.isTransparent = 1;
00312 resolved = 1;
00313 break;
00314 case 12:
00315
00316 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00317 blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate );
00318 blendfunc.isTransparent = 1;
00319 resolved = 1;
00320 break;
00321 case 13:
00322
00323 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00324 blendfunc.param0 = 1.f/255.f;
00325 blendfunc.isTransparent = 1;
00326 resolved = 1;
00327 break;
00328 case 14:
00329
00330 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00331 blendfunc.param0 = 0.5f;
00332 blendfunc.isTransparent = 1;
00333 resolved = 1;
00334 break;
00335 case 15:
00336
00337 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00338 blendfunc.param0 = 1.f / 255.f;
00339 blendfunc.isTransparent = 1;
00340 resolved = 1;
00341 break;
00342
00343 }
00344
00345
00346 if ( 0 == resolved )
00347 {
00348 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00349 blendfunc.param0 = video::pack_textureBlendFunc (
00350 (video::E_BLEND_FACTOR) srcFact,
00351 (video::E_BLEND_FACTOR) dstFact,
00352 blendfunc.modulate);
00353
00354 blendfunc.isTransparent = 1;
00355 }
00356 }
00357
00358
00359 struct Noiser
00360 {
00361 static f32 get ()
00362 {
00363 static u32 RandomSeed = 0x69666966;
00364 RandomSeed = (RandomSeed * 3631 + 1);
00365
00366 f32 value = ( (f32) (RandomSeed & 0x7FFF ) * (1.0f / (f32)(0x7FFF >> 1) ) ) - 1.f;
00367 return value;
00368 }
00369 };
00370
00371 enum eQ3ModifierFunction
00372 {
00373 TCMOD = 0,
00374 DEFORMVERTEXES = 1,
00375 RGBGEN = 2,
00376 TCGEN = 3,
00377 MAP = 4,
00378 ALPHAGEN = 5,
00379
00380 FUNCTION2 = 0x10,
00381 SCROLL = FUNCTION2 + 1,
00382 SCALE = FUNCTION2 + 2,
00383 ROTATE = FUNCTION2 + 3,
00384 STRETCH = FUNCTION2 + 4,
00385 TURBULENCE = FUNCTION2 + 5,
00386 WAVE = FUNCTION2 + 6,
00387
00388 IDENTITY = FUNCTION2 + 7,
00389 VERTEX = FUNCTION2 + 8,
00390 TEXTURE = FUNCTION2 + 9,
00391 LIGHTMAP = FUNCTION2 + 10,
00392 ENVIRONMENT = FUNCTION2 + 11,
00393 DOLLAR_LIGHTMAP = FUNCTION2 + 12,
00394 BULGE = FUNCTION2 + 13,
00395 AUTOSPRITE = FUNCTION2 + 14,
00396 AUTOSPRITE2 = FUNCTION2 + 15,
00397 TRANSFORM = FUNCTION2 + 16,
00398 EXACTVERTEX = FUNCTION2 + 17,
00399 CONSTANT = FUNCTION2 + 18,
00400 LIGHTINGSPECULAR = FUNCTION2 + 19,
00401 MOVE = FUNCTION2 + 20,
00402 NORMAL = FUNCTION2 + 21,
00403 IDENTITYLIGHTING = FUNCTION2 + 22,
00404
00405 WAVE_MODIFIER_FUNCTION = 0x30,
00406 SINUS = WAVE_MODIFIER_FUNCTION + 1,
00407 COSINUS = WAVE_MODIFIER_FUNCTION + 2,
00408 SQUARE = WAVE_MODIFIER_FUNCTION + 3,
00409 TRIANGLE = WAVE_MODIFIER_FUNCTION + 4,
00410 SAWTOOTH = WAVE_MODIFIER_FUNCTION + 5,
00411 SAWTOOTH_INVERSE = WAVE_MODIFIER_FUNCTION + 6,
00412 NOISE = WAVE_MODIFIER_FUNCTION + 7,
00413
00414
00415 UNKNOWN = -2
00416
00417 };
00418
00419 struct SModifierFunction
00420 {
00421 SModifierFunction ()
00422 : masterfunc0 ( UNKNOWN ), masterfunc1( UNKNOWN ), func ( SINUS ),
00423 tcgen( TEXTURE ), rgbgen ( IDENTITY ), alphagen ( UNKNOWN ),
00424 base ( 0 ), amp ( 1 ), phase ( 0 ), frequency ( 1 ),
00425 wave ( 1 ),
00426 x ( 0 ), y ( 0 ), z( 0 ), count( 0 ) {}
00427
00428
00429 eQ3ModifierFunction masterfunc0;
00430
00431 eQ3ModifierFunction masterfunc1;
00432
00433 eQ3ModifierFunction func;
00434
00435 eQ3ModifierFunction tcgen;
00436 eQ3ModifierFunction rgbgen;
00437 eQ3ModifierFunction alphagen;
00438
00439 union
00440 {
00441 f32 base;
00442 f32 bulgewidth;
00443 };
00444
00445 union
00446 {
00447 f32 amp;
00448 f32 bulgeheight;
00449 };
00450
00451 f32 phase;
00452
00453 union
00454 {
00455 f32 frequency;
00456 f32 bulgespeed;
00457 };
00458
00459 union
00460 {
00461 f32 wave;
00462 f32 div;
00463 };
00464
00465 f32 x;
00466 f32 y;
00467 f32 z;
00468 u32 count;
00469
00470 f32 evaluate ( f32 dt ) const
00471 {
00472
00473 f32 x = core::fract( (dt + phase ) * frequency );
00474 f32 y = 0.f;
00475
00476 switch ( func )
00477 {
00478 case SINUS:
00479 y = sinf ( x * core::PI * 2.f );
00480 break;
00481 case COSINUS:
00482 y = cosf ( x * core::PI * 2.f );
00483 break;
00484 case SQUARE:
00485 y = x < 0.5f ? 1.f : -1.f;
00486 break;
00487 case TRIANGLE:
00488 y = x < 0.5f ? ( 4.f * x ) - 1.f : ( -4.f * x ) + 3.f;
00489 break;
00490 case SAWTOOTH:
00491 y = x;
00492 break;
00493 case SAWTOOTH_INVERSE:
00494 y = 1.f - x;
00495 break;
00496 case NOISE:
00497 y = Noiser::get();
00498 break;
00499 default:
00500 break;
00501 }
00502
00503 return base + ( y * amp );
00504 }
00505
00506
00507 };
00508
00509 inline core::vector3df getMD3Normal ( u32 i, u32 j )
00510 {
00511 const f32 lng = i * 2.0f * core::PI / 255.0f;
00512 const f32 lat = j * 2.0f * core::PI / 255.0f;
00513 return core::vector3df(cosf ( lat ) * sinf ( lng ),
00514 sinf ( lat ) * sinf ( lng ),
00515 cosf ( lng ));
00516 }
00517
00518
00519 inline void getModifierFunc ( SModifierFunction& fill, const core::stringc &string, u32 &pos )
00520 {
00521 if ( string.size() == 0 )
00522 return;
00523
00524 static const c8 * funclist[] =
00525 {
00526 "sin","cos","square",
00527 "triangle", "sawtooth","inversesawtooth", "noise"
00528 };
00529
00530 fill.func = (eQ3ModifierFunction) isEqual ( string,pos, funclist,7 );
00531 fill.func = fill.func == UNKNOWN ? SINUS : (eQ3ModifierFunction) ((u32) fill.func + WAVE_MODIFIER_FUNCTION + 1);
00532
00533 fill.base = getAsFloat ( string, pos );
00534 fill.amp = getAsFloat ( string, pos );
00535 fill.phase = getAsFloat ( string, pos );
00536 fill.frequency = getAsFloat ( string, pos );
00537 }
00538
00539
00540
00541 struct SVariable
00542 {
00543 core::stringc name;
00544 core::stringc content;
00545
00546 SVariable ( const c8 * n, const c8 *c = 0 ) : name ( n ), content (c) {}
00547 virtual ~SVariable () {}
00548
00549 void clear ()
00550 {
00551 name = "";
00552 content = "";
00553 }
00554
00555 s32 isValid () const
00556 {
00557 return name.size();
00558 }
00559
00560 bool operator == ( const SVariable &other ) const
00561 {
00562 return 0 == strcmp ( name.c_str(), other.name.c_str () );
00563 }
00564
00565 bool operator < ( const SVariable &other ) const
00566 {
00567 return 0 > strcmp ( name.c_str(), other.name.c_str () );
00568 }
00569
00570 };
00571
00572
00573
00574 struct SVarGroup
00575 {
00576 SVarGroup () { Variable.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); }
00577 virtual ~SVarGroup () {}
00578
00579 u32 isDefined ( const c8 * name, const c8 * content = 0 ) const
00580 {
00581 for ( u32 i = 0; i != Variable.size (); ++i )
00582 {
00583 if ( 0 == strcmp ( Variable[i].name.c_str(), name ) &&
00584 ( 0 == content || strstr ( Variable[i].content.c_str(), content ) )
00585 )
00586 {
00587 return i + 1;
00588 }
00589 }
00590 return 0;
00591 }
00592
00593
00594
00595 const core::stringc &get( const c8 * name ) const
00596 {
00597 SVariable search ( name );
00598 s32 index = Variable.linear_search ( search );
00599 if ( index < 0 )
00600 return irrEmptyStringc;
00601
00602 return Variable [ index ].content;
00603 }
00604
00605
00606 void set ( const c8 * name, const c8 * content = 0 )
00607 {
00608 u32 index = isDefined ( name, 0 );
00609 if ( 0 == index )
00610 {
00611 Variable.push_back ( SVariable ( name, content ) );
00612 }
00613 else
00614 {
00615 Variable [ index ].content = content;
00616 }
00617 }
00618
00619
00620 core::array < SVariable > Variable;
00621 };
00622
00624 struct SVarGroupList: public IReferenceCounted
00625 {
00626 SVarGroupList ()
00627 {
00628 VariableGroup.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
00629 }
00630 virtual ~SVarGroupList () {}
00631
00632 core::array < SVarGroup > VariableGroup;
00633 };
00634
00635
00637 struct IShader
00638 {
00639 IShader ()
00640 : ID ( 0 ), VarGroup ( 0 ) {}
00641 virtual ~IShader () {}
00642
00643 void operator = (const IShader &other )
00644 {
00645 ID = other.ID;
00646 VarGroup = other.VarGroup;
00647 name = other.name;
00648 }
00649
00650 bool operator == (const IShader &other ) const
00651 {
00652 return 0 == strcmp ( name.c_str(), other.name.c_str () );
00653
00654 }
00655
00656 bool operator < (const IShader &other ) const
00657 {
00658 return strcmp ( name.c_str(), other.name.c_str () ) < 0;
00659
00660 }
00661
00662 u32 getGroupSize () const
00663 {
00664 if ( 0 == VarGroup )
00665 return 0;
00666 return VarGroup->VariableGroup.size ();
00667 }
00668
00669 const SVarGroup * getGroup ( u32 stage ) const
00670 {
00671 if ( 0 == VarGroup || stage >= VarGroup->VariableGroup.size () )
00672 return 0;
00673
00674 return &VarGroup->VariableGroup [ stage ];
00675 }
00676
00677
00678 s32 ID;
00679 SVarGroupList *VarGroup;
00680
00681
00682
00683 core::stringc name;
00684 };
00685
00686 typedef IShader IEntity;
00687
00688 typedef core::array < IEntity > tQ3EntityList;
00689
00690
00691
00692
00693
00694 inline void dumpVarGroup ( core::stringc &dest, const SVarGroup * group, s32 stack )
00695 {
00696 core::stringc buf;
00697 s32 i;
00698
00699
00700 if ( stack > 0 )
00701 {
00702 buf = "";
00703 for ( i = 0; i < stack - 1; ++i )
00704 buf += '\t';
00705
00706 buf += "{\n";
00707 dest.append ( buf );
00708 }
00709
00710 for ( u32 g = 0; g != group->Variable.size(); ++g )
00711 {
00712 buf = "";
00713 for ( i = 0; i < stack; ++i )
00714 buf += '\t';
00715
00716 buf += group->Variable[g].name;
00717 buf += " ";
00718 buf += group->Variable[g].content;
00719 buf += "\n";
00720 dest.append ( buf );
00721 }
00722
00723 if ( stack > 1 )
00724 {
00725 buf = "";
00726 for ( i = 0; i < stack - 1; ++i )
00727 buf += '\t';
00728
00729 buf += "}\n";
00730 dest.append ( buf );
00731 }
00732
00733 }
00734
00738 inline core::stringc & dumpShader ( core::stringc &dest, const IShader * shader, bool entity = false )
00739 {
00740 if ( 0 == shader )
00741 return dest;
00742
00743 const SVarGroup * group;
00744
00745 const u32 size = shader->VarGroup->VariableGroup.size ();
00746 for ( u32 i = 0; i != size; ++i )
00747 {
00748 group = &shader->VarGroup->VariableGroup[ i ];
00749 dumpVarGroup ( dest, group, core::clamp( (int)i, 0, 2 ) );
00750 }
00751
00752 if ( !entity )
00753 {
00754 if ( size <= 1 )
00755 {
00756 dest.append ( "{\n" );
00757 }
00758 dest.append ( "}\n" );
00759 }
00760 return dest;
00761 }
00762
00763
00764
00765
00766
00767
00768
00769 inline void getTextures(tTexArray &textures,
00770 const core::stringc &name, u32 &startPos,
00771 io::IFileSystem *fileSystem,
00772 video::IVideoDriver* driver)
00773 {
00774 static const char* extension[] =
00775 {
00776 ".jpg",
00777 ".jpeg",
00778 ".png",
00779 ".dds",
00780 ".tga",
00781 ".bmp",
00782 ".pcx"
00783 };
00784
00785 tStringList stringList;
00786 getAsStringList(stringList, -1, name, startPos);
00787
00788 textures.clear();
00789
00790 io::path loadFile;
00791 for ( u32 i = 0; i!= stringList.size (); ++i )
00792 {
00793 video::ITexture* texture = 0;
00794 for (u32 g = 0; g != 7 ; ++g)
00795 {
00796 core::cutFilenameExtension ( loadFile, stringList[i] );
00797
00798 if ( loadFile == "$whiteimage" )
00799 {
00800 texture = driver->getTexture( "$whiteimage" );
00801 if ( 0 == texture )
00802 {
00803 core::dimension2du s ( 2, 2 );
00804 u32 image[4] = { 0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
00805 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00806 texture = driver->addTexture( "$whiteimage", w );
00807 w->drop ();
00808 }
00809
00810 }
00811 else
00812 if ( loadFile == "$redimage" )
00813 {
00814 texture = driver->getTexture( "$redimage" );
00815 if ( 0 == texture )
00816 {
00817 core::dimension2du s ( 2, 2 );
00818 u32 image[4] = { 0xFFFF0000, 0xFFFF0000,0xFFFF0000,0xFFFF0000 };
00819 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00820 texture = driver->addTexture( "$redimage", w );
00821 w->drop ();
00822 }
00823 }
00824 else
00825 if ( loadFile == "$blueimage" )
00826 {
00827 texture = driver->getTexture( "$blueimage" );
00828 if ( 0 == texture )
00829 {
00830 core::dimension2du s ( 2, 2 );
00831 u32 image[4] = { 0xFF0000FF, 0xFF0000FF,0xFF0000FF,0xFF0000FF };
00832 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00833 texture = driver->addTexture( "$blueimage", w );
00834 w->drop ();
00835 }
00836 }
00837 else
00838 if ( loadFile == "$checkerimage" )
00839 {
00840 texture = driver->getTexture( "$checkerimage" );
00841 if ( 0 == texture )
00842 {
00843 core::dimension2du s ( 2, 2 );
00844 u32 image[4] = { 0xFFFFFFFF, 0xFF000000,0xFF000000,0xFFFFFFFF };
00845 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00846 texture = driver->addTexture( "$checkerimage", w );
00847 w->drop ();
00848 }
00849 }
00850 else
00851 if ( loadFile == "$lightmap" )
00852 {
00853 texture = 0;
00854 }
00855 else
00856 {
00857 loadFile.append ( extension[g] );
00858 }
00859
00860 if ( fileSystem->existFile ( loadFile ) )
00861 {
00862 texture = driver->getTexture( loadFile );
00863 if ( texture )
00864 break;
00865 texture = 0;
00866 }
00867 }
00868
00869 textures.push_back(texture);
00870 }
00871 }
00872
00873
00875 class IShaderManager : public IReferenceCounted
00876 {
00877 };
00878
00879 }
00880 }
00881 }
00882
00883 #endif
00884