X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=plugins%2Fshaders%2Fshaders.cpp;h=a78a660202f834d07595963ca2c2d81be810774a;hp=a7a3078dbbde5f319d21b777f7fde25ad25184e3;hb=124e1494d744288a6a0a693fe5c38a03233f219a;hpb=b76bdbdcb68e84944acdb5ea7e5402e337c0f848 diff --git a/plugins/shaders/shaders.cpp b/plugins/shaders/shaders.cpp index a7a3078d..a78a6602 100644 --- a/plugins/shaders/shaders.cpp +++ b/plugins/shaders/shaders.cpp @@ -31,10 +31,12 @@ // // Shaders Manager Plugin // -// Leonardo Zide (leo@lokigames.com) +// Leonardo Zide ( leo@lokigames.com ) // +#include "defaults.h" #include "shaders.h" +#include "globaldefs.h" #include #include @@ -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 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 ShaderPool; typedef PooledString ShaderString; typedef ShaderString ShaderVariable; @@ -268,7 +261,6 @@ bool Tokeniser_parseString( Tokeniser& tokeniser, ShaderString& string ){ } - typedef std::list ShaderParameters; typedef std::list 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 MapLayers; MapLayers m_layers; }; @@ -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 MapLayers; @@ -1145,7 +1173,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(); @@ -1354,7 +1382,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 +1397,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 +1423,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 +1469,6 @@ void LoadShaderFile( const char* filename ){ } } -typedef FreeCaller1 LoadShaderFileCaller; - - void loadGuideFile( const char* filename ){ StringOutputStream fullname( 256 ); fullname << "guides/" << filename; @@ -1465,9 +1490,6 @@ void loadGuideFile( const char* filename ){ } } -typedef FreeCaller1 LoadGuideFileCaller; - - CShader* Try_Shader_ForName( const char* name ){ { shaders_t::iterator i = g_ActiveShaders.find( name ); @@ -1507,8 +1529,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 +1562,8 @@ void IfFound_dumpUnreferencedShader( bool& bFound, const char* filename ){ globalOutputStream() << "\t" << filename << "\n"; } } -typedef ReferenceCaller1 IfFoundDumpUnreferencedShaderCaller; + +typedef ReferenceCaller IfFoundDumpUnreferencedShaderCaller; void DumpUnreferencedShaders(){ bool bFound = false; @@ -1566,9 +1587,6 @@ void ShaderList_addShaderFile( const char* dirstring ){ } } -typedef FreeCaller1 AddShaderFileCaller; - - /* ================== BuildShaderList @@ -1623,8 +1641,6 @@ void ShaderList_addFromArchive( const char *archivename ){ } } -typedef FreeCaller1 AddShaderListFromArchiveCaller; - #include "stream/filestream.h" bool shaderlist_findOrInstall( const char* enginePath, const char* toolsPath, const char* shaderPath, const char* gamename ){ @@ -1652,7 +1668,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 +1690,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 +1709,7 @@ void Shaders_Load(){ } } - //StringPool_analyse(ShaderPool::instance()); + //StringPool_analyse( ShaderPool::instance() ); } void Shaders_Free(){ @@ -1708,12 +1724,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 +1750,11 @@ public: void realise(){ Shaders_Realise(); } + void unrealise(){ Shaders_Unrealise(); } + void refresh(){ Shaders_Refresh(); } @@ -1753,22 +1773,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& notify ){ g_ActiveShadersChangedNotify = notify; } void attach( ModuleObserver& observer ){ g_observers.attach( observer ); } + void detach( ModuleObserver& observer ){ g_observers.detach( observer ); } @@ -1801,6 +1826,7 @@ ShaderSystem& GetShaderSystem(){ void Shaders_Construct(){ GlobalFileSystem().attach( g_Quake3ShaderSystem ); } + void Shaders_Destroy(){ GlobalFileSystem().detach( g_Quake3ShaderSystem );