LCOV - code coverage report
Current view: top level - usr/include/irrlicht - IQ3Shader.h (source / functions) Hit Total Coverage
Test: report Lines: 1 1 100.0 %
Date: 2015-07-11 18:23:49 Functions: 0 0 -

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

Generated by: LCOV version 1.11