Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials

IQ3Shader.h

Go to the documentation of this file.
00001 // Copyright (C) 2006-2010 Nikolaus Gebhardt / Thomas Alten
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
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         // some useful typedefs
00079         typedef core::array< core::stringc > tStringList;
00080         typedef core::array< video::ITexture* > tTexArray;
00081 
00082         // string helper.. TODO: move to generic files
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                 extract substrings
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         // parses the content of Variable cull
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         // parses the content of Variable depthfunc
00192         // return a z-test
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                 // maps to E_BLEND_FACTOR
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                                         // gl_zero gl_src_color == gl_dst_color gl_zero
00270                                         case video::EBF_SRC_COLOR:
00271                                                 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00272                                                 blendfunc.param0 = video::pack_texureBlendFunc ( 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                                         // gl_one gl_zero
00282                                         case video::EBF_ZERO:
00283                                                 blendfunc.type = video::EMT_SOLID;
00284                                                 blendfunc.isTransparent = 0;
00285                                                 resolved = 1;
00286                                                 break;
00287 
00288                                         // gl_one gl_one
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                                         // gl_src_alpha gl_one_minus_src_alpha
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                                 // add
00310                                 blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR;
00311                                 blendfunc.isTransparent = 1;
00312                                 resolved = 1;
00313                                 break;
00314                         case 12:
00315                                 // filter = gl_dst_color gl_zero or gl_zero gl_src_color
00316                                 blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00317                                 blendfunc.param0 = video::pack_texureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate );
00318                                 blendfunc.isTransparent = 1;
00319                                 resolved = 1;
00320                                 break;
00321                         case 13:
00322                                 // blend = gl_src_alpha gl_one_minus_src_alpha
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                                 // alphafunc ge128
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                                 // alphafunc gt0
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                 // use the generic blender
00346                 if ( 0 == resolved )
00347                 {
00348                         blendfunc.type = video::EMT_ONETEXTURE_BLEND;
00349                         blendfunc.param0 = video::pack_texureBlendFunc (
00350                                         (video::E_BLEND_FACTOR) srcFact,
00351                                         (video::E_BLEND_FACTOR) dstFact,
00352                                         blendfunc.modulate);
00353 
00354                         blendfunc.isTransparent = 1;
00355                 }
00356         }
00357 
00358         // random noise [-1;1]
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                 // "tcmod","deformvertexes","rgbgen", "tcgen"
00429                 eQ3ModifierFunction masterfunc0;
00430                 // depends
00431                 eQ3ModifierFunction masterfunc1;
00432                 // depends
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                         // phase in 0 and 1..
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         // name = "a b c .."
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         // string database. "a" = "Hello", "b" = "1234.6"
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                 // searches for Variable name and returns is content
00594                 // if Variable is not found a reference to an Empty String is returned
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                 // set the Variable name
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                         //return name == other.name;
00654                 }
00655 
00656                 bool operator < (const IShader &other ) const
00657                 {
00658                         return strcmp ( name.c_str(), other.name.c_str () ) < 0;
00659                         //return name < other.name;
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                 // id
00678                 s32 ID;
00679                 SVarGroupList *VarGroup; // reference
00680 
00681                 // Shader: shader name ( also first variable in first Vargroup )
00682                 // Entity: classname ( variable in Group(1) )
00683                 core::stringc name;
00684         };
00685 
00686         typedef IShader IEntity;
00687 
00688         typedef core::array < IEntity > tQ3EntityList;
00689 
00690         /*
00691                 dump shader like original layout, regardless of internal data holding
00692                 no recursive folding..
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                 quake3 doesn't care much about tga & jpg
00766                 load one or multiple files stored in name started at startPos to the texture array textures
00767                 if texture is not loaded 0 will be added ( to find missing textures easier)
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[2] =
00775                 {
00776                         ".jpg",
00777                         ".tga"
00778                 };
00779 
00780                 tStringList stringList;
00781                 getAsStringList ( stringList, -1, name, startPos );
00782 
00783                 textures.clear();
00784 
00785                 io::path loadFile;
00786                 for ( u32 i = 0; i!= stringList.size (); ++i )
00787                 {
00788                         video::ITexture* texture = 0;
00789                         for ( u32 g = 0; g != 2 ; ++g )
00790                         {
00791                                 core::cutFilenameExtension ( loadFile, stringList[i] );
00792 
00793                                 if ( loadFile == "$whiteimage" )
00794                                 {
00795                                         texture = driver->getTexture( "$whiteimage" );
00796                                         if ( 0 == texture )
00797                                         {
00798                                                 core::dimension2du s ( 2, 2 );
00799                                                 u32 image[4] = { 0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
00800                                                 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00801                                                 texture = driver->addTexture( "$whiteimage", w );
00802                                                 w->drop ();
00803                                         }
00804 
00805                                 }
00806                                 else
00807                                 if ( loadFile == "$redimage" )
00808                                 {
00809                                         texture = driver->getTexture( "$redimage" );
00810                                         if ( 0 == texture )
00811                                         {
00812                                                 core::dimension2du s ( 2, 2 );
00813                                                 u32 image[4] = { 0xFFFF0000, 0xFFFF0000,0xFFFF0000,0xFFFF0000 };
00814                                                 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00815                                                 texture = driver->addTexture( "$redimage", w );
00816                                                 w->drop ();
00817                                         }
00818                                 }
00819                                 else
00820                                 if ( loadFile == "$blueimage" )
00821                                 {
00822                                         texture = driver->getTexture( "$blueimage" );
00823                                         if ( 0 == texture )
00824                                         {
00825                                                 core::dimension2du s ( 2, 2 );
00826                                                 u32 image[4] = { 0xFF0000FF, 0xFF0000FF,0xFF0000FF,0xFF0000FF };
00827                                                 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00828                                                 texture = driver->addTexture( "$blueimage", w );
00829                                                 w->drop ();
00830                                         }
00831                                 }
00832                                 else
00833                                 if ( loadFile == "$checkerimage" )
00834                                 {
00835                                         texture = driver->getTexture( "$checkerimage" );
00836                                         if ( 0 == texture )
00837                                         {
00838                                                 core::dimension2du s ( 2, 2 );
00839                                                 u32 image[4] = { 0xFFFFFFFF, 0xFF000000,0xFF000000,0xFFFFFFFF };
00840                                                 video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image );
00841                                                 texture = driver->addTexture( "$checkerimage", w );
00842                                                 w->drop ();
00843                                         }
00844                                 }
00845                                 else
00846                                 if ( loadFile == "$lightmap" )
00847                                 {
00848                                         texture = 0;
00849                                 }
00850                                 else
00851                                 {
00852                                         loadFile.append ( extension[g] );
00853                                 }
00854 
00855                                 if ( fileSystem->existFile ( loadFile ) )
00856                                 {
00857                                         texture = driver->getTexture( loadFile );
00858                                         if ( texture )
00859                                                 break;
00860                                         texture = 0;
00861                                 }
00862                         }
00863                         // take 0 Texture
00864                         textures.push_back(texture);
00865                 }
00866         }
00867 
00868 
00870         class IShaderManager : public IReferenceCounted
00871         {
00872         };
00873 
00874 } // end namespace quake3
00875 } // end namespace scene
00876 } // end namespace irr
00877 
00878 #endif
00879 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Oct 24 12:41:57 2010 by Doxygen (1.6.2)