#include <glib/gslist.h>
#include "debugging/debugging.h"
-#include "string/string.h"
+#include "string/pooledstring.h"
#include "math/vector.h"
#include "generic/callback.h"
#include "generic/referencecounted.h"
return GlobalTexturesCache().loadImage(name);
}
-
+class ShaderPoolContext
+{
+};
+typedef Static<StringPool, ShaderPoolContext> ShaderPool;
+typedef PooledString<ShaderPool> ShaderString;
+typedef ShaderString ShaderVariable;
+typedef ShaderString ShaderValue;
+typedef CopiedString TextureExpression;
// clean a texture name to the qtexture_t name format we use internally
// NOTE: case sensitivity: the engine is case sensitive. we store the shader name with case information and save with case
// information as well. but we assume there won't be any case conflict and so when doing lookups based on shader name,
// we compare as case insensitive. That is Radiant is case insensitive, but knows that the engine is case sensitive.
//++timo FIXME: we need to put code somewhere to detect when two shaders that are case insensitive equal are present
-void parseTextureName(CopiedString& name, const char* token)
+template<typename StringType>
+void parseTextureName(StringType& name, const char* token)
{
StringOutputStream cleaned(256);
cleaned << PathCleaned(token);
- name = CopiedString(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str())); // remove extension
+ name = CopiedString(StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str()))).c_str(); // remove extension
}
-bool Tokeniser_parseTextureName(Tokeniser& tokeniser, CopiedString& name)
+bool Tokeniser_parseTextureName(Tokeniser& tokeniser, TextureExpression& name)
{
const char* token = tokeniser.getToken();
if(token == 0)
return true;
}
-void parseShaderName(CopiedString& name, const char* token)
-{
- StringOutputStream cleaned(256);
- cleaned << PathCleaned(token);
- name = cleaned.c_str();
-}
-
bool Tokeniser_parseShaderName(Tokeniser& tokeniser, CopiedString& name)
{
const char* token = tokeniser.getToken();
Tokeniser_unexpectedError(tokeniser, token, "#shader-name");
return false;
}
- parseShaderName(name, token);
+ parseTextureName(name, token);
return true;
}
-bool Tokeniser_parseString(Tokeniser& tokeniser, CopiedString& string)
+bool Tokeniser_parseString(Tokeniser& tokeniser, ShaderString& string)
{
const char* token = tokeniser.getToken();
if(token == 0)
-typedef std::list<CopiedString> ShaderParameters;
-typedef std::list<CopiedString> ShaderArguments;
+typedef std::list<ShaderVariable> ShaderParameters;
+typedef std::list<ShaderVariable> ShaderArguments;
-typedef CopiedString TextureExpression;
-typedef CopiedString ShaderValue;
-typedef std::pair<CopiedString, CopiedString> BlendFuncExpression;
+typedef std::pair<ShaderVariable, ShaderVariable> BlendFuncExpression;
class ShaderTemplate
{
};
-bool Doom3Shader_parseHeightmap(Tokeniser& tokeniser, CopiedString& bump, CopiedString& heightmapScale)
+bool Doom3Shader_parseHeightmap(Tokeniser& tokeniser, TextureExpression& bump, ShaderValue& heightmapScale)
{
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
RETURN_FALSE_IF_FAIL(Tokeniser_parseTextureName(tokeniser, bump));
return true;
}
-bool Doom3Shader_parseAddnormals(Tokeniser& tokeniser, CopiedString& bump)
+bool Doom3Shader_parseAddnormals(Tokeniser& tokeniser, TextureExpression& bump)
{
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
RETURN_FALSE_IF_FAIL(Tokeniser_parseTextureName(tokeniser, bump));
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ","));
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "heightmap"));
- CopiedString heightmapName;
- CopiedString heightmapScale;
+ TextureExpression heightmapName;
+ ShaderValue heightmapScale;
RETURN_FALSE_IF_FAIL(Doom3Shader_parseHeightmap(tokeniser, heightmapName, heightmapScale));
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")"));
return true;
}
-bool Doom3Shader_parseBumpmap(Tokeniser& tokeniser, CopiedString& bump, CopiedString& heightmapScale)
+bool Doom3Shader_parseBumpmap(Tokeniser& tokeniser, TextureExpression& bump, ShaderValue& heightmapScale)
{
const char* token = tokeniser.getToken();
if(token == 0)
{
public:
LayerTypeId m_type;
- CopiedString m_texture;
+ TextureExpression m_texture;
BlendFuncExpression m_blendFunc;
bool m_clampToBorder;
ShaderValue m_alphaTest;
if(string_equal_nocase(lightFalloffImage, "makeintensity"))
{
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
- CopiedString name;
+ TextureExpression name;
RETURN_FALSE_IF_FAIL(Tokeniser_parseTextureName(tokeniser, name));
- m_lightFalloffImage = name.c_str();
+ m_lightFalloffImage = name;
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")"));
}
else
bool parseTemplateInstance(Tokeniser& tokeniser, const char* filename)
{
CopiedString name;
- RETURN_FALSE_IF_FAIL(Tokeniser_parseTextureName(tokeniser, name));
+ RETURN_FALSE_IF_FAIL(Tokeniser_parseShaderName(tokeniser, name));
const char* templateName = tokeniser.getToken();
ShaderTemplate* shaderTemplate = findTemplate(templateName);
if(shaderTemplate == 0)
}
realiseLighting();
-
- 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 unrealise()
{
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";
+ }
+ }
+ }
}
}
GlobalTexturesCache().release((*i).texture());
}
m_layers.clear();
+
+ m_blendFunc = BlendFunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA);
}
}
bool ShaderTemplate::parseQuake3(Tokeniser& tokeniser)
{
// name of the qtexture_t we'll use to represent this shader (this one has the "textures\" before)
- m_textureName = m_Name;
+ m_textureName = m_Name.c_str();
tokeniser.nextLine();
{
public:
LayerTypeId m_type;
- CopiedString m_texture;
+ TextureExpression m_texture;
BlendFunc m_blendFunc;
bool m_clampToBorder;
float m_alphaTest;
lst = lst->next;
}
}
+
+ //StringPool_analyse(ShaderPool::instance());
}
void Shaders_Free()