//
// 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>
#include "qerplugin.h"
#include "irender.h"
-#include <glib/gslist.h>
+#include <glib.h>
#include "debugging/debugging.h"
#include "string/pooledstring.h"
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 );
return 0;
}
-
-Image* loadSpecial( void* environment, const char* name ){
- if ( *name == '_' ) { // special image
- StringOutputStream bitmapName( 256 );
- bitmapName << GlobalRadiant().getAppPath() << "bitmaps/" << name + 1 << ".bmp";
- 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;
}
-
typedef std::list<ShaderVariable> ShaderParameters;
typedef std::list<ShaderVariable> ShaderArguments;
void IncRef(){
++m_refcount;
}
+
void DecRef(){
ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" );
if ( --m_refcount == 0 ) {
const char* getName() const {
return m_Name.c_str();
}
+
void setName( const char* name ){
m_Name = name;
}
// -----------------------------------------
bool parseDoom3( Tokeniser& tokeniser );
+
bool parseQuake3( Tokeniser& tokeniser );
+
bool parseTemplate( Tokeniser& tokeniser );
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;
};
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;
ShaderDefinition( ShaderTemplate* shaderTemplate, const ShaderArguments& args, const char* filename )
: shaderTemplate( shaderTemplate ), args( args ), filename( filename ){
}
+
ShaderTemplate* shaderTemplate;
ShaderArguments args;
const char* filename;
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;
qtexture_t* m_pTexture;
realise();
}
+
virtual ~CShader(){
unrealise();
void IncRef(){
++m_refcount;
}
+
void DecRef(){
ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" );
if ( --m_refcount == 0 ) {
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)
+
+// get shader file name ( ie the file where this one is defined )
const char* getShaderFileName() const {
return m_filename;
}
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() );
+ m_pTexture = GlobalTexturesCache().capture( IsDefault() ? DEFAULT_NOTEX_NAME : DEFAULT_SHADERNOTEX_NAME );
}
}
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 )
- );
+ evaluateTexture( layerTemplate.texture(), params, args ),
+ evaluateBlendFunc( layerTemplate.blendFunc(), params, args ),
+ layerTemplate.clampToBorder(),
+ evaluateFloat( layerTemplate.alphaTest(), params, args )
+ );
}
typedef std::vector<MapLayer> MapLayers;
}
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();
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;
}
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;
&& !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 ) ) {
}
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
}
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 ) {
}
}
-typedef FreeCaller1<const char*, LoadShaderFile> LoadShaderFileCaller;
-
-
void loadGuideFile( const char* filename ){
StringOutputStream fullname( 256 );
fullname << "guides/" << filename;
}
}
-typedef FreeCaller1<const char*, loadGuideFile> LoadGuideFileCaller;
-
-
CShader* Try_Shader_ForName( const char* name ){
{
shaders_t::iterator i = g_ActiveShaders.find( name );
}
-
-
// the list of scripts/*.shader files we need to work with
// those are listed in shaderlist file
GSList *l_shaderfiles = 0;
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;
}
}
-typedef FreeCaller1<const char*, ShaderList_addShaderFile> AddShaderFileCaller;
-
-
/*
==================
BuildShaderList
}
}
-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 ){
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" );
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;
}
}
- //StringPool_analyse(ShaderPool::instance());
+ //StringPool_analyse( ShaderPool::instance() );
}
void Shaders_Free(){
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();
void realise(){
Shaders_Realise();
}
+
void unrealise(){
Shaders_Unrealise();
}
+
void refresh(){
Shaders_Refresh();
}
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 );
}
void Shaders_Construct(){
GlobalFileSystem().attach( g_Quake3ShaderSystem );
}
+
void Shaders_Destroy(){
GlobalFileSystem().detach( g_Quake3ShaderSystem );