2007-11-04 03:34:51 +00:00
/*
Copyright ( C ) 1999 - 2007 id Software , Inc . and contributors .
For a list of contributors , see the accompanying CONTRIBUTORS file .
This file is part of GtkRadiant .
GtkRadiant is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
GtkRadiant is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with GtkRadiant ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
//-----------------------------------------------------------------------------
//
//
// DESCRIPTION:
// a set of functions to manipulate textures in Radiant
//
# ifndef __ISHADERS_H_
# define __ISHADERS_H_
# define SHADERS_MAJOR "shaders"
// define a GUID for this interface so plugins can access and reference it
// {D42F798A-DF57-11d3-A3EE-0004AC96D4C3}
static const GUID QERShadersTable_GUID =
{ 0xd42f798a , 0xdf57 , 0x11d3 , { 0xa3 , 0xee , 0x0 , 0x4 , 0xac , 0x96 , 0xd4 , 0xc3 } } ;
// NOTES ABOUT SYNTAX:
// if a function starts by 'Try' it means that if the requested thing could not be found / loaded it will return nothing / NULL
// otherwise a default object will be created
// the _QERShadersTable is also used by shader code inside Radiant. but for speed and "keep it simple" consideration you
// can get the static equivalent of the func pointers by adding 'QERApp_' (access to _QERShadersTable is better thought ..
// see the note to move all the shader language out of Radiant below)
/*!
\ todo FIXME TTimo
fix the reference count strategy
- define the policy . It seems the initial policy of doing an inc ref when you create the shader is not good
( it doesn ' t work , and it ' s not being used right )
so , when you request an IShader and store it , incref it yourself
as a debugging safe check : push the created increfed objects into a list , and scan them at next idle loop
to make sure they have been decref ' ed ? ( sounds easy , may not be that much ) .
*/
class IShader
{
public :
2008-02-18 20:54:58 +00:00
virtual ~ IShader ( ) { }
2007-11-04 03:34:51 +00:00
// Increment the number of references to this object
virtual void IncRef ( ) = 0 ;
// Decrement the reference count
virtual void DecRef ( ) = 0 ;
// get/set the qtexture_t* Radiant uses to represent this shader object
virtual qtexture_t * getTexture ( ) const = 0 ;
virtual void setTexture ( qtexture_t * pTex ) = 0 ;
// get shader name
virtual const char * getName ( ) const = 0 ;
// is this shader in use?
// NOTE: this flag can mean this shader has been in use at least once since the last rescan of in-use stuff
// (rescan of in-use happens in several cases, user command or during a texture directory load)
// NOTE: this is used to draw the green outline in the texture window
// NOTE: when does Radiant set the InUse flag? Whenever Select_SetTexture is called (well that doesn't necessarily means the texture actually gets in use, but that's close enough)
virtual bool IsInUse ( ) const = 0 ;
virtual void SetInUse ( bool ) = 0 ;
// is this shader displayed in the texture browser?
// NOTE: if IsInUse() == true, the shader will always be displayed in the texture window and this flag ingored
virtual bool IsDisplayed ( ) const = 0 ;
virtual void SetDisplayed ( bool ) = 0 ;
// get the editor flags (QER_NOCARVE QER_TRANS)
virtual int getFlags ( ) = 0 ;
// get the transparency value
virtual float getTrans ( ) = 0 ;
// test if it's a true shader, or a default shader created to wrap around a texture
virtual bool IsDefault ( ) = 0 ;
// test if it's a plain color shader, i.e. a shader we use on plain color stuff (like info_playerstart)
virtual bool IsColor ( ) = 0 ;
// get the related color then!
virtual void getColor ( vec3_t v ) = 0 ;
// get the alphaFunc
virtual void getAlphaFunc ( int * func , float * ref ) = 0 ;
// get the cull type
virtual int getCull ( ) = 0 ;
// get shader file name (ie the file where this one is defined)
virtual const char * getShaderFileName ( ) const = 0 ;
} ;
// NOTE: how to move all the shader language out of Radiant in a plugin?
// -> change this _QERShadersTable into an IShadersManager
// -> let the plugin create an instance of IShadersManager
// -> make sure Radiant uses this IShadersManager to load / query the shaders
// NOTE: shader and texture names used must be full path, ie. most often with "textures/" prefix
// (since shaders are defined in .shader files with textures/)
// free all shaders
// free the shaders, will not free the qtexture_t*
typedef void ( WINAPI * PFN_FREESHADERS ) ( ) ;
// reload all the shaders
// this will free everything (shaders and their textures), then reload all in use stuff
typedef void ( WINAPI * PFN_RELOADSHADERS ) ( ) ;
// load all shaders in a given directory
// this will scan the list of in-memory shaders, and load the related qtexture_t if needed
typedef int ( WINAPI * PFN_LOADSHADERSFROMDIR ) ( const char * path ) ;
// load a shader file (ie a set of shaders)
// after LoadShaderFile shaders will be in memory, next step is to load the qtexture_t Radiant uses to represent them
// if a shader with the same name exists, new one will not be loaded - don't use this to refresh the shaders!
typedef void ( WINAPI * PFN_LOADSHADERFILE ) ( const char * filename ) ;
// tell if a given shader exists in our shader table
// NOTE: this doesn't tell wether it's corresponding qtexture is loaded
typedef int ( WINAPI * PFN_HASSHADER ) ( const char * name ) ;
// return the shader for a given name
// if the qtexture is not already in memory, will try loading it
// if the qtexture could not be found, will use default
// will return NULL on shader not found
typedef IShader * ( WINAPI * PFN_TRYSHADERFORNAME ) ( const char * name ) ;
// return the shader for a given name
// if the qtexture is not already in memory, will try loading it
// will create a default shader if not found (will use a default texture)
typedef IShader * ( WINAPI * PFN_SHADERFORNAME ) ( const char * name ) ;
// query / load a texture
// will not try loading a shader, will look for the actual image file ..
// returns NULL on file not found
// NOTE: strategy for file lookup:
// paths must be relative, ie. textures/me/myfile
// if a 3-letters filename extension (such as .jpg or .tga) is provided, it will get loaded first
// if not found or no extension, will try loading after adding .tga and .jpg (in this order)
typedef qtexture_t * ( WINAPI * PFN_TRYTEXTUREFORNAME ) ( const char * filename ) ;
// query / load a texture
// will not try loading a shader, will look for the actual image file ..
// on file not found will use the "texture not found"
typedef qtexture_t * ( WINAPI * PFN_TEXTUREFORNAME ) ( const char * filename ) ;
// get the number of active shaders
// these are the shaders currently loaded, that have an associated qtexture_t*
typedef int ( WINAPI * PFN_GETACTIVESHADERCOUNT ) ( ) ;
// for stuff that needs to be represented by a plain texture
// the shader will get a "color" name, use GetColor to get the actual color
typedef IShader * ( WINAPI * PFN_COLORSHADERFORNAME ) ( const char * name ) ;
// reload a shaderfile - update shaders and their display properties/qtexture_t if needed
// will not reload the texture files
// will switch to "show in use" atfer use
// filename must be reletive path of the shader, ex. scripts/gothic_wall.shader
typedef void ( WINAPI * PFN_RELOADSHADERFILE ) ( const char * filename ) ;
// retrieve a shader if exists, without loading the textures for it etc.
// use this function if you want special info on a shader
typedef IShader * ( WINAPI * PFN_SHADERFORNAMENOLOAD ) ( const char * name ) ;
// force the "in use" flag on all active shaders
typedef void ( WINAPI * PFN_ACTIVESHADERSSETINUSE ) ( bool b ) ;
// sort the shaders in alphabetical order, we use the order in the texture inspector
typedef void ( WINAPI * PFN_SORTACTIVESHADERS ) ( ) ;
// check if there exists an active shader with the given texture name (loaded or not, doesn't matter)
// (used to detect the textures we need to create a default shader for .. while scanning a directory)
typedef IShader * ( WINAPI * PFN_ACTIVESHADERFORTEXTURENAME ) ( char * ) ;
// create a shader to wrap around a texture name, we use this when loading a texture directory and some textures
// are not present as shaders
typedef IShader * ( WINAPI * PFN_CREATESHADERFORTEXTURENAME ) ( const char * name ) ;
// switch the IsDisplayed flag on all the active shaders
typedef void ( WINAPI * PFN_ACTIVESHADERSSETDISPLAYED ) ( bool b ) ;
// retrieve an active shader based on index
typedef IShader * ( WINAPI * PFN_ACTIVESHADERFORINDEX ) ( int i ) ;
// will cleanup a texture name and force it to the right format
// the debug version is painfully slow, but will detect more problems
// the idea being to avoid loading the same file several time because of uppercase/lowercase etc.
typedef const char * ( WINAPI * PFN_CLEANTEXTURENAME ) ( const char * name , bool bAddTexture ) ;
struct _QERShadersTable
{
int m_nSize ;
PFN_FREESHADERS m_pfnFreeShaders ;
PFN_RELOADSHADERS m_pfnReloadShaders ;
PFN_LOADSHADERSFROMDIR m_pfnLoadShadersFromDir ;
PFN_LOADSHADERFILE m_pfnLoadShaderFile ;
PFN_RELOADSHADERFILE m_pfnReloadShaderFile ;
PFN_HASSHADER m_pfnHasShader ;
PFN_TRYSHADERFORNAME m_pfnTry_Shader_ForName ;
PFN_SHADERFORNAME m_pfnShader_ForName ;
PFN_TRYTEXTUREFORNAME m_pfnTry_Texture_ForName ;
PFN_TEXTUREFORNAME m_pfnTexture_ForName ;
PFN_GETACTIVESHADERCOUNT m_pfnGetActiveShaderCount ;
PFN_COLORSHADERFORNAME m_pfnColorShader_ForName ;
PFN_SHADERFORNAMENOLOAD m_pfnShader_ForName_NoLoad ;
PFN_ACTIVESHADERSSETINUSE m_pfnActiveShaders_SetInUse ;
PFN_SORTACTIVESHADERS m_pfnSortActiveShaders ;
PFN_ACTIVESHADERFORTEXTURENAME m_pfnActiveShader_ForTextureName ;
PFN_CREATESHADERFORTEXTURENAME m_pfnCreateShader_ForTextureName ;
PFN_ACTIVESHADERSSETDISPLAYED m_pfnActiveShaders_SetDisplayed ;
PFN_ACTIVESHADERFORINDEX m_pfnActiveShader_ForIndex ;
PFN_CLEANTEXTURENAME m_pfnCleanTextureName ;
} ;
/*!
\ todo FIXME fix the QERApp_ prototyping on shaders module
make it homogeneous with other modules , should be straight calls
*/
# ifdef USE_SHADERSTABLE_DEFINE
# ifndef __SHADERSTABLENAME
# define __SHADERSTABLENAME g_ShadersTable
# endif
# define QERApp_Shader_ForName __SHADERSTABLENAME.m_pfnShader_ForName
# define QERApp_Texture_ForName2 __SHADERSTABLENAME.m_pfnTexture_ForName
# define QERApp_FreeShaders __SHADERSTABLENAME.m_pfnFreeShaders
# define QERApp_ReloadShaders __SHADERSTABLENAME.m_pfnReloadShaders
# define QERApp_SortActiveShaders __SHADERSTABLENAME.m_pfnSortActiveShaders
# define QERApp_ReloadShaderFile __SHADERSTABLENAME.m_pfnReloadShaderFile
# define QERApp_LoadShaderFile __SHADERSTABLENAME.m_pfnLoadShaderFile
# define QERApp_HasShader __SHADERSTABLENAME.m_pfnHasShader
# define QERApp_Try_Shader_ForName __SHADERSTABLENAME.m_pfnTry_Shader_ForName
# define QERApp_Try_Texture_ForName __SHADERSTABLENAME.m_pfnTry_Texture_ForName
# define QERApp_ColorShader_ForName __SHADERSTABLENAME.m_pfnColorShader_ForName
# define QERApp_Shader_ForName_NoLoad __SHADERSTABLENAME.m_pfnShader_ForName_NoLoad
# define QERApp_LoadShadersFromDir __SHADERSTABLENAME.m_pfnLoadShadersFromDir
# define QERApp_LoadShadersFromDir __SHADERSTABLENAME.m_pfnLoadShadersFromDir
# define QERApp_CreateShader_ForTextureName __SHADERSTABLENAME.m_pfnCreateShader_ForTextureName
# define QERApp_GetActiveShaderCount __SHADERSTABLENAME.m_pfnGetActiveShaderCount
# define QERApp_ActiveShaders_SetDisplayed __SHADERSTABLENAME.m_pfnActiveShaders_SetDisplayed
# define QERApp_ActiveShader_ForIndex __SHADERSTABLENAME.m_pfnActiveShader_ForIndex
# define QERApp_ActiveShaders_SetInUse __SHADERSTABLENAME.m_pfnActiveShaders_SetInUse
# define QERApp_ActiveShader_ForTextureName __SHADERSTABLENAME.m_pfnActiveShader_ForTextureName
# define QERApp_ActiveShader_ForIndex __SHADERSTABLENAME.m_pfnActiveShader_ForIndex
# define QERApp_CleanTextureName __SHADERSTABLENAME.m_pfnCleanTextureName
# endif
# define APPSHADERS_MAJOR "appshaders"
// FIXME: remove
static const GUID QERAppShadersTable_GUID =
{ 0xec3008a8 , 0xbd0b , 0x11d4 , { 0x82 , 0x51 , 0x20 , 0x4c , 0x4f , 0x4f , 0x50 , 0x20 } } ;
// g_qeglobals.d_qtextures is used internally by the editor for actual camera drawing
typedef qtexture_t * * ( WINAPI * PFN_QTEXTURES ) ( ) ;
// g_qeglobals.d_qtexmap is a map for fast access
typedef GHashTable * ( WINAPI * PFN_QTEXMAP ) ( ) ;
// d_texturewin
//++timo NOTE: this same function is also in isurface.h table, we would eventually have to merge some stuff
typedef texturewin_t * ( * PFN_QEGLOBALSTEXTUREWIN ) ( ) ;
// Texture_SetTexture
//++timo NOTE: this one may have to be reorganized too .. putting it here is a bit clumsy
// NOTE: the C++ function used internally has a lot of default values
typedef void ( WINAPI * PFN_TEXTURESETTEXTURE ) ( texdef_t * texdef , brushprimit_texdef_t * brushprimit_texdef ) ;
// Texture_ShowInuse
typedef void ( WINAPI * PFN_TEXTURESHOWINUSE ) ( ) ;
// BuildShaderList
typedef void ( * PFN_BUILDSHADERLIST ) ( ) ;
// PreloadShaders
typedef void ( * PFN_PRELOADSHADERS ) ( ) ;
// a table that Radiant makes available to the shader module in return
struct _QERAppShadersTable
{
int m_nSize ;
PFN_QTEXTURES m_pfnQTextures ;
PFN_QTEXMAP m_pfnQTexmap ;
PFN_QEGLOBALSTEXTUREWIN m_pfnQeglobalsTexturewin ;
PFN_TEXTURESETTEXTURE m_pfnTexture_SetTexture ;
PFN_TEXTURESHOWINUSE m_pfnTexture_ShowInuse ;
PFN_BUILDSHADERLIST m_pfnBuildShaderList ;
PFN_PRELOADSHADERS m_pfnPreloadShaders ;
} ;
# ifdef USE_APPSHADERSTABLE_DEFINE
# ifndef __APPSHADERTABLENAME
# define __APPSHADERTABLENAME g_AppShadersTable
# endif
# define Texture_ShowInuse __APPSHADERTABLENAME.m_pfnTexture_ShowInuse
# endif
/*!
NOTE TTimo : there is an important distinction between SHADER_NOT_FOUND and SHADER_NOTEX :
SHADER_NOT_FOUND means we didn ' t find the raw texture or the shader for this
SHADER_NOTEX means we recognize this as a shader script , but we are missing the texture to represent it
this was in the initial design of the shader code since early GtkRadiant alpha , and got sort of foxed in 1.2 and put back in
*/
# define SHADER_NOT_FOUND "textures / radiant / notex"
# define SHADER_NOTEX "textures / radiant / shadernotex" ///< Q3 tech specific
# endif