]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/shaders/shaders.cpp
Merge branch 'NateEag-master-patch-12920' into 'master'
[xonotic/netradiant.git] / plugins / shaders / shaders.cpp
index a7a3078dbbde5f319d21b777f7fde25ad25184e3..14308bad3b10beb8a005cdfe677bb7b64e066d82 100644 (file)
 //
 // Shaders Manager Plugin
 //
-// Leonardo Zide (leo@lokigames.com)
+// Leonardo Zide ( leo@lokigames.com )
 //
 
+#include "defaults.h"
 #include "shaders.h"
+#include "globaldefs.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -75,18 +77,21 @@ bool g_enableDefaultShaders = true;
 ShaderLanguage g_shaderLanguage = SHADERLANGUAGE_QUAKE3;
 bool g_useShaderList = true;
 _QERPlugImageTable* g_bitmapModule = 0;
-const char* g_texturePrefix = "textures/";
+const char* g_texturePrefix = DEFAULT_TEXTURE_DIRNAME;
 
 void ActiveShaders_IteratorBegin();
+
 bool ActiveShaders_IteratorAtEnd();
+
 IShader *ActiveShaders_IteratorCurrent();
+
 void ActiveShaders_IteratorIncrement();
-Callback g_ActiveShadersChangedNotify;
+
+Callback<void()> g_ActiveShadersChangedNotify;
 
 void FreeShaders();
-void LoadShaderFile( const char *filename );
-qtexture_t *Texture_ForName( const char *filename );
 
+void LoadShaderFile( const char *filename );
 
 /*!
    NOTE TTimo: there is an important distinction between SHADER_NOT_FOUND and SHADER_NOTEX:
@@ -203,22 +208,10 @@ Image* loadHeightmap( void* environment, const char* name ){
        return 0;
 }
 
-
-Image* loadSpecial( void* environment, const char* name ){
-       if ( *name == '_' ) { // special image
-               StringOutputStream bitmapName( 256 );
-               bitmapName << GlobalRadiant().getAppPath() << "bitmaps/" << name + 1 << ".png";
-               Image* image = loadBitmap( environment, bitmapName.c_str() );
-               if ( image != 0 ) {
-                       return image;
-               }
-       }
-       return GlobalTexturesCache().loadImage( name );
-}
-
 class ShaderPoolContext
 {
 };
+
 typedef Static<StringPool, ShaderPoolContext> ShaderPool;
 typedef PooledString<ShaderPool> ShaderString;
 typedef ShaderString ShaderVariable;
@@ -268,7 +261,6 @@ bool Tokeniser_parseString( Tokeniser& tokeniser, ShaderString& string ){
 }
 
 
-
 typedef std::list<ShaderVariable> ShaderParameters;
 typedef std::list<ShaderVariable> ShaderArguments;
 
@@ -278,6 +270,7 @@ class ShaderTemplate
 {
 std::size_t m_refcount;
 CopiedString m_Name;
+CopiedString m_WadName;
 public:
 
 ShaderParameters m_params;
@@ -307,6 +300,7 @@ ShaderTemplate() :
 void IncRef(){
        ++m_refcount;
 }
+
 void DecRef(){
        ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" );
        if ( --m_refcount == 0 ) {
@@ -321,6 +315,7 @@ std::size_t refcount(){
 const char* getName() const {
        return m_Name.c_str();
 }
+
 void setName( const char* name ){
        m_Name = name;
 }
@@ -328,7 +323,9 @@ void setName( const char* name ){
 // -----------------------------------------
 
 bool parseDoom3( Tokeniser& tokeniser );
+
 bool parseQuake3( Tokeniser& tokeniser );
+
 bool parseTemplate( Tokeniser& tokeniser );
 
 
@@ -357,19 +354,24 @@ MapLayerTemplate( const TextureExpression& texture, const BlendFuncExpression& b
        m_clampToBorder( false ),
        m_alphaTest( alphaTest ){
 }
+
 const TextureExpression& texture() const {
        return m_texture;
 }
+
 const BlendFuncExpression& blendFunc() const {
        return m_blendFunc;
 }
+
 bool clampToBorder() const {
        return m_clampToBorder;
 }
+
 const ShaderValue& alphaTest() const {
        return m_alphaTest;
 }
 };
+
 typedef std::vector<MapLayerTemplate> MapLayers;
 MapLayers m_layers;
 };
@@ -633,7 +635,7 @@ bool ShaderTemplate::parseDoom3( Tokeniser& tokeniser ){
                                m_nFlags |= QER_NONSOLID;
                        }
                        else if ( string_equal_nocase( token, "liquid" ) ) {
-                               m_nFlags |= QER_WATER;
+                               m_nFlags |= QER_LIQUID;
                        }
                        else if ( string_equal_nocase( token, "areaportal" ) ) {
                                m_nFlags |= QER_AREAPORTAL;
@@ -695,6 +697,7 @@ public:
 ShaderDefinition( ShaderTemplate* shaderTemplate, const ShaderArguments& args, const char* filename )
        : shaderTemplate( shaderTemplate ), args( args ), filename( filename ){
 }
+
 ShaderTemplate* shaderTemplate;
 ShaderArguments args;
 const char* filename;
@@ -837,8 +840,9 @@ std::size_t m_refcount;
 const ShaderTemplate& m_template;
 const ShaderArguments& m_args;
 const char* m_filename;
-// name is shader-name, otherwise texture-name (if not a real shader)
+// name is shader-name, otherwise texture-name ( if not a real shader )
 CopiedString m_Name;
+CopiedString m_WadName;
 
 qtexture_t* m_pTexture;
 qtexture_t* m_notfound;
@@ -871,6 +875,7 @@ CShader( const ShaderDefinition& definition ) :
 
        realise();
 }
+
 virtual ~CShader(){
        unrealise();
 
@@ -881,6 +886,7 @@ virtual ~CShader(){
 void IncRef(){
        ++m_refcount;
 }
+
 void DecRef(){
        ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" );
        if ( --m_refcount == 0 ) {
@@ -896,48 +902,64 @@ std::size_t refcount(){
 qtexture_t* getTexture() const {
        return m_pTexture;
 }
+
 qtexture_t* getDiffuse() const {
        return m_pDiffuse;
 }
+
 qtexture_t* getBump() const {
        return m_pBump;
 }
+
 qtexture_t* getSpecular() const {
        return m_pSpecular;
 }
+
 // get shader name
 const char* getName() const {
        return m_Name.c_str();
 }
+
+const char* getWadName() const {
+       return m_WadName.c_str();
+}
+
 bool IsInUse() const {
        return m_bInUse;
 }
+
 void SetInUse( bool bInUse ){
        m_bInUse = bInUse;
        g_ActiveShadersChangedNotify();
 }
+
 // get the shader flags
 int getFlags() const {
        return m_template.m_nFlags;
 }
+
 // get the transparency value
 float getTrans() const {
        return m_template.m_fTrans;
 }
+
 // test if it's a true shader, or a default shader created to wrap around a texture
 bool IsDefault() const {
        return string_empty( m_filename );
 }
+
 // get the alphaFunc
 void getAlphaFunc( EAlphaFunc *func, float *ref ) { *func = m_template.m_AlphaFunc; *ref = m_template.m_AlphaRef; };
 BlendFunc getBlendFunc() const {
        return m_blendFunc;
 }
+
 // get the cull type
 ECull getCull(){
        return m_template.m_Cull;
 };
-// get shader file name (ie the file where this one is defined)
+
+// get shader file name ( ie the file where this one is defined )
 const char* getShaderFileName() const {
        return m_filename;
 }
@@ -950,9 +972,7 @@ void realise(){
                m_notfound = m_pTexture;
 
                {
-                       StringOutputStream name( 256 );
-                       name << GlobalRadiant().getAppPath() << "bitmaps/" << ( IsDefault() ? "notex.png" : "shadernotex.png" );
-                       m_pTexture = GlobalTexturesCache().capture( LoadImageCallback( 0, loadBitmap ), name.c_str() );
+                       m_pTexture = GlobalTexturesCache().capture( IsDefault() ? DEFAULT_NOTEX_NAME : DEFAULT_SHADERNOTEX_NAME );
                }
        }
 
@@ -1039,6 +1059,10 @@ void setName( const char* name ){
        m_Name = name;
 }
 
+void setWadName( const char* name ){
+       m_WadName = name;
+}
+
 class MapLayer : public ShaderLayer
 {
 qtexture_t* m_texture;
@@ -1052,15 +1076,19 @@ MapLayer( qtexture_t* texture, BlendFunc blendFunc, bool clampToBorder, float al
        m_clampToBorder( false ),
        m_alphaTest( alphaTest ){
 }
+
 qtexture_t* texture() const {
        return m_texture;
 }
+
 BlendFunc blendFunc() const {
        return m_blendFunc;
 }
+
 bool clampToBorder() const {
        return m_clampToBorder;
 }
+
 float alphaTest() const {
        return m_alphaTest;
 }
@@ -1068,11 +1096,11 @@ float alphaTest() const {
 
 static MapLayer evaluateLayer( const ShaderTemplate::MapLayerTemplate& layerTemplate, const ShaderParameters& params, const ShaderArguments& args ){
        return MapLayer(
-                          evaluateTexture( layerTemplate.texture(), params, args ),
-                          evaluateBlendFunc( layerTemplate.blendFunc(), params, args ),
-                          layerTemplate.clampToBorder(),
-                          evaluateFloat( layerTemplate.alphaTest(), params, args )
-                          );
+                       evaluateTexture( layerTemplate.texture(), params, args ),
+                       evaluateBlendFunc( layerTemplate.blendFunc(), params, args ),
+                       layerTemplate.clampToBorder(),
+                       evaluateFloat( layerTemplate.alphaTest(), params, args )
+                       );
 }
 
 typedef std::vector<MapLayer> MapLayers;
@@ -1084,12 +1112,6 @@ const ShaderLayer* firstLayer() const {
        }
        return &m_layers.front();
 }
-void forEachLayer( const ShaderLayerCallback& callback ) const {
-       for ( MapLayers::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i )
-       {
-               callback( *i );
-       }
-}
 
 qtexture_t* lightFalloffImage() const {
        if ( !string_empty( m_template.m_lightFalloffImage.c_str() ) ) {
@@ -1145,7 +1167,7 @@ void FreeShaders(){
 }
 
 bool ShaderTemplate::parseQuake3( Tokeniser& tokeniser ){
-       // name of the qtexture_t we'll use to represent this shader (this one has the "textures\" before)
+       // name of the qtexture_t we'll use to represent this shader ( this one has the "textures\" before )
        m_textureName = m_Name.c_str();
 
        tokeniser.nextLine();
@@ -1255,6 +1277,7 @@ bool ShaderTemplate::parseQuake3( Tokeniser& tokeniser ){
 
                                if ( string_equal_nocase( surfaceparm, "fog" ) ) {
                                        m_nFlags |= QER_FOG;
+                                       m_nFlags |= QER_TRANS;
                                        if ( m_fTrans == 1.0f ) { // has not been explicitly set by qer_trans
                                                m_fTrans = 0.35f;
                                        }
@@ -1265,11 +1288,10 @@ bool ShaderTemplate::parseQuake3( Tokeniser& tokeniser ){
                                else if ( string_equal_nocase( surfaceparm, "nonsolid" ) ) {
                                        m_nFlags |= QER_NONSOLID;
                                }
-                               else if ( string_equal_nocase( surfaceparm, "water" ) ) {
-                                       m_nFlags |= QER_WATER;
-                               }
-                               else if ( string_equal_nocase( surfaceparm, "lava" ) ) {
-                                       m_nFlags |= QER_LAVA;
+                               else if ( string_equal_nocase( surfaceparm, "water" ) ||
+                                                       string_equal_nocase( surfaceparm, "lava" ) ||
+                                                       string_equal_nocase( surfaceparm, "slime") ){
+                                       m_nFlags |= QER_LIQUID;
                                }
                                else if ( string_equal_nocase( surfaceparm, "areaportal" ) ) {
                                        m_nFlags |= QER_AREAPORTAL;
@@ -1354,7 +1376,7 @@ void ParseShaderFile( Tokeniser& tokeniser, const char* filename ){
                                         && !string_equal( token, "skin" ) ) {
                                        tokeniser.ungetToken();
                                }
-                               // first token should be the path + name.. (from base)
+                               // first token should be the path + name.. ( from base )
                                CopiedString name;
                                if ( !Tokeniser_parseShaderName( tokeniser, name ) ) {
                                }
@@ -1369,9 +1391,9 @@ void ParseShaderFile( Tokeniser& tokeniser, const char* filename ){
                                if ( result ) {
                                        // do we already have this shader?
                                        if ( !g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( shaderTemplate->getName(), ShaderDefinition( shaderTemplate.get(), ShaderArguments(), filename ) ) ).second ) {
-  #ifdef _DEBUG
+#if GDEF_DEBUG
                                                globalOutputStream() << "WARNING: shader " << shaderTemplate->getName() << " is already in memory, definition in " << filename << " ignored.\n";
-  #endif
+#endif
                                        }
                                }
                                else
@@ -1395,7 +1417,7 @@ void parseGuideFile( Tokeniser& tokeniser, const char* filename ){
                }
 
                if ( string_equal( token, "guide" ) ) {
-                       // first token should be the path + name.. (from base)
+                       // first token should be the path + name.. ( from base )
                        ShaderTemplatePointer shaderTemplate( new ShaderTemplate );
                        shaderTemplate->parseTemplate( tokeniser );
                        if ( !g_shaderTemplates.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ).second ) {
@@ -1441,9 +1463,6 @@ void LoadShaderFile( const char* filename ){
        }
 }
 
-typedef FreeCaller1<const char*, LoadShaderFile> LoadShaderFileCaller;
-
-
 void loadGuideFile( const char* filename ){
        StringOutputStream fullname( 256 );
        fullname << "guides/" << filename;
@@ -1465,9 +1484,6 @@ void loadGuideFile( const char* filename ){
        }
 }
 
-typedef FreeCaller1<const char*, loadGuideFile> LoadGuideFileCaller;
-
-
 CShader* Try_Shader_ForName( const char* name ){
        {
                shaders_t::iterator i = g_ActiveShaders.find( name );
@@ -1507,8 +1523,6 @@ IShader *Shader_ForName( const char *name ){
 }
 
 
-
-
 // the list of scripts/*.shader files we need to work with
 // those are listed in shaderlist file
 GSList *l_shaderfiles = 0;
@@ -1542,7 +1556,8 @@ void IfFound_dumpUnreferencedShader( bool& bFound, const char* filename ){
                globalOutputStream() << "\t" << filename << "\n";
        }
 }
-typedef ReferenceCaller1<bool, const char*, IfFound_dumpUnreferencedShader> IfFoundDumpUnreferencedShaderCaller;
+
+typedef ReferenceCaller<bool, void(const char*), IfFound_dumpUnreferencedShader> IfFoundDumpUnreferencedShaderCaller;
 
 void DumpUnreferencedShaders(){
        bool bFound = false;
@@ -1566,9 +1581,6 @@ void ShaderList_addShaderFile( const char* dirstring ){
        }
 }
 
-typedef FreeCaller1<const char*, ShaderList_addShaderFile> AddShaderFileCaller;
-
-
 /*
    ==================
    BuildShaderList
@@ -1623,8 +1635,6 @@ void ShaderList_addFromArchive( const char *archivename ){
        }
 }
 
-typedef FreeCaller1<const char *, ShaderList_addFromArchive> AddShaderListFromArchiveCaller;
-
 #include "stream/filestream.h"
 
 bool shaderlist_findOrInstall( const char* enginePath, const char* toolsPath, const char* shaderPath, const char* gamename ){
@@ -1652,7 +1662,7 @@ bool shaderlist_findOrInstall( const char* enginePath, const char* toolsPath, co
 
 void Shaders_Load(){
        if ( g_shaderLanguage == SHADERLANGUAGE_QUAKE4 ) {
-               GlobalFileSystem().forEachFile( "guides/", "guide", LoadGuideFileCaller(), 0 );
+               GlobalFileSystem().forEachFile("guides/", "guide", makeCallbackF(loadGuideFile), 0);
        }
 
        const char* shaderPath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" );
@@ -1674,12 +1684,12 @@ void Shaders_Load(){
                                shaderlist_findOrInstall( enginePath, toolsPath, path.c_str(), gamename );
                        }
 
-                       GlobalFileSystem().forEachArchive( AddShaderListFromArchiveCaller(), false, true );
+                       GlobalFileSystem().forEachArchive(makeCallbackF(ShaderList_addFromArchive), false, true);
                        DumpUnreferencedShaders();
                }
                else
                {
-                       GlobalFileSystem().forEachFile( path.c_str(), g_shadersExtension, AddShaderFileCaller(), 0 );
+                       GlobalFileSystem().forEachFile(path.c_str(), g_shadersExtension, makeCallbackF(ShaderList_addShaderFile), 0);
                }
 
                GSList *lst = l_shaderfiles;
@@ -1693,7 +1703,7 @@ void Shaders_Load(){
                }
        }
 
-       //StringPool_analyse(ShaderPool::instance());
+       //StringPool_analyse( ShaderPool::instance() );
 }
 
 void Shaders_Free(){
@@ -1708,12 +1718,14 @@ std::size_t g_shaders_unrealised = 1; // wait until filesystem and is realised b
 bool Shaders_realised(){
        return g_shaders_unrealised == 0;
 }
+
 void Shaders_Realise(){
        if ( --g_shaders_unrealised == 0 ) {
                Shaders_Load();
                g_observers.realise();
        }
 }
+
 void Shaders_Unrealise(){
        if ( ++g_shaders_unrealised == 1 ) {
                g_observers.unrealise();
@@ -1732,9 +1744,11 @@ public:
 void realise(){
        Shaders_Realise();
 }
+
 void unrealise(){
        Shaders_Unrealise();
 }
+
 void refresh(){
        Shaders_Refresh();
 }
@@ -1753,22 +1767,27 @@ void foreachShaderName( const ShaderNameCallback& callback ){
 void beginActiveShadersIterator(){
        ActiveShaders_IteratorBegin();
 }
+
 bool endActiveShadersIterator(){
        return ActiveShaders_IteratorAtEnd();
 }
+
 IShader* dereferenceActiveShadersIterator(){
        return ActiveShaders_IteratorCurrent();
 }
+
 void incrementActiveShadersIterator(){
        ActiveShaders_IteratorIncrement();
 }
-void setActiveShadersChangedNotify( const Callback& notify ){
+
+void setActiveShadersChangedNotify( const Callback<void()>& notify ){
        g_ActiveShadersChangedNotify = notify;
 }
 
 void attach( ModuleObserver& observer ){
        g_observers.attach( observer );
 }
+
 void detach( ModuleObserver& observer ){
        g_observers.detach( observer );
 }
@@ -1801,6 +1820,7 @@ ShaderSystem& GetShaderSystem(){
 void Shaders_Construct(){
        GlobalFileSystem().attach( g_Quake3ShaderSystem );
 }
+
 void Shaders_Destroy(){
        GlobalFileSystem().detach( g_Quake3ShaderSystem );