D:/Zythum/DinoKod/Render/Shader.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : Shader.cpp
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 09/09/2002
00008 //      Modification    :
00009 //
00010 //---------------------------------------------------------------------------------------------
00011 #include <string.h>
00012 #include <stdlib.h>
00013 #include "Common/Assert.h"
00014 #include "Common/Error.h"
00015 #include "Common/Directory.h"
00016 #include "Common/Console.h"
00017 
00018 #include "Render/Render.h"
00019 
00020 #include "Common/SearchFile.h"
00021 #include "Common/Parser.h"
00022 #include "Common/File.h"
00023 
00024 #include "Render/Shader.h"
00025 
00026 //--------------------------------------------------------------------------------------------------------------------------------
00027 //--------------------------------------------------------------------------------------------------------------------------------
00028 //---------------------------------------------------------------------------------------------------------------------
00029 void KShader::LoadTextures( u32 Size )
00030 {
00031         // Pas de stage
00032         if( !GetnStages() )
00033         {
00034                 m_hTexture = GetpShaderBank()->GetTexture( m_pName, true, Size );
00035                 KTexture*       pTexture        = m_pRender->GetpTextureBank()->GetpTexture( m_hTexture );
00036                 m_bAlpha                = pTexture ? pTexture->HasAlpha() : false;
00037                 return;
00038         }
00039 
00040         // Load les textures du shader
00041         for( u32 l = 0; l < GetnStages(); l ++ )
00042         {
00043                 char*   pMapName;
00044                 char*   pTemp;
00045 
00046                 if( !m_StageList[l]->m_nTextures )
00047                         continue;
00048 
00049                 if( m_StageList[l]->m_pTextureList )
00050                         continue;
00051 
00052                 m_StageList[l]->m_pTextureList = new KTEXTURE[ m_StageList[l]->m_nTextures];
00053 
00054                 pMapName = m_StageList[l]->m_pMapName;
00055 
00056                 // Remplace les , en null
00057                 u32     Length = (u32)strlen( pMapName );
00058                 for( u32 j = 0; j < Length; j ++ )
00059                 {
00060                         if( pMapName[j] == ',' )
00061                                 pMapName[j] = '\0';
00062                 }
00063 
00064                 // Load les textures
00065                 pTemp = pMapName;
00066                 for( u32 i = 0; i < m_StageList[l]->m_nTextures; i ++ )
00067                 {
00068                         KTEXTURE        TextureId = GetpShaderBank()->GetTexture( pTemp, m_bMipMap, Size );
00069 
00070                         m_StageList[l]->m_pTextureList[i]       = TextureId;
00071                         pTemp += strlen( pTemp ) + 1;
00072                 }
00073         }
00074 }
00075 
00076 //---------------------------------------------------------------------------------------------------------------------
00077 void KShader::AddStage( char* pMapName, KRBLEND BlendSrc, KRBLEND BlendDst )
00078 {
00079         KShaderStage*   pStage = new KShaderStage();
00080         pStage->m_pMapName      = strdup( pMapName );
00081         pStage->m_nTextures     = 1;
00082         pStage->m_BlendSrc      = BlendSrc;
00083         pStage->m_BlendDst      = BlendDst;
00084 
00085         m_StageList.Add( pStage );
00086 }
00087 //---------------------------------------------------------------------------------------------------------------------
00088 void KShader::SetStageBlend( u32 Stage, KRBLEND BlendSrc, KRBLEND BlendDst )
00089 {
00090         KASSERT( Stage < m_StageList.GetSize() );
00091 
00092         m_StageList[Stage]->m_BlendSrc  = BlendSrc;
00093         m_StageList[Stage]->m_BlendDst  = BlendDst;
00094 }
00095 
00096 //---------------------------------------------------------------------------------------------------------------------
00097 void KShader::FlushAllStages()
00098 {
00099         u32     Size = m_StageList.GetSize();
00100         for( u32 s = 0; s < Size; s ++ )
00101         {
00102                 if( m_StageList[s] )
00103                 {
00104                         // Unload les textures
00105                         if( m_StageList[s]->m_pTextureList )
00106                                 for( u32 i = 0; i < m_StageList[s]->m_nTextures; i ++ )
00107                                         GetpShaderBank()->UnloadTexture( m_StageList[s]->m_pTextureList[i] );
00108 
00109                         Deletep( m_StageList[s] );
00110                 }
00111         }
00112         m_StageList.Clear();
00113 }
00114 
00115 //---------------------------------------------------------------------------------------------------------------------
00116 void KShader::FlushAllTextures()
00117 {
00118         //
00119         //      Stages
00120         //
00121         u32     Size = m_StageList.GetSize();
00122         for( u32 s = 0; s < Size; s ++ )
00123         {
00124                 if( m_StageList[s] )
00125                 {
00126                         // Unload les textures
00127                         if( m_StageList[s]->m_pTextureList )
00128                         {
00129                                 for( u32 i = 0; i < m_StageList[s]->m_nTextures; i ++ )
00130                                 {
00131                                         GetpShaderBank()->UnloadTexture( m_StageList[s]->m_pTextureList[i] );
00132 
00133                                 }
00134                                 Deletev( m_StageList[s]->m_pTextureList );
00135                         }
00136                 }
00137         }
00138 
00139         //
00140         //      Texture
00141         //
00142         if( m_hTexture != KTEXTURE_NO )
00143         {
00144                 GetpShaderBank()->UnloadTexture( m_hTexture );
00145                 m_hTexture = KTEXTURE_NO;
00146         }
00147 }
00148 
00149 //--------------------------------------------------------------------------------------------------------------------------------
00150 //--------------------------------------------------------------------------------------------------------------------------------
00151 //--------------------------------------------------------------------------------------------------------------------------------
00152 KShaderBank::KShaderBank( KRender* pRender )
00153 {
00154         m_pRender = pRender;
00155 }
00156 
00157 //---------------------------------------------------------------------------------------------------------------------
00158 KShaderBank::~KShaderBank()
00159 {
00160         while( GetnDatas() )
00161         {
00162                 FlushShader( GethFirst() );
00163         }
00164 }
00165 
00166 //---------------------------------------------------------------------------------------------------------------------
00167 bool KShaderBank::PreLoad()
00168 {
00169         for( s32 Path = 0; Path < g_Directory.GetnPath(); Path ++ )
00170         {
00171                 KStr    sPath = g_Directory.GetPath( KStr( "Shaders" ), Path );
00172                 KStr    sSearchPath = sPath;
00173                 sSearchPath += "*.sdr";
00174 
00175                 // Cherche tous les fichiers
00176                 KSearchFile             SearchFile( sSearchPath );
00177 
00178                 KStr    sFullName;
00179                 for( u32 i = 0; i < SearchFile.GetnFiles(); i ++ )
00180                 {
00181                         sFullName = sPath;
00182                         sFullName += SearchFile.GetpFile( i );
00183 
00184                         if( !LoadFile( sFullName ) )
00185                                 KError::Warning( NULL, "KShader::Load(...) : Cannot load shader file %s", (char*)sFullName );
00186                 }
00187         }
00188 
00189         return true;
00190 }
00191 
00192 //---------------------------------------------------------------------------------------------------------------------
00193 void KShaderBank::FlushShader( KSHADER Handle )
00194 {
00195         KShader*        pShader;
00196                 
00197         pShader = GetpData( Handle );
00198         KASSERT( pShader );
00199 
00200         if( pShader->GetnInstances() != 0 )
00201                 KError::Debug( NULL, "KShaderBank::FlushShader(...) : Bad instance counter : %i\nShader : %s", pShader->GetnInstances(), pShader->m_pName );
00202 
00203         RemoveData( Handle );
00204         Deletep( pShader );
00205 }
00206 
00207 //---------------------------------------------------------------------------------------------------------------------
00208 
00209 #define FINDTOKEN               Parser.FindToken()
00210 #define TOKEN                   Parser.GetToken()
00211 #define NEWLINETOKEN    Parser.IsNewLine()
00212 #define CMPTOKEN(__s)   (stricmp(__s,Parser.GetToken()) == 0)
00213 
00214 //---------------------------------------------------------------------------------------------------------------------
00215 bool KShaderBank::LoadFile( char* pFileName )
00216 {
00217         KSHADER         Handle;
00218         KParser         Parser( pFileName );
00219 
00220         // Fin de fichier ?
00221         if( Parser.IsEOF() )
00222                 return true;
00223 
00224         do
00225         {
00226                 KShader*        pShader;
00227         
00228                 FINDTOKEN;
00229 
00230                 // Fin de fichier ?
00231                 if( Parser.IsEOF() )
00232                         return true;
00233                 
00234                 KASSERT( TOKEN[0] );
00235                 
00236                 // Existe deja ?
00237                 bool bDuplicate = false;
00238                 for( Handle = GethFirst(); Handle != KSHADER_NO; Handle = GethNext( Handle ) )
00239                 {
00240                         pShader = GetpShader( Handle );
00241                         if( pShader && !stricmp( pShader->m_pName, TOKEN ) )
00242                         {
00243                                 KError::Warning( NULL, "KShaderBank::LoadFile(...) : Duplicate shader found : [%s]", TOKEN );
00244 
00245                                 // Ignore le shader
00246                                 u32     i = 0;
00247                                 do
00248                                 {
00249                                         FINDTOKEN;
00250                                         if( CMPTOKEN( "{" ) )
00251                                                 i ++;
00252                                         if( CMPTOKEN( "}" ) )
00253                                                 i --;
00254                                 }while( i );
00255                                 bDuplicate = true;
00256                                 break;
00257                         }
00258                 }
00259                 if( bDuplicate )
00260                         continue;
00261 
00262                 KSHADER Handle;
00263                 pShader = new KShader( m_pRender, this );
00264                 Handle = AddData( pShader );
00265                 pShader->m_hShader = Handle;
00266                 
00267                 // Shader name
00268                 pShader->m_pName        = strdup( TOKEN );
00269                 
00270                 FINDTOKEN;
00271                 if( !CMPTOKEN( "{" ) )
00272                         return false;
00273 
00274                 // Shader desc
00275                 do
00276                 {
00277 continue_shader:
00278                         FINDTOKEN;
00279 
00280                         // SurfaceParm
00281                         if CMPTOKEN( "surfaceparm" )
00282                         {
00283                                 FINDTOKEN;
00284                                 if CMPTOKEN( "alphashadow"      )       pShader->m_SurfaceParm |= KSSP_ALPHASHADOW;
00285                                 if CMPTOKEN( "areaportal"       )       pShader->m_SurfaceParm |= KSSP_AREAPORTAL;
00286                                 if CMPTOKEN( "clusterportal")   pShader->m_SurfaceParm |= KSSP_CLUSTERPORTAL;
00287                                 if CMPTOKEN( "donotenter"       )       pShader->m_SurfaceParm |= KSSP_DONOTENTER;
00288                                 if CMPTOKEN( "flesh"            )       pShader->m_SurfaceParm |= KSSP_FLESH;
00289                                 if CMPTOKEN( "fog"                      )       pShader->m_SurfaceParm |= KSSP_FOG;
00290                                 if CMPTOKEN( "lava"                     )       pShader->m_SurfaceParm |= KSSP_LAVA;
00291                                 if CMPTOKEN( "metalsteps"       )       pShader->m_SurfaceParm |= KSSP_METALSTEPS;
00292                                 if CMPTOKEN( "nodamage"         )       pShader->m_SurfaceParm |= KSSP_NODAMAGE;
00293                                 if CMPTOKEN( "nodlight"         )       pShader->m_SurfaceParm |= KSSP_NODLIGHT;
00294                                 if CMPTOKEN( "nodraw"           )       pShader->m_SurfaceParm |= KSSP_NODRAW;
00295                                 if CMPTOKEN( "nodrop"           )       pShader->m_SurfaceParm |= KSSP_NODROP;
00296                                 if CMPTOKEN( "noimpact"         )       pShader->m_SurfaceParm |= KSSP_NOIMPACT;
00297                                 if CMPTOKEN( "nomarks"          )       pShader->m_SurfaceParm |= KSSP_NOMARKS;
00298                                 if CMPTOKEN( "nolightmap"       )       pShader->m_SurfaceParm |= KSSP_NOLIGHTMAP;
00299                                 if CMPTOKEN( "nosteps"          )       pShader->m_SurfaceParm |= KSSP_NOSTEPS;
00300                                 if CMPTOKEN( "nonsolid"         )       pShader->m_SurfaceParm |= KSSP_NONSOLID;
00301                                 if CMPTOKEN( "origin"           )       pShader->m_SurfaceParm |= KSSP_ORIGIN;
00302                                 if CMPTOKEN( "playerclip"       )       pShader->m_SurfaceParm |= KSSP_PLAYERCLIP;
00303                                 if CMPTOKEN( "slick"            )       pShader->m_SurfaceParm |= KSSP_SLICK;
00304                                 if CMPTOKEN( "slime"            )       pShader->m_SurfaceParm |= KSSP_SLIME;
00305                                 if CMPTOKEN( "structural"       )       pShader->m_SurfaceParm |= KSSP_STRUCTURAL;
00306                                 if CMPTOKEN( "trans"            )       pShader->m_SurfaceParm |= KSSP_TRANS;
00307                                 if CMPTOKEN( "water"            )       pShader->m_SurfaceParm |= KSSP_WATER;
00308                                 if CMPTOKEN( "sky"                      )       pShader->m_SurfaceParm |= KSSP_SKY;
00309                                 goto continue_shader;
00310                         }
00311                         
00312                         // General
00313                         if CMPTOKEN( "cull" )
00314                         {
00315                                 FINDTOKEN;
00316                                 if CMPTOKEN( "front" )                  pShader->m_Cull = KSGC_CW;
00317                                 if CMPTOKEN( "back" )                   pShader->m_Cull = KSGC_CCW;
00318                                 if CMPTOKEN( "none" )                   pShader->m_Cull = KSGC_NONE;
00319                                 if CMPTOKEN( "disable" )                pShader->m_Cull = KSGC_NONE;
00320                         }
00321 
00322                         if CMPTOKEN( "nomipmap" )
00323                         {
00324                                 pShader->m_bMipMap = false;
00325                         }
00326 
00327                         if( CMPTOKEN( "sort" ) )
00328                         {
00329                                 FINDTOKEN;
00330                                 if( CMPTOKEN( "portal" ) )
00331                                         pShader->m_SortValue = 1;
00332                                 else
00333                                 if( CMPTOKEN( "sky" ) )
00334                                         pShader->m_SortValue = 2;
00335                                 else
00336                                 if( CMPTOKEN( "opaque" ) )
00337                                         pShader->m_SortValue = 3;
00338                                 else
00339                                 if( CMPTOKEN( "banner" ) )
00340                                         pShader->m_SortValue = 6;
00341                                 else
00342                                 if( CMPTOKEN( "underwater" ) )
00343                                         pShader->m_SortValue = 8;
00344                                 else
00345                                 if( CMPTOKEN( "additive" ) )
00346                                         pShader->m_SortValue = 9;
00347                                 else
00348                                 if( CMPTOKEN( "nearest" ) )
00349                                         pShader->m_SortValue = 16;
00350                                 else
00351                                         pShader->m_SortValue = atoi( TOKEN );
00352 //                                      KError::Warning( NULL, "KShaderBank::LoadFile(...) : Unknown sort value [%s] in shader [%s]", TOKEN, pShader->m_pName );
00353                         }
00354 
00355                         if( CMPTOKEN( "{" ) )
00356                         {
00357                                 // Nouveau stage
00358                                 KShaderStage*   pShaderStage;
00359 
00360                                 pShaderStage = new KShaderStage();
00361                                 pShader->m_StageList.Add( pShaderStage );
00362 
00363                                 do
00364                                 {
00365 continue_shaderstage:
00366                                         FINDTOKEN;
00367                                         
00368                                         // Map type
00369                                         if( CMPTOKEN( "map" ) )
00370                                         {
00371 //                                              KASSERT( !pShaderStage->m_pMapName );
00372                                                 if( pShaderStage->m_pMapName )
00373                                                 {
00374                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Shader [%s] has already a map, ignoring...", pShader->m_pName );
00375                                                         continue;
00376                                                 }
00377 
00378 
00379                                                 FINDTOKEN;
00380                                                 pShaderStage->m_StageFlags              |= KSSF_MAP;
00381                                                 pShaderStage->m_pMapName                = strdup( TOKEN );
00382                                                 pShaderStage->m_nTextures               = 1;
00383                                                 if( CMPTOKEN( "$lightmap" ) )
00384                                                 {
00385                                                         pShader->m_Flags                        |= KSF_LIGHTMAP;
00386                                                         pShaderStage->m_StageFlags      |= KSSF_LIGHTMAP;
00387                                                 }
00388                                                 goto continue_shaderstage;
00389                                         }
00390                                         if( CMPTOKEN( "bumpmap" ) )
00391                                         {
00392 //                                              KASSERT( !pShaderStage->m_pMapName );
00393                                                 if( pShaderStage->m_pMapName )
00394                                                 {
00395                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Shader [%s] has already a map, ignoring...", pShader->m_pName );
00396                                                         continue;
00397                                                 }
00398 
00399                                                 pShaderStage->m_StageFlags              |= KSSF_BUMPMAP;
00400                                                 
00401                                                 char*   pTemp;
00402                                                 u32             nTextures = 0;
00403                                                 
00404                                                 // Place a la suite tout les fichiers
00405                                                 do
00406                                                 {
00407                                                         FINDTOKEN;
00408                                                         pTemp = (char*)malloc( strlen( TOKEN ) + 1 + (pShaderStage->m_pMapName ? strlen( pShaderStage->m_pMapName ) : 0) + 1 );
00409                                                         
00410                                                         strcpy( pTemp, pShaderStage->m_pMapName ? pShaderStage->m_pMapName : "" );
00411                                                         strcat( pTemp, pShaderStage->m_pMapName ? "," : "" );
00412                                                         strcat( pTemp, TOKEN );
00413 
00414                                                         if( pShaderStage->m_pMapName )
00415                                                                 free( pShaderStage->m_pMapName );
00416 
00417                                                         pShaderStage->m_pMapName = pTemp;
00418                                                         nTextures ++;
00419                                                 }while( !NEWLINETOKEN );
00420                                                 pShaderStage->m_nTextures = nTextures;
00421                                                 goto continue_shaderstage;
00422                                         }
00423                                         if( CMPTOKEN( "clampmap" ) )
00424                                         {
00425 //                                              KASSERT( !pShaderStage->m_pMapName );
00426                                                 if( pShaderStage->m_pMapName )
00427                                                 {
00428                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Shader [%s] has already a map, ignoring...", pShader->m_pName );
00429                                                         continue;
00430                                                 }
00431 
00432                                                 FINDTOKEN;
00433                                                 pShaderStage->m_StageFlags              |= KSSF_CLAMPMAP;
00434                                                 pShaderStage->m_pMapName                = strdup( TOKEN );
00435                                                 pShaderStage->m_nTextures               = 1;
00436                                                 if( CMPTOKEN( "$lightmap" ) )
00437                                                 {
00438                                                         pShader->m_Flags                        |= KSF_LIGHTMAP;
00439                                                         pShaderStage->m_StageFlags      |= KSSF_LIGHTMAP;
00440                                                 }
00441                                                 goto continue_shaderstage;
00442                                         }
00443                                         if( CMPTOKEN( "animmap" ) )
00444                                         {
00445 //                                              KASSERT( !pShaderStage->m_pMapName );
00446                                                 if( pShaderStage->m_pMapName )
00447                                                 {
00448                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Shader [%s] has already a map, ignoring...", pShader->m_pName );
00449                                                         continue;
00450                                                 }
00451 
00452                                                 FINDTOKEN;
00453                                                 pShaderStage->m_StageFlags              |= KSSF_ANIMMAP;
00454                                                 pShaderStage->m_Frequency               = (float)atof( TOKEN );
00455                                                 
00456                                                 char*   pTemp;
00457                                                 u32             nTextures = 0;
00458 
00459                                                 // Place a la suite tout les fichiers
00460                                                 do
00461                                                 {
00462                                                         FINDTOKEN;
00463                                                         pTemp = (char*)malloc( strlen( TOKEN ) + 1 + (pShaderStage->m_pMapName ? strlen( pShaderStage->m_pMapName ) : 0) + 1 );
00464                                                         
00465                                                         strcpy( pTemp, pShaderStage->m_pMapName ? pShaderStage->m_pMapName : "" );
00466                                                         strcat( pTemp, pShaderStage->m_pMapName ? "," : "" );
00467                                                         strcat( pTemp, TOKEN );
00468 
00469                                                         if( pShaderStage->m_pMapName )
00470                                                                 free( pShaderStage->m_pMapName );
00471 
00472                                                         pShaderStage->m_pMapName = pTemp;
00473                                                         nTextures ++;
00474                                                 }while( !NEWLINETOKEN );
00475                                                 pShaderStage->m_nTextures = nTextures;
00476                                                 goto continue_shaderstage;
00477                                         }
00478                                         if( CMPTOKEN( "blendfunc" ) )
00479                                         {
00480                                                 FINDTOKEN;
00481                                                 pShaderStage->m_StageFlags      |= KSSF_BLEND;
00482                                                 if( CMPTOKEN( "add" ) )
00483                                                 {
00484                                                         //pShaderStage->m_bDepthWrite   = false;
00485                                                         pShaderStage->m_BlendSrc        = KRBLEND_ONE;
00486                                                         pShaderStage->m_BlendDst        = KRBLEND_ONE;
00487                                                 
00488                                                         if( !pShader->m_SortValue )
00489                                                                 pShader->m_SortValue = 9;
00490                                                 }
00491                                                 else
00492                                                 if( CMPTOKEN( "filter" ) )
00493                                                 {
00494                                                         //pShaderStage->m_bDepthWrite   = false;
00495                                                         pShaderStage->m_BlendSrc        = KRBLEND_DST;
00496                                                         pShaderStage->m_BlendDst        = KRBLEND_ZERO;
00497                                                 }
00498                                                 else
00499                                                 if( CMPTOKEN( "blend" ) )
00500                                                 {
00501                                                         //pShaderStage->m_bDepthWrite   = false;
00502                                                         pShaderStage->m_BlendSrc        = KRBLEND_SRCALPHA;
00503                                                         pShaderStage->m_BlendDst        = KRBLEND_INVSRCALPHA;
00504                                                 }
00505                                                 else
00506                                                 if( CMPTOKEN( "factor" ) )
00507                                                 {
00508                                                         //pShaderStage->m_bDepthWrite   = false;
00509                                                         pShaderStage->m_BlendSrc        = KRBLEND_BLENDFACTOR;
00510                                                         pShaderStage->m_BlendDst        = KRBLEND_INVBLENDFACTOR;
00511                                                 }
00512                                                 else
00513                                                 {
00514                                                         pShaderStage->m_BlendSrc = GetBlendByText( TOKEN );
00515                                                         FINDTOKEN;
00516                                                         pShaderStage->m_BlendDst = GetBlendByText( TOKEN );
00517 
00518                                                         if( !pShader->m_SortValue && ( pShaderStage->m_BlendSrc == KRBLEND_ONE ) && ( pShaderStage->m_BlendDst == KRBLEND_ONE ) )
00519                                                         {
00520                                                                 pShader->m_SortValue = 9;
00521                                                                 //pShaderStage->m_bDepthWrite   = false;
00522                                                         }
00523                                                 }
00524                                                 
00525                                                 goto continue_shaderstage;
00526                                         }
00527 
00528                                         //
00529                                         //      RGBGEN
00530                                         //
00531                                         if( CMPTOKEN( "rgbGen" ) )
00532                                         {
00533                                                 pShader->m_Flags |= KSF_RGBGEN;
00534 
00535                                                 FINDTOKEN;
00536                                                 if( CMPTOKEN( "identityLighting" ) )
00537                                                 {
00538                                                         pShaderStage->m_RgbGen = KSSR_IDENTITYLIGHTING;
00539                                                 }
00540                                                 else
00541                                                 if( CMPTOKEN( "identity" ) )
00542                                                 {
00543                                                         pShaderStage->m_RgbGen = KSSR_IDENTITY;
00544                                                 }
00545                                                 else
00546                                                 if( CMPTOKEN( "wave" ) )
00547                                                 {
00548                                                         pShaderStage->m_RgbGen = KSSR_WAVE;
00549                                                         
00550                                                         FINDTOKEN;
00551                                                         if( CMPTOKEN( "sin" ) )
00552                                                                 pShaderStage->m_RgbGenWaveFunc  = KSSTW_SIN;
00553                                                         else
00554                                                         if( CMPTOKEN( "triangle" ) )
00555                                                                 pShaderStage->m_RgbGenWaveFunc  = KSSTW_TRIANGLE;
00556                                                         else
00557                                                         if( CMPTOKEN( "square" ) )
00558                                                                 pShaderStage->m_RgbGenWaveFunc  = KSSTW_SQUARE;
00559                                                         else
00560                                                         if( CMPTOKEN( "sawtooth" ) )
00561                                                                 pShaderStage->m_RgbGenWaveFunc  = KSSTW_SAWTOOTH;
00562                                                         else
00563                                                         if( CMPTOKEN( "inversesawtooth" ) )
00564                                                                 pShaderStage->m_RgbGenWaveFunc  = KSSTW_INVERSESAWTOOTH;
00565                                                         else
00566                                                                 KError::Warning( NULL, "KShaderBank::LoadFile(...) : Unknown TcMod StretchFunc [%s] in shader [%s]", TOKEN, pShader->m_pName );
00567                                                         
00568                                                         FINDTOKEN;
00569                                                         pShaderStage->m_RgbGenWaveParam1 = (float)atof( TOKEN );
00570                                                         FINDTOKEN;
00571                                                         pShaderStage->m_RgbGenWaveParam2 = (float)atof( TOKEN );
00572                                                         FINDTOKEN;
00573                                                         pShaderStage->m_RgbGenWaveParam3 = (float)atof( TOKEN );
00574                                                         FINDTOKEN;
00575                                                         pShaderStage->m_RgbGenWaveParam4 = (float)atof( TOKEN );
00576                                                 }
00577                                                 else
00578                                                 if( CMPTOKEN( "entity" ) )
00579                                                 {
00580                                                         pShaderStage->m_RgbGen = KSSR_ENTITY;
00581                                                 }
00582                                                 else
00583                                                 if( CMPTOKEN( "oneMinusEntity" ) )
00584                                                 {
00585                                                         pShaderStage->m_RgbGen = KSSR_ONEMINUSENTITY;
00586                                                 }
00587                                                 else
00588                                                 if( CMPTOKEN( "vertex" ) )
00589                                                 {
00590                                                         pShaderStage->m_RgbGen = KSSR_VERTEX;
00591                                                 }
00592                                                 else
00593                                                 if( CMPTOKEN( "exactVertex" ) )
00594                                                 {
00595                                                         pShaderStage->m_RgbGen = KSSR_VERTEX;
00596                                                 }
00597                                                 else
00598                                                 if( CMPTOKEN( "oneMinusVertex" ) )
00599                                                 {
00600                                                         pShaderStage->m_RgbGen = KSSR_ONEMINUSVERTEX;
00601                                                 }
00602                                                 else
00603                                                 if( CMPTOKEN( "lightingDiffuse" ) )
00604                                                 {
00605                                                         pShaderStage->m_RgbGen = KSSR_LIGHTINGDIFFUSE;
00606                                                 }
00607                                                 else
00608                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Unknown rgbGen [%s] in shader [%s]", TOKEN, pShader->m_pName );
00609                                         }
00610 
00611                                         //
00612                                         //      DEPTHWRITE
00613                                         //
00614                                         if( CMPTOKEN( "depthWrite" ) )
00615                                         {
00616                                                 pShaderStage->m_bDepthWrite     = true;
00617                                         }
00618 
00619                                         if( CMPTOKEN( "noDepthWrite" ) )
00620                                         {
00621                                                 pShaderStage->m_bDepthWrite     = false;
00622                                         }
00623 
00624                                         //
00625                                         //      DEPTHFUNC
00626                                         //
00627                                         if( CMPTOKEN( "depthFunc" ) )
00628                                         {
00629                                                 //pShaderStage->m_bDepthWrite   = false;
00630                                                 pShaderStage->m_StageFlags |= KSSF_DEPTHTEST;
00631 
00632                                                 FINDTOKEN;
00633                                                 if( stricmp( TOKEN, "lequal" ) == 0 )
00634                                                         pShaderStage->m_DepthFunc = KRCMP_LESSEQUAL;
00635                                                 else
00636                                                 if( stricmp( TOKEN, "equal" ) == 0 )
00637                                                         pShaderStage->m_DepthFunc = KRCMP_EQUAL;
00638                                                 else
00639                                                 if( stricmp( TOKEN, "always" ) == 0 )
00640                                                         pShaderStage->m_DepthFunc = KRCMP_ALWAYS;
00641                                                 else
00642                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Unknown depthFunc [%s] in shader [%s]", TOKEN, pShader->m_pName );
00643                                         }
00644 
00645                                         //
00646                                         //      ALPHAFUNC
00647                                         //
00648                                         if( CMPTOKEN( "alphaFunc" ) )
00649                                         {
00650                                                 //pShaderStage->m_bDepthWrite   = false;
00651                                                 pShaderStage->m_StageFlags |= KSSF_ALPHATEST;
00652                                                 
00653                                                 FINDTOKEN;
00654                                                 if( stricmp( TOKEN, "always" ) == 0 )
00655                                                         pShaderStage->m_AlphaFunc = KRCMP_ALWAYS;
00656                                                 else
00657                                                 if( strnicmp( TOKEN, "ge", 2 ) == 0 )
00658                                                         pShaderStage->m_AlphaFunc = KRCMP_GREATEREQUAL;
00659                                                 else
00660                                                 if( strnicmp( TOKEN, "gt", 2 ) == 0 )
00661                                                         pShaderStage->m_AlphaFunc = KRCMP_GREATER;
00662                                                 else
00663                                                 if( strnicmp( TOKEN, "lt", 2 ) == 0 )
00664                                                         pShaderStage->m_AlphaFunc = KRCMP_LESS;
00665                                                 else
00666                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Unknown alphaFunc [%s] in shader [%s]", TOKEN, pShader->m_pName );
00667 
00668                                                 pShaderStage->m_AlphaRef = atoi( &TOKEN[2] );
00669                                         }
00670 
00671                                         //
00672                                         //      TCMOD
00673                                         //
00674                                         if( CMPTOKEN( "tcMod" ) )
00675                                         {
00676                                                 pShader->m_Flags |= KSF_TCMOD;
00677                                                 
00678                                                 KShaderTcMod*   pShaderTcMod = new KShaderTcMod();
00679                                                 pShaderStage->m_TcModList.Add( pShaderTcMod );
00680 
00681                                                 FINDTOKEN;
00682                                                 if( CMPTOKEN( "rotate" ) )
00683                                                 {
00684                                                         pShaderTcMod->m_TcMod           = KSST_ROTATE;
00685                                                         FINDTOKEN;
00686                                                         pShaderTcMod->m_TcModParam1 = (float)atof( TOKEN );
00687                                                 }
00688                                                 else
00689                                                 if( CMPTOKEN( "scale" ) )
00690                                                 {
00691                                                         pShaderTcMod->m_TcMod           = KSST_SCALE;
00692                                                         FINDTOKEN;
00693                                                         pShaderTcMod->m_TcModParam1 = (float)atof( TOKEN );
00694                                                         FINDTOKEN;
00695                                                         pShaderTcMod->m_TcModParam2 = (float)atof( TOKEN );
00696                                                 }
00697                                                 else
00698                                                 if( CMPTOKEN( "scroll" ) )
00699                                                 {
00700                                                         pShaderTcMod->m_TcMod           = KSST_SCROLL;
00701                                                         FINDTOKEN;
00702                                                         pShaderTcMod->m_TcModParam1 = (float)atof( TOKEN );
00703                                                         FINDTOKEN;
00704                                                         pShaderTcMod->m_TcModParam2 = (float)atof( TOKEN );
00705                                                 }
00706                                                 else
00707                                                 if( CMPTOKEN( "stretch" ) )
00708                                                 {
00709                                                         pShaderTcMod->m_TcMod           = KSST_STRETCH;
00710                                                         FINDTOKEN;
00711                                                         if( CMPTOKEN( "sin" ) )
00712                                                                 pShaderTcMod->m_TcModFunc       = KSSTF_SIN;
00713                                                         else
00714                                                         if( CMPTOKEN( "triangle" ) )
00715                                                                 pShaderTcMod->m_TcModFunc       = KSSTF_TRIANGLE;
00716                                                         else
00717                                                         if( CMPTOKEN( "square" ) )
00718                                                                 pShaderTcMod->m_TcModFunc       = KSSTF_SQUARE;
00719                                                         else
00720                                                         if( CMPTOKEN( "sawtooth" ) )
00721                                                                 pShaderTcMod->m_TcModFunc       = KSSTF_SAWTOOTH;
00722                                                         else
00723                                                         if( CMPTOKEN( "inversesawtooth" ) )
00724                                                                 pShaderTcMod->m_TcModFunc       = KSSTF_INVERSESAWTOOTH;
00725                                                         else
00726                                                                 KError::Warning( NULL, "KShaderBank::LoadFile(...) : Unknown TcMod StretchFunc [%s] in shader [%s]", TOKEN, pShader->m_pName );
00727                                                         
00728                                                         FINDTOKEN;
00729                                                         pShaderTcMod->m_TcModParam1 = (float)atof( TOKEN );
00730                                                         FINDTOKEN;
00731                                                         pShaderTcMod->m_TcModParam2 = (float)atof( TOKEN );
00732                                                         FINDTOKEN;
00733                                                         pShaderTcMod->m_TcModParam3 = (float)atof( TOKEN );
00734                                                         FINDTOKEN;
00735                                                         pShaderTcMod->m_TcModParam4 = (float)atof( TOKEN );
00736                                                 }
00737                                                 else
00738                                                 if( CMPTOKEN( "transform" ) )
00739                                                 {
00740                                                         pShaderTcMod->m_TcMod           = KSST_TRANSFORM;
00741                                                         FINDTOKEN;
00742                                                         pShaderTcMod->m_TcModParam1 = (float)atof( TOKEN );
00743                                                         FINDTOKEN;
00744                                                         pShaderTcMod->m_TcModParam2 = (float)atof( TOKEN );
00745                                                         FINDTOKEN;
00746                                                         pShaderTcMod->m_TcModParam3 = (float)atof( TOKEN );
00747                                                         FINDTOKEN;
00748                                                         pShaderTcMod->m_TcModParam4 = (float)atof( TOKEN );
00749                                                         FINDTOKEN;
00750                                                         pShaderTcMod->m_TcModParam5 = (float)atof( TOKEN );
00751                                                         FINDTOKEN;
00752                                                         pShaderTcMod->m_TcModParam6 = (float)atof( TOKEN );
00753                                                 }
00754                                                 else
00755                                                 if( CMPTOKEN( "turb" ) )
00756                                                 {
00757                                                         pShaderTcMod->m_TcMod           = KSST_TURB;
00758                                                         FINDTOKEN;
00759                                                         pShaderTcMod->m_TcModParam1 = (float)atof( TOKEN );
00760                                                         FINDTOKEN;
00761                                                         pShaderTcMod->m_TcModParam2 = (float)atof( TOKEN );
00762                                                         FINDTOKEN;
00763                                                         pShaderTcMod->m_TcModParam3 = (float)atof( TOKEN );
00764                                                         FINDTOKEN;
00765                                                         pShaderTcMod->m_TcModParam4 = (float)atof( TOKEN );
00766                                                 }
00767                                                 else
00768                                                         KError::Warning( NULL, "KShaderBank::LoadFile(...) : Unknown TcMod [%s] in shader [%s]", TOKEN, pShader->m_pName );
00769                                         }
00770 
00771                                 }while( !CMPTOKEN( "}" ) );
00772                                 goto continue_shader;
00773 
00774                         }
00775                 }while( !CMPTOKEN( "}" ) );
00776 
00777         }while( TOKEN[0] );
00778 
00779         return true;
00780 }
00781 
00782 //---------------------------------------------------------------------------------------------------------------------
00783 KTEXTURE KShaderBank::GetTexture( char* pFileName, bool GenerateMipMap, u32 Size )
00784 {
00785         if( stricmp( pFileName, "$lightmap" ) == 0 )
00786                 return KTEXTURE_NO;
00787 
00788         if( stricmp( pFileName, "noshader" ) == 0 )
00789                 return KTEXTURE_NO;
00790 
00791         char            pFullName[1024];
00792         char*           pExtension;
00793 
00794         strcpy( pFullName, pFileName );
00795         pExtension = KFile::GetFileExtension( pFullName );
00796         if( pExtension )
00797         {
00798                 // Pas d'extension !!! on l'enleve
00799                 pFullName[strlen(pFullName) - strlen( pExtension ) - 1] = '\0';
00800         }
00801 
00802         // Recherche la texture sur differents repertoires
00803         for( s32 i = 0; i < g_Directory.GetnPath(); i ++ )
00804         {
00805                 KTEXTURE        TextureId = KTEXTURE_NO;
00806                 
00807                 KStr    sTexturePath = g_Directory.GetPath( KStr( "Textures" ), i );
00808                 sTexturePath += pFullName;
00809 
00810                 TextureId = m_pRender->GetpTextureBank()->LoadTexture( sTexturePath, GenerateMipMap, Size );
00811                 if( TextureId != KTEXTURE_NO )
00812                 {
00813                         g_Console << "Texture loaded : " << pFileName << KENDL;
00814                         return TextureId;
00815                 }
00816         }
00817 
00818         KError::Warning( NULL, "Cannot load texture %s", pFileName );
00819         
00820         return KTEXTURE_NO;
00821 }
00822 
00823 //---------------------------------------------------------------------------------------------------------------------
00824 KSHADER KShaderBank::LoadShader( char* pShaderName, u32 Size )
00825 {
00826         KSHADER         Handle;
00827         KShader*        pShader;
00828 
00829         // Recherche le shader
00830         for( Handle = GethFirst(); Handle != KSHADER_NO; Handle = GethNext( Handle ) )
00831         {
00832                 pShader = GetpShader( Handle );
00833                 if( pShader && stricmp( pShader->m_pName, pShaderName ) == 0 )
00834                 {
00835                         // Nouvelle instance du shader
00836                         pShader->AddInstance();
00837 
00838                         // Load les textures du shader
00839                         pShader->LoadTextures( Size );
00840 
00841                         return Handle;
00842                 }
00843         }
00844 
00845         KError::Debug( NULL, "%s not found, default loaded.", pShaderName );
00846 
00847         // Shader pas trouvé
00848         // On le crée
00849         pShader = new KShader( m_pRender, this );
00850         pShader->AddInstance();
00851         Handle = AddData( pShader );
00852         
00853         pShader->m_hShader              = Handle;
00854         pShader->m_pName                = strdup( pShaderName );
00855         pShader->LoadTextures( Size );
00856 /*
00857         pShader->m_hTexture             = GetTexture( pShaderName, true, Size );
00858         KTexture*       pTexture        = m_pRender->GetpTextureBank()->GetpTexture( pShader->m_hTexture );
00859         pShader->m_bAlpha               = pTexture ? pTexture->HasAlpha() : false;
00860 */
00861         return Handle;
00862 }
00863 
00864 //---------------------------------------------------------------------------------------------------------------------
00865 KSHADER KShaderBank::CreateShader( char* pShaderName )
00866 {
00867         KShader*        pShader;
00868         KSHADER         Handle;
00869 
00870         pShader = new KShader( m_pRender, this );
00871         pShader->AddInstance();
00872         Handle = AddData( pShader );
00873 
00874         pShader->m_hShader              = Handle;
00875         pShader->m_pName                = strdup( pShaderName );
00876         
00877         return Handle;
00878 }
00879 
00880 //---------------------------------------------------------------------------------------------------------------------
00881 void KShaderBank::UnloadShader( KSHADER& hShader )
00882 {
00883         KShader*        pShader;
00884 
00885         if( hShader == KSHADER_NO )
00886                 return;
00887 
00888         pShader = GetpData( hShader );
00889         KASSERT( pShader );
00890 
00891         pShader->RemoveInstance();
00892         KASSERT( pShader->GetnInstances() >= 0 );
00893 
00894         if( !pShader->GetnInstances() )
00895         {
00896                 // Plus aucune instance du shader, on peut detruire ses textures
00897                 pShader->FlushAllTextures();
00898         }
00899 
00900         hShader = KSHADER_NO;
00901 }
00902 
00903 //---------------------------------------------------------------------------------------------------------------------
00904 void KShaderBank::UnloadTexture( KTEXTURE hTexture )
00905 {
00906         m_pRender->GetpTextureBank()->UnloadTexture( hTexture );
00907 }
00908 
00909 //---------------------------------------------------------------------------------------------------------------------
00910 KRBLEND KShaderBank::GetBlendByText( char* pBlendText )
00911 {
00912         if( stricmp( pBlendText, "GL_ZERO" ) == 0 )
00913                 return KRBLEND_ZERO;
00914         else
00915         if( stricmp( pBlendText, "GL_ONE" ) == 0 )
00916                 return KRBLEND_ONE;
00917         else
00918         if( stricmp( pBlendText, "GL_SRC_COLOR" ) == 0 )
00919                 return KRBLEND_SRC;
00920         else
00921         if( stricmp( pBlendText, "GL_ONE_MINUS_SRC_COLOR" ) == 0 )
00922                 return KRBLEND_INVSRC;
00923         else
00924         if( stricmp( pBlendText, "GL_DST_COLOR" ) == 0 )
00925                 return KRBLEND_DST;
00926         else
00927         if( stricmp( pBlendText, "GL_ONE_MINUS_DST_COLOR" ) == 0 )
00928                 return KRBLEND_INVDST;
00929         else
00930         if( stricmp( pBlendText, "GL_SRC_ALPHA" ) == 0 )
00931                 return KRBLEND_SRCALPHA;
00932         else
00933         if( stricmp( pBlendText, "GL_ONE_MINUS_SRC_ALPHA" ) == 0 )
00934                 return KRBLEND_INVSRCALPHA;
00935         else
00936         if( stricmp( pBlendText, "GL_DST_ALPHA" ) == 0 )
00937                 return KRBLEND_DSTALPHA;
00938         else
00939         if( stricmp( pBlendText, "GL_ONE_MINUS_DST_ALPHA" ) == 0 )
00940                 return KRBLEND_INVDSTALPHA;
00941         else
00942         if( stricmp( pBlendText, "GL_SRC_ALPHA_SATURATE" ) == 0 )
00943                 return KRBLEND_SRCALPHASAT;
00944 
00945         return (KRBLEND)-1;
00946 }
00947 
00948 //---------------------------------------------------------------------------------------------------------------------
00949 void KShaderBank::DumpUsed()
00950 {
00951         KSHADER         Handle;
00952         KShader*        pShader;
00953         s32                     n = 0;
00954 
00955         // Recherche le shader
00956         for( Handle = GethFirst(); Handle != KSHADER_NO; Handle = GethNext( Handle ) )
00957         {
00958                 pShader = GetpShader( Handle );
00959                 if( pShader && pShader->GetnInstances() )
00960                 {
00961                         g_Console << Handle << ":" << pShader->m_pName << " " << pShader->GetnInstances() << " instance(s)" << KENDL;
00962                         n ++;
00963                 }
00964         }
00965         g_Console << n << " shader(s) loaded." << KENDL;
00966 }
00967 

Generated on Sun Mar 25 20:02:16 2007 for Zythum Project by  doxygen 1.5.1-p1