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 break;
00208 case 1:
00209 ret = video::ECFN_EQUAL;
00210 break;
00211 }
00212 return ret;
00213 }
00214
00215
00227 inline static void getBlendFunc ( const core::stringc &string, SBlendFunc &blendfunc )
00228 {
00229 if ( string.size() == 0 )
00230 return;
00231
00232
00233 static const c8 * funclist[] =
00234 {
00235 "gl_zero",
00236 "gl_one",
00237 "gl_dst_color",
00238 "gl_one_minus_dst_color",
00239 "gl_src_color",
00240 "gl_one_minus_src_color",
00241 "gl_src_alpha",
00242 "gl_one_minus_src_alpha",
00243 "gl_dst_alpha",
00244 "gl_one_minus_dst_alpha",
00245 "gl_src_alpha_sat",
00246
00247 "add",
00248 "filter",
00249 "blend",
00250
00251 "ge128",
00252 "gt0",
00253 };
00254
00255
00256 u32 pos = 0;
00257 s32 srcFact = isEqual ( string, pos, funclist, 16 );
00258
00259 if ( srcFact < 0 )
00260 return;
00261
00262 u32 resolved = 0;
00263 s32 dstFact = isEqual ( string, pos, funclist, 16 );
00264
00265 switch ( srcFact )
00266 {
00267 case video::EBF_ZERO:
00268 switch ( dstFact )
00269 {
00270
00271 case video::EBF_SRC_COLOR:
00272 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00273 blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate );
00274 blendfunc.isTransparent = 1;
00275 resolved = 1;
00276 break;
00277 } break;
00278
00279 case video::EBF_ONE:
00280 switch ( dstFact )
00281 {
00282
00283 case video::EBF_ZERO:
00284 blendfunc.type = video::EMT_SOLID;
00285 blendfunc.isTransparent = 0;
00286 resolved = 1;
00287 break;
00288
00289
00290 case video::EBF_ONE:
00291 blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR;
00292 blendfunc.isTransparent = 1;
00293 resolved = 1;
00294 break;
00295 } break;
00296
00297 case video::EBF_SRC_ALPHA:
00298 switch ( dstFact )
00299 {
00300
00301 case video::EBF_ONE_MINUS_SRC_ALPHA:
00302 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00303 blendfunc.param0 = 1.f/255.f;
00304 blendfunc.isTransparent = 1;
00305 resolved = 1;
00306 break;
00307 } break;
00308
00309 case 11:
00310
00311 blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR;
00312 blendfunc.isTransparent = 1;
00313 resolved = 1;
00314 break;
00315 case 12:
00316
00317 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00318 blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate );
00319 blendfunc.isTransparent = 1;
00320 resolved = 1;
00321 break;
00322 case 13:
00323
00324 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00325 blendfunc.param0 = 1.f/255.f;
00326 blendfunc.isTransparent = 1;
00327 resolved = 1;
00328 break;
00329 case 14:
00330
00331 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00332 blendfunc.param0 = 0.5f;
00333 blendfunc.isTransparent = 1;
00334 resolved = 1;
00335 break;
00336 case 15:
00337
00338 blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
00339 blendfunc.param0 = 1.f / 255.f;
00340 blendfunc.isTransparent = 1;
00341 resolved = 1;
00342 break;
00343
00344 }
00345
00346
00347 if ( 0 == resolved )
00348 {
00349 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00350 blendfunc.param0 = video::pack_textureBlendFunc (
00351 (video::E_BLEND_FACTOR) srcFact,
00352 (video::E_BLEND_FACTOR) dstFact,
00353 blendfunc.modulate);
00354
00355 blendfunc.isTransparent = 1;
00356 }
00357 }
00358
00359
00360 struct Noiser
00361 {
00362 static f32 get ()
00363 {
00364 static u32 RandomSeed = 0x69666966;
00365 RandomSeed = (RandomSeed * 3631 + 1);
00366
00367 f32 value = ( (f32) (RandomSeed & 0x7FFF ) * (1.0f / (f32)(0x7FFF >> 1) ) ) - 1.f;
00368 return value;
00369 }
00370 };
00371
00372 enum eQ3ModifierFunction
00373 {
00374 TCMOD = 0,
00375 DEFORMVERTEXES = 1,
00376 RGBGEN = 2,
00377 TCGEN = 3,
00378 MAP = 4,
00379 ALPHAGEN = 5,
00380
00381 FUNCTION2 = 0x10,
00382 SCROLL = FUNCTION2 + 1,
00383 SCALE = FUNCTION2 + 2,
00384 ROTATE = FUNCTION2 + 3,
00385 STRETCH = FUNCTION2 + 4,
00386 TURBULENCE = FUNCTION2 + 5,
00387 WAVE = FUNCTION2 + 6,
00388
00389 IDENTITY = FUNCTION2 + 7,
00390 VERTEX = FUNCTION2 + 8,
00391 TEXTURE = FUNCTION2 + 9,
00392 LIGHTMAP = FUNCTION2 + 10,
00393 ENVIRONMENT = FUNCTION2 + 11,
00394 DOLLAR_LIGHTMAP = FUNCTION2 + 12,
00395 BULGE = FUNCTION2 + 13,
00396 AUTOSPRITE = FUNCTION2 + 14,
00397 AUTOSPRITE2 = FUNCTION2 + 15,
00398 TRANSFORM = FUNCTION2 + 16,
00399 EXACTVERTEX = FUNCTION2 + 17,
00400 CONSTANT = FUNCTION2 + 18,
00401 LIGHTINGSPECULAR = FUNCTION2 + 19,
00402 MOVE = FUNCTION2 + 20,
00403 NORMAL = FUNCTION2 + 21,
00404 IDENTITYLIGHTING = FUNCTION2 + 22,
00405
00406 WAVE_MODIFIER_FUNCTION = 0x30,
00407 SINUS = WAVE_MODIFIER_FUNCTION + 1,
00408 COSINUS = WAVE_MODIFIER_FUNCTION + 2,
00409 SQUARE = WAVE_MODIFIER_FUNCTION + 3,
00410 TRIANGLE = WAVE_MODIFIER_FUNCTION + 4,
00411 SAWTOOTH = WAVE_MODIFIER_FUNCTION + 5,
00412 SAWTOOTH_INVERSE = WAVE_MODIFIER_FUNCTION + 6,
00413 NOISE = WAVE_MODIFIER_FUNCTION + 7,
00414
00415
00416 UNKNOWN = -2
00417
00418 };
00419
00420 struct SModifierFunction
00421 {
00422 SModifierFunction ()
00423 : masterfunc0 ( UNKNOWN ), masterfunc1( UNKNOWN ), func ( SINUS ),
00424 tcgen( TEXTURE ), rgbgen ( IDENTITY ), alphagen ( UNKNOWN ),
00425 base ( 0 ), amp ( 1 ), phase ( 0 ), frequency ( 1 ),
00426 wave ( 1 ),
00427 x ( 0 ), y ( 0 ), z( 0 ), count( 0 ) {}
00428
00429
00430 eQ3ModifierFunction masterfunc0;
00431
00432 eQ3ModifierFunction masterfunc1;
00433
00434 eQ3ModifierFunction func;
00435
00436 eQ3ModifierFunction tcgen;
00437 eQ3ModifierFunction rgbgen;
00438 eQ3ModifierFunction alphagen;
00439
00440 union
00441 {
00442 f32 base;
00443 f32 bulgewidth;
00444 };
00445
00446 union
00447 {
00448 f32 amp;
00449 f32 bulgeheight;
00450 };
00451
00452 f32 phase;
00453
00454 union
00455 {
00456 f32 frequency;
00457 f32 bulgespeed;
00458 };
00459
00460 union
00461 {
00462 f32 wave;
00463 f32 div;
00464 };
00465
00466 f32 x;
00467 f32 y;
00468 f32 z;
00469 u32 count;
00470
00471 f32 evaluate ( f32 dt ) const
00472 {
00473
00474 f32 x = core::fract( (dt + phase ) * frequency );
00475 f32 y = 0.f;
00476
00477 switch ( func )
00478 {
00479 case SINUS:
00480 y = sinf ( x * core::PI * 2.f );
00481 break;
00482 case COSINUS:
00483 y = cosf ( x * core::PI * 2.f );
00484 break;
00485 case SQUARE:
00486 y = x < 0.5f ? 1.f : -1.f;
00487 break;
00488 case TRIANGLE:
00489 y = x < 0.5f ? ( 4.f * x ) - 1.f : ( -4.f * x ) + 3.f;
00490 break;
00491 case SAWTOOTH:
00492 y = x;
00493 break;
00494 case SAWTOOTH_INVERSE:
00495 y = 1.f - x;
00496 break;
00497 case NOISE:
00498 y = Noiser::get();
00499 break;
00500 default:
00501 break;
00502 }
00503
00504 return base + ( y * amp );
00505 }
00506
00507
00508 };
00509
00510 inline core::vector3df getMD3Normal ( u32 i, u32 j )
00511 {
00512 const f32 lng = i * 2.0f * core::PI / 255.0f;
00513 const f32 lat = j * 2.0f * core::PI / 255.0f;
00514 return core::vector3df(cosf ( lat ) * sinf ( lng ),
00515 sinf ( lat ) * sinf ( lng ),
00516 cosf ( lng ));
00517 }
00518
00519
00520 inline void getModifierFunc ( SModifierFunction& fill, const core::stringc &string, u32 &pos )
00521 {
00522 if ( string.size() == 0 )
00523 return;
00524
00525 static const c8 * funclist[] =
00526 {
00527 "sin","cos","square",
00528 "triangle", "sawtooth","inversesawtooth", "noise"
00529 };
00530
00531 fill.func = (eQ3ModifierFunction) isEqual ( string,pos, funclist,7 );
00532 fill.func = fill.func == UNKNOWN ? SINUS : (eQ3ModifierFunction) ((u32) fill.func + WAVE_MODIFIER_FUNCTION + 1);
00533
00534 fill.base = getAsFloat ( string, pos );
00535 fill.amp = getAsFloat ( string, pos );
00536 fill.phase = getAsFloat ( string, pos );
00537 fill.frequency = getAsFloat ( string, pos );
00538 }
00539
00540
00541
00542 struct SVariable
00543 {
00544 core::stringc name;
00545 core::stringc content;
00546
00547 SVariable ( const c8 * n, const c8 *c = 0 ) : name ( n ), content (c) {}
00548 virtual ~SVariable () {}
00549
00550 void clear ()
00551 {
00552 name = "";
00553 content = "";
00554 }
00555
00556 s32 isValid () const
00557 {
00558 return name.size();
00559 }
00560
00561 bool operator == ( const SVariable &other ) const
00562 {
00563 return 0 == strcmp ( name.c_str(), other.name.c_str () );
00564 }
00565
00566 bool operator < ( const SVariable &other ) const
00567 {
00568 return 0 > strcmp ( name.c_str(), other.name.c_str () );
00569 }
00570
00571 };
00572
00573
00574
00575 struct SVarGroup
00576 {
00577 SVarGroup () { Variable.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); }
00578 virtual ~SVarGroup () {}
00579
00580 u32 isDefined ( const c8 * name, const c8 * content = 0 ) const
00581 {
00582 for ( u32 i = 0; i != Variable.size (); ++i )
00583 {
00584 if ( 0 == strcmp ( Variable[i].name.c_str(), name ) &&
00585 ( 0 == content || strstr ( Variable[i].content.c_str(), content ) )
00586 )
00587 {
00588 return i + 1;
00589 }
00590 }
00591 return 0;
00592 }
00593
00594
00595
00596 const core::stringc &get( const c8 * name ) const
00597 {
00598 SVariable search ( name );
00599 s32 index = Variable.linear_search ( search );
00600 if ( index < 0 )
00601 return irrEmptyStringc;
00602
00603 return Variable [ index ].content;
00604 }
00605
00606
00607 void set ( const c8 * name, const c8 * content = 0 )
00608 {
00609 u32 index = isDefined ( name, 0 );
00610 if ( 0 == index )
00611 {
00612 Variable.push_back ( SVariable ( name, content ) );
00613 }
00614 else
00615 {
00616 Variable [ index ].content = content;
00617 }
00618 }
00619
00620
00621 core::array < SVariable > Variable;
00622 };
00623
00625 struct SVarGroupList: public IReferenceCounted
00626 {
00627 SVarGroupList ()
00628 {
00629 VariableGroup.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
00630 }
00631 virtual ~SVarGroupList () {}
00632
00633 core::array < SVarGroup > VariableGroup;
00634 };
00635
00636
00638 struct IShader
00639 {
00640 IShader ()
00641 : ID ( 0 ), VarGroup ( 0 ) {}
00642 virtual ~IShader () {}
00643
00644 void operator = (const IShader &other )
00645 {
00646 ID = other.ID;
00647 VarGroup = other.VarGroup;
00648 name = other.name;
00649 }
00650
00651 bool operator == (const IShader &other ) const
00652 {
00653 return 0 == strcmp ( name.c_str(), other.name.c_str () );
00654
00655 }
00656
00657 bool operator < (const IShader &other ) const
00658 {
00659 return strcmp ( name.c_str(), other.name.c_str () ) < 0;
00660
00661 }
00662
00663 u32 getGroupSize () const
00664 {
00665 if ( 0 == VarGroup )
00666 return 0;
00667 return VarGroup->VariableGroup.size ();
00668 }
00669
00670 const SVarGroup * getGroup ( u32 stage ) const
00671 {
00672 if ( 0 == VarGroup || stage >= VarGroup->VariableGroup.size () )
00673 return 0;
00674
00675 return &VarGroup->VariableGroup [ stage ];
00676 }
00677
00678
00679 s32 ID;
00680 SVarGroupList *VarGroup;
00681
00682
00683
00684 core::stringc name;
00685 };
00686
00687 typedef IShader IEntity;
00688
00689 typedef core::array < IEntity > tQ3EntityList;
00690
00691
00692
00693
00694
00695 inline void dumpVarGroup ( core::stringc &dest, const SVarGroup * group, s32 stack )
00696 {
00697 core::stringc buf;
00698 s32 i;
00699
00700
00701 if ( stack > 0 )
00702 {
00703 buf = "";
00704 for ( i = 0; i < stack - 1; ++i )
00705 buf += '\t';
00706
00707 buf += "{\n";
00708 dest.append ( buf );
00709 }
00710
00711 for ( u32 g = 0; g != group->Variable.size(); ++g )
00712 {
00713 buf = "";
00714 for ( i = 0; i < stack; ++i )
00715 buf += '\t';
00716
00717 buf += group->Variable[g].name;
00718 buf += " ";
00719 buf += group->Variable[g].content;
00720 buf += "\n";
00721 dest.append ( buf );
00722 }
00723
00724 if ( stack > 1 )
00725 {
00726 buf = "";
00727 for ( i = 0; i < stack - 1; ++i )
00728 buf += '\t';
00729
00730 buf += "}\n";
00731 dest.append ( buf );
00732 }
00733
00734 }
00735
00739 inline core::stringc & dumpShader ( core::stringc &dest, const IShader * shader, bool entity = false )
00740 {
00741 if ( 0 == shader )
00742 return dest;
00743
00744 const SVarGroup * group;
00745
00746 const u32 size = shader->VarGroup->VariableGroup.size ();
00747 for ( u32 i = 0; i != size; ++i )
00748 {
00749 group = &shader->VarGroup->VariableGroup[ i ];
00750 dumpVarGroup ( dest, group, core::clamp( (int)i, 0, 2 ) );
00751 }
00752
00753 if ( !entity )
00754 {
00755 if ( size <= 1 )
00756 {
00757 dest.append ( "{\n" );
00758 }
00759 dest.append ( "}\n" );
00760 }
00761 return dest;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770 inline void getTextures(tTexArray &textures,
00771 const core::stringc &name, u32 &startPos,
00772 io::IFileSystem *fileSystem,
00773 video::IVideoDriver* driver)
00774 {
00775 static const char* extension[] =
00776 {
00777 ".jpg",
00778 ".jpeg",
00779 ".png",
00780 ".dds",
00781 ".tga",
00782 ".bmp",
00783 ".pcx"
00784 };
00785
00786 tStringList stringList;
00787 getAsStringList(stringList, -1, name, startPos);
00788
00789 textures.clear();
00790
00791 io::path loadFile;
00792 for ( u32 i = 0; i!= stringList.size (); ++i )
00793 {
00794 video::ITexture* texture = 0;
00795 for (u32 g = 0; g != 7 ; ++g)
00796 {
00797 core::cutFilenameExtension ( loadFile, stringList[i] );
00798
00799 if ( loadFile == "$whiteimage" )
00800 {
00801 texture = driver->getTexture( "$whiteimage" );
00802 if ( 0 == texture )
00803 {
00804 core::dimension2du s ( 2, 2 );
00805 u32 image[4] = { 0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
00806 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00807 texture = driver->addTexture( "$whiteimage", w );
00808 w->drop ();
00809 }
00810
00811 }
00812 else
00813 if ( loadFile == "$redimage" )
00814 {
00815 texture = driver->getTexture( "$redimage" );
00816 if ( 0 == texture )
00817 {
00818 core::dimension2du s ( 2, 2 );
00819 u32 image[4] = { 0xFFFF0000, 0xFFFF0000,0xFFFF0000,0xFFFF0000 };
00820 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00821 texture = driver->addTexture( "$redimage", w );
00822 w->drop ();
00823 }
00824 }
00825 else
00826 if ( loadFile == "$blueimage" )
00827 {
00828 texture = driver->getTexture( "$blueimage" );
00829 if ( 0 == texture )
00830 {
00831 core::dimension2du s ( 2, 2 );
00832 u32 image[4] = { 0xFF0000FF, 0xFF0000FF,0xFF0000FF,0xFF0000FF };
00833 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00834 texture = driver->addTexture( "$blueimage", w );
00835 w->drop ();
00836 }
00837 }
00838 else
00839 if ( loadFile == "$checkerimage" )
00840 {
00841 texture = driver->getTexture( "$checkerimage" );
00842 if ( 0 == texture )
00843 {
00844 core::dimension2du s ( 2, 2 );
00845 u32 image[4] = { 0xFFFFFFFF, 0xFF000000,0xFF000000,0xFFFFFFFF };
00846 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00847 texture = driver->addTexture( "$checkerimage", w );
00848 w->drop ();
00849 }
00850 }
00851 else
00852 if ( loadFile == "$lightmap" )
00853 {
00854 texture = 0;
00855 }
00856 else
00857 {
00858 loadFile.append ( extension[g] );
00859 }
00860
00861 if ( fileSystem->existFile ( loadFile ) )
00862 {
00863 texture = driver->getTexture( loadFile );
00864 if ( texture )
00865 break;
00866 texture = 0;
00867 }
00868 }
00869
00870 textures.push_back(texture);
00871 }
00872 }
00873
00874
00876 class IShaderManager : public IReferenceCounted
00877 {
00878 };
00879
00880 }
00881 }
00882 }
00883
00884 #endif
00885