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-2009 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                 core::stringc 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 Documentation © 2003-2009 by Nikolaus Gebhardt. Generated on Sun Jan 10 09:24:04 2010 by Doxygen (1.5.6)