- static bool m_lightingEnabled;
-
- CShader(const ShaderDefinition& definition) :
- m_refcount(0),
- m_template(*definition.shaderTemplate),
- m_args(definition.args),
- m_filename(definition.filename),
- m_blendFunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA),
- m_bInUse(false)
- {
- m_pTexture = 0;
- m_pDiffuse = 0;
- m_pBump = 0;
- m_pSpecular = 0;
-
- m_notfound = 0;
-
- realise();
- }
- virtual ~CShader()
- {
- unrealise();
-
- ASSERT_MESSAGE(m_refcount == 0, "deleting active shader");
- }
-
- // IShaders implementation -----------------
- void IncRef()
- {
- ++m_refcount;
- }
- void DecRef()
- {
- ASSERT_MESSAGE(m_refcount != 0, "shader reference-count going below zero");
- if(--m_refcount == 0)
- {
- delete this;
- }
- }
-
- std::size_t refcount()
- {
- return m_refcount;
- }
-
- // get/set the qtexture_t* Radiant uses to represent this shader object
- 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();
- }
- 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)
- const char* getShaderFileName() const
- {
- return m_filename;
- }
- // -----------------------------------------
-
- void realise()
- {
- m_pTexture = evaluateTexture(m_template.m_textureName, m_template.m_params, m_args);
-
- if(m_pTexture->texture_number == 0)
- {
- m_notfound = m_pTexture;
-
- {
- StringOutputStream name(256);
- name << GlobalRadiant().getAppPath() << "bitmaps/" << (IsDefault() ? "notex.bmp" : "shadernotex.bmp");
- m_pTexture = GlobalTexturesCache().capture(LoadImageCallback(0, loadBitmap), name.c_str());
- }
- }
-
- realiseLighting();
- }
-
- void unrealise()
- {
- GlobalTexturesCache().release(m_pTexture);
-
- if(m_notfound != 0)
- {
- GlobalTexturesCache().release(m_notfound);
- }
-
- unrealiseLighting();
- }
-
- void realiseLighting()
- {
- if(m_lightingEnabled)
- {
- LoadImageCallback loader = GlobalTexturesCache().defaultLoader();
- if(!string_empty(m_template.m_heightmapScale.c_str()))
- {
- m_heightmapScale = evaluateFloat(m_template.m_heightmapScale, m_template.m_params, m_args);
- loader = LoadImageCallback(&m_heightmapScale, loadHeightmap);
- }
- m_pDiffuse = evaluateTexture(m_template.m_diffuse, m_template.m_params, m_args);
- m_pBump = evaluateTexture(m_template.m_bump, m_template.m_params, m_args, loader);
- m_pSpecular = evaluateTexture(m_template.m_specular, m_template.m_params, m_args);
- m_pLightFalloffImage = evaluateTexture(m_template.m_lightFalloffImage, m_template.m_params, m_args);
-
- for(ShaderTemplate::MapLayers::const_iterator i = m_template.m_layers.begin(); i != m_template.m_layers.end(); ++i)
- {
- m_layers.push_back(evaluateLayer(*i, m_template.m_params, m_args));
- }
-
- if(m_layers.size() == 1)
- {
- const BlendFuncExpression& blendFunc = m_template.m_layers.front().blendFunc();
- if(!string_empty(blendFunc.second.c_str()))
- {
- m_blendFunc = BlendFunc(
- evaluateBlendFactor(blendFunc.first.c_str(), m_template.m_params, m_args),
- evaluateBlendFactor(blendFunc.second.c_str(), m_template.m_params, m_args)
- );
- }
- else
- {
- const char* blend = evaluateShaderValue(blendFunc.first.c_str(), m_template.m_params, m_args);
-
- if(string_equal_nocase(blend, "add"))
- {
- m_blendFunc = BlendFunc(BLEND_ONE, BLEND_ONE);
- }
- else if(string_equal_nocase(blend, "filter"))
- {
- m_blendFunc = BlendFunc(BLEND_DST_COLOUR, BLEND_ZERO);
- }
- else if(string_equal_nocase(blend, "blend"))
- {
- m_blendFunc = BlendFunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- globalErrorStream() << "parsing blend value failed: " << makeQuoted(blend) << "\n";
- }
- }
- }
- }
- }
-
- void unrealiseLighting()
- {
- if(m_lightingEnabled)
- {
- GlobalTexturesCache().release(m_pDiffuse);
- GlobalTexturesCache().release(m_pBump);
- GlobalTexturesCache().release(m_pSpecular);
-
- GlobalTexturesCache().release(m_pLightFalloffImage);
-
- for(MapLayers::iterator i = m_layers.begin(); i != m_layers.end(); ++i)
- {
- GlobalTexturesCache().release((*i).texture());
- }
- m_layers.clear();
-
- m_blendFunc = BlendFunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA);
- }
- }
-
- // set shader name
- void setName(const char* name)
- {
- m_Name = name;
- }
-
- class MapLayer : public ShaderLayer
- {
- qtexture_t* m_texture;
- BlendFunc m_blendFunc;
- bool m_clampToBorder;
- float m_alphaTest;
- public:
- MapLayer(qtexture_t* texture, BlendFunc blendFunc, bool clampToBorder, float alphaTest) :
- m_texture(texture),
- m_blendFunc(blendFunc),
- 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;
- }
- };
-
- 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)
- );
- }
-
- typedef std::vector<MapLayer> MapLayers;
- MapLayers m_layers;
-
- const ShaderLayer* firstLayer() const
- {
- if(m_layers.empty())
- {
- return 0;
- }
- 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()))
- {
- return m_pLightFalloffImage;
- }
- return 0;
- }
+MapLayer( qtexture_t* texture, BlendFunc blendFunc, bool clampToBorder, float alphaTest ) :
+ m_texture( texture ),
+ m_blendFunc( blendFunc ),
+ 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;
+}
+};
+
+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 )
+ );
+}
+
+typedef std::vector<MapLayer> MapLayers;
+MapLayers m_layers;
+
+const ShaderLayer* firstLayer() const {
+ if ( m_layers.empty() ) {
+ return 0;
+ }
+ 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() ) ) {
+ return m_pLightFalloffImage;
+ }
+ return 0;
+}