]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - include/ishaders.h
macos: ignore warnings about OpenGL being deprecated
[xonotic/netradiant.git] / include / ishaders.h
index 5ade595666e77c935b24a9b8ee25134adc9613e7..e1ce6261fbcf92da9c55d9e26bbf5e96bb6ff5f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   Copyright (C) 1999-2006 Id Software, Inc. and contributors.
    For a list of contributors, see the accompanying CONTRIBUTORS file.
 
    This file is part of GtkRadiant.
    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).
- */
+#if !defined( INCLUDED_ISHADERS_H )
+#define INCLUDED_ISHADERS_H
+
+#include "generic/constant.h"
+#include "generic/callback.h"
+
+enum
+{
+       QER_TRANS = 1 << 0,
+       QER_NOCARVE = 1 << 1,
+       QER_NODRAW = 1 << 2,
+       QER_NONSOLID = 1 << 3,
+       QER_WATER = 1 << 4,
+       QER_LAVA = 1 << 5,
+       QER_FOG = 1 << 6,
+       QER_ALPHATEST = 1 << 7,
+       QER_CULL = 1 << 8,
+       QER_AREAPORTAL = 1 << 9,
+       QER_CLIP = 1 << 10,
+       QER_BOTCLIP = 1 << 11,
+};
+
+struct qtexture_t;
+
+template<typename Element> class BasicVector3;
+typedef BasicVector3<float> Vector3;
+typedef Vector3 Colour3;
+
+typedef unsigned char BlendFactor;
+const BlendFactor BLEND_ZERO = 0;
+const BlendFactor BLEND_ONE = 1;
+const BlendFactor BLEND_SRC_COLOUR = 2;
+const BlendFactor BLEND_ONE_MINUS_SRC_COLOUR = 3;
+const BlendFactor BLEND_SRC_ALPHA = 4;
+const BlendFactor BLEND_ONE_MINUS_SRC_ALPHA = 5;
+const BlendFactor BLEND_DST_COLOUR = 6;
+const BlendFactor BLEND_ONE_MINUS_DST_COLOUR = 7;
+const BlendFactor BLEND_DST_ALPHA = 8;
+const BlendFactor BLEND_ONE_MINUS_DST_ALPHA = 9;
+const BlendFactor BLEND_SRC_ALPHA_SATURATE = 10;
+
+class BlendFunc
+{
+public:
+BlendFunc( BlendFactor src, BlendFactor dst ) : m_src( src ), m_dst( dst ){
+}
+BlendFactor m_src;
+BlendFactor m_dst;
+};
+
+class ShaderLayer
+{
+public:
+virtual qtexture_t* texture() const = 0;
+virtual BlendFunc blendFunc() const = 0;
+virtual bool clampToBorder() const = 0;
+virtual float alphaTest() const = 0;
+};
+
+typedef Callback<void(const ShaderLayer&)> ShaderLayerCallback;
 
 class IShader
 {
 public:
-virtual ~IShader() { }
+enum EAlphaFunc
+{
+       eAlways,
+       eEqual,
+       eLess,
+       eGreater,
+       eLEqual,
+       eGEqual,
+};
+enum ECull
+{
+       eCullNone,
+       eCullBack,
+};
 // 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;
+virtual qtexture_t* getDiffuse() const = 0;
+virtual qtexture_t* getBump() const = 0;
+virtual qtexture_t* getSpecular() const = 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 const char* getWadName() const = 0;
+virtual void setWadName( const char* name ) = 0;
 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;
+virtual void SetInUse( bool bInUse ) = 0;
 // get the editor flags (QER_NOCARVE QER_TRANS)
-virtual int getFlags() = 0;
+virtual int getFlags() const = 0;
 // get the transparency value
-virtual float getTrans() = 0;
+virtual float getTrans() const = 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;
+virtual bool IsDefault() const = 0;
 // get the alphaFunc
-virtual void getAlphaFunc( int *func, float *ref ) = 0;
+virtual void getAlphaFunc( EAlphaFunc *func, float *ref ) = 0;
+virtual BlendFunc getBlendFunc() const = 0;
 // get the cull type
-virtual int getCull() = 0;
+virtual ECull 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;
+virtual const ShaderLayer* firstLayer() const = 0;
+virtual void forEachLayer( const ShaderLayerCallback& layer ) const = 0;
+
+virtual qtexture_t* lightFalloffImage() const = 0;
 };
 
-/*!
-   \todo FIXME fix the QERApp_ prototyping on shaders module
-   make it homogeneous with other modules, should be straight calls
- */
+typedef struct _GSList GSList;
+typedef Callback<void(const char*)> ShaderNameCallback;
 
-#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
+class ModuleObserver;
 
-#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
+class ShaderSystem
 {
-       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;
+public:
+INTEGER_CONSTANT( Version, 1 );
+STRING_CONSTANT( Name, "shaders" );
+// NOTE: shader and texture names used must be full path.
+// Shaders usable as textures have prefix equal to getTexturePrefix()
+
+virtual void realise() = 0;
+virtual void unrealise() = 0;
+virtual void refresh() = 0;
+// activate the shader for a given name and return it
+// will return the default shader if name is not found
+virtual IShader* getShaderForName( const char* name ) = 0;
+
+virtual void foreachShaderName( const ShaderNameCallback& callback ) = 0;
+
+// iterate over the list of active shaders
+virtual void beginActiveShadersIterator() = 0;
+virtual bool endActiveShadersIterator() = 0;
+virtual IShader* dereferenceActiveShadersIterator() = 0;
+virtual void incrementActiveShadersIterator() = 0;
+
+virtual void setActiveShadersChangedNotify( const Callback<void()>& notify ) = 0;
+
+virtual void attach( ModuleObserver& observer ) = 0;
+virtual void detach( ModuleObserver& observer ) = 0;
+
+virtual void setLightingEnabled( bool enabled ) = 0;
+
+virtual const char* getTexturePrefix() const = 0;
 };
 
-#ifdef USE_APPSHADERSTABLE_DEFINE
-  #ifndef __APPSHADERTABLENAME
-       #define __APPSHADERTABLENAME g_AppShadersTable
-  #endif
-#define Texture_ShowInuse __APPSHADERTABLENAME.m_pfnTexture_ShowInuse
-#endif
+#include "modulesystem.h"
 
-/*!
-   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
+template<typename Type>
+class GlobalModule;
+typedef GlobalModule<ShaderSystem> GlobalShadersModule;
+
+template<typename Type>
+class GlobalModuleRef;
+typedef GlobalModuleRef<ShaderSystem> GlobalShadersModuleRef;
+
+inline ShaderSystem& GlobalShaderSystem(){
+       return GlobalShadersModule::getTable();
+}
+
+#define QERApp_Shader_ForName GlobalShaderSystem().getShaderForName
+#define QERApp_ActiveShaders_IteratorBegin GlobalShaderSystem().beginActiveShadersIterator
+#define QERApp_ActiveShaders_IteratorAtEnd GlobalShaderSystem().endActiveShadersIterator
+#define QERApp_ActiveShaders_IteratorCurrent GlobalShaderSystem().dereferenceActiveShadersIterator
+#define QERApp_ActiveShaders_IteratorIncrement GlobalShaderSystem().incrementActiveShadersIterator
 
 #endif