X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=include%2Fishaders.h;h=f588c287440e2e1c91355920729e98ca86ae76a9;hb=184fba9ab5ad3111f50c25b70b79d4103943f1f2;hp=e50233ed9264875a11adc277c81588b3fcca8590;hpb=ab3a99dbbe84a0d130fea4d0ceb7b79d7ed07eb7;p=xonotic%2Fnetradiant.git diff --git a/include/ishaders.h b/include/ishaders.h index e50233ed..f588c287 100644 --- a/include/ishaders.h +++ b/include/ishaders.h @@ -1,284 +1,191 @@ /* -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). -*/ + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -class IShader + 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 + */ + +#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 class BasicVector3; +typedef BasicVector3 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: - // 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; +BlendFunc( BlendFactor src, BlendFactor dst ) : m_src( src ), m_dst( dst ){ +} +BlendFactor m_src; +BlendFactor m_dst; }; -// 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 +class ShaderLayer { - 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; +public: +virtual qtexture_t* texture() const = 0; +virtual BlendFunc blendFunc() const = 0; +virtual bool clampToBorder() const = 0; +virtual float alphaTest() const = 0; }; -/*! -\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 +typedef Callback ShaderLayerCallback; -#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 IShader { - 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: +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 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; +virtual bool IsInUse() const = 0; +virtual void SetInUse( bool bInUse ) = 0; +// get the editor flags (QER_NOCARVE QER_TRANS) +virtual int getFlags() const = 0; +// get the transparency value +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() const = 0; +// get the alphaFunc +virtual void getAlphaFunc( EAlphaFunc *func, float *ref ) = 0; +virtual BlendFunc getBlendFunc() const = 0; +// get the cull type +virtual ECull getCull() = 0; +// get shader file name (ie the file where this one is defined) +virtual const char* getShaderFileName() const = 0; + +virtual const ShaderLayer* firstLayer() const = 0; +virtual void forEachLayer( const ShaderLayerCallback& layer ) const = 0; + +virtual qtexture_t* lightFalloffImage() const = 0; }; -#ifdef USE_APPSHADERSTABLE_DEFINE - #ifndef __APPSHADERTABLENAME - #define __APPSHADERTABLENAME g_AppShadersTable - #endif -#define Texture_ShowInuse __APPSHADERTABLENAME.m_pfnTexture_ShowInuse -#endif +typedef struct _GSList GSList; +typedef Callback ShaderNameCallback; + +class ModuleObserver; + +class ShaderSystem +{ +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& 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; +}; + +#include "modulesystem.h" + +template +class GlobalModule; +typedef GlobalModule GlobalShadersModule; + +template +class GlobalModuleRef; +typedef GlobalModuleRef GlobalShadersModuleRef; + +inline ShaderSystem& GlobalShaderSystem(){ + return GlobalShadersModule::getTable(); +} -/*! -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 +#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