2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 //-----------------------------------------------------------------------------
26 // a set of functions to manipulate textures in Radiant
32 #define SHADERS_MAJOR "shaders"
33 // define a GUID for this interface so plugins can access and reference it
34 // {D42F798A-DF57-11d3-A3EE-0004AC96D4C3}
35 static const GUID QERShadersTable_GUID =
36 { 0xd42f798a, 0xdf57, 0x11d3, { 0xa3, 0xee, 0x0, 0x4, 0xac, 0x96, 0xd4, 0xc3 } };
38 // NOTES ABOUT SYNTAX:
39 // if a function starts by 'Try' it means that if the requested thing could not be found / loaded it will return nothing / NULL
40 // otherwise a default object will be created
41 // the _QERShadersTable is also used by shader code inside Radiant. but for speed and "keep it simple" consideration you
42 // can get the static equivalent of the func pointers by adding 'QERApp_' (access to _QERShadersTable is better thought ..
43 // see the note to move all the shader language out of Radiant below)
47 fix the reference count strategy
48 - define the policy. It seems the initial policy of doing an inc ref when you create the shader is not good
49 (it doesn't work, and it's not being used right)
50 so, when you request an IShader and store it, incref it yourself
51 as a debugging safe check: push the created increfed objects into a list, and scan them at next idle loop
52 to make sure they have been decref'ed ? (sounds easy, may not be that much).
58 // Increment the number of references to this object
59 virtual void IncRef () = 0;
60 // Decrement the reference count
61 virtual void DecRef () = 0;
62 // get/set the qtexture_t* Radiant uses to represent this shader object
63 virtual qtexture_t* getTexture() const = 0;
64 virtual void setTexture(qtexture_t *pTex) = 0;
66 virtual const char* getName() const = 0;
67 // is this shader in use?
68 // NOTE: this flag can mean this shader has been in use at least once since the last rescan of in-use stuff
69 // (rescan of in-use happens in several cases, user command or during a texture directory load)
70 // NOTE: this is used to draw the green outline in the texture window
71 // 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)
72 virtual bool IsInUse() const = 0;
73 virtual void SetInUse(bool) = 0;
74 // is this shader displayed in the texture browser?
75 // NOTE: if IsInUse() == true, the shader will always be displayed in the texture window and this flag ingored
76 virtual bool IsDisplayed() const = 0;
77 virtual void SetDisplayed(bool) = 0;
78 // get the editor flags (QER_NOCARVE QER_TRANS)
79 virtual int getFlags() = 0;
80 // get the transparency value
81 virtual float getTrans() = 0;
82 // test if it's a true shader, or a default shader created to wrap around a texture
83 virtual bool IsDefault() = 0;
84 // test if it's a plain color shader, i.e. a shader we use on plain color stuff (like info_playerstart)
85 virtual bool IsColor() = 0;
86 // get the related color then!
87 virtual void getColor(vec3_t v) = 0;
89 virtual void getAlphaFunc(int *func, float *ref) = 0;
91 virtual int getCull() = 0;
92 // get shader file name (ie the file where this one is defined)
93 virtual const char* getShaderFileName() const = 0;
96 // NOTE: how to move all the shader language out of Radiant in a plugin?
97 // -> change this _QERShadersTable into an IShadersManager
98 // -> let the plugin create an instance of IShadersManager
99 // -> make sure Radiant uses this IShadersManager to load / query the shaders
101 // NOTE: shader and texture names used must be full path, ie. most often with "textures/" prefix
102 // (since shaders are defined in .shader files with textures/)
105 // free the shaders, will not free the qtexture_t*
106 typedef void (WINAPI* PFN_FREESHADERS) ();
107 // reload all the shaders
108 // this will free everything (shaders and their textures), then reload all in use stuff
109 typedef void (WINAPI* PFN_RELOADSHADERS) ();
110 // load all shaders in a given directory
111 // this will scan the list of in-memory shaders, and load the related qtexture_t if needed
112 typedef int (WINAPI* PFN_LOADSHADERSFROMDIR)(const char* path);
113 // load a shader file (ie a set of shaders)
114 // after LoadShaderFile shaders will be in memory, next step is to load the qtexture_t Radiant uses to represent them
115 // if a shader with the same name exists, new one will not be loaded - don't use this to refresh the shaders!
116 typedef void (WINAPI* PFN_LOADSHADERFILE) (const char* filename);
117 // tell if a given shader exists in our shader table
118 // NOTE: this doesn't tell wether it's corresponding qtexture is loaded
119 typedef int (WINAPI* PFN_HASSHADER) (const char* name);
120 // return the shader for a given name
121 // if the qtexture is not already in memory, will try loading it
122 // if the qtexture could not be found, will use default
123 // will return NULL on shader not found
124 typedef IShader* (WINAPI* PFN_TRYSHADERFORNAME) (const char* name);
125 // return the shader for a given name
126 // if the qtexture is not already in memory, will try loading it
127 // will create a default shader if not found (will use a default texture)
128 typedef IShader* (WINAPI* PFN_SHADERFORNAME) (const char* name);
129 // query / load a texture
130 // will not try loading a shader, will look for the actual image file ..
131 // returns NULL on file not found
132 // NOTE: strategy for file lookup:
133 // paths must be relative, ie. textures/me/myfile
134 // if a 3-letters filename extension (such as .jpg or .tga) is provided, it will get loaded first
135 // if not found or no extension, will try loading after adding .tga and .jpg (in this order)
136 typedef qtexture_t* (WINAPI* PFN_TRYTEXTUREFORNAME) (const char* filename);
137 // query / load a texture
138 // will not try loading a shader, will look for the actual image file ..
139 // on file not found will use the "texture not found"
140 typedef qtexture_t* (WINAPI* PFN_TEXTUREFORNAME) (const char* filename);
141 // get the number of active shaders
142 // these are the shaders currently loaded, that have an associated qtexture_t*
143 typedef int (WINAPI* PFN_GETACTIVESHADERCOUNT) ();
144 // for stuff that needs to be represented by a plain texture
145 // the shader will get a "color" name, use GetColor to get the actual color
146 typedef IShader* (WINAPI* PFN_COLORSHADERFORNAME) (const char* name);
147 // reload a shaderfile - update shaders and their display properties/qtexture_t if needed
148 // will not reload the texture files
149 // will switch to "show in use" atfer use
150 // filename must be reletive path of the shader, ex. scripts/gothic_wall.shader
151 typedef void (WINAPI* PFN_RELOADSHADERFILE)(const char* filename);
152 // retrieve a shader if exists, without loading the textures for it etc.
153 // use this function if you want special info on a shader
154 typedef IShader* (WINAPI* PFN_SHADERFORNAMENOLOAD) (const char* name);
155 // force the "in use" flag on all active shaders
156 typedef void (WINAPI* PFN_ACTIVESHADERSSETINUSE) (bool b);
157 // sort the shaders in alphabetical order, we use the order in the texture inspector
158 typedef void (WINAPI* PFN_SORTACTIVESHADERS) ();
159 // check if there exists an active shader with the given texture name (loaded or not, doesn't matter)
160 // (used to detect the textures we need to create a default shader for .. while scanning a directory)
161 typedef IShader* (WINAPI* PFN_ACTIVESHADERFORTEXTURENAME) (char *);
162 // create a shader to wrap around a texture name, we use this when loading a texture directory and some textures
163 // are not present as shaders
164 typedef IShader* (WINAPI* PFN_CREATESHADERFORTEXTURENAME) (const char* name);
165 // switch the IsDisplayed flag on all the active shaders
166 typedef void (WINAPI* PFN_ACTIVESHADERSSETDISPLAYED) (bool b);
167 // retrieve an active shader based on index
168 typedef IShader* (WINAPI* PFN_ACTIVESHADERFORINDEX) (int i);
169 // will cleanup a texture name and force it to the right format
170 // the debug version is painfully slow, but will detect more problems
171 // the idea being to avoid loading the same file several time because of uppercase/lowercase etc.
172 typedef const char* (WINAPI* PFN_CLEANTEXTURENAME) (const char* name, bool bAddTexture);
174 struct _QERShadersTable
177 PFN_FREESHADERS m_pfnFreeShaders;
178 PFN_RELOADSHADERS m_pfnReloadShaders;
179 PFN_LOADSHADERSFROMDIR m_pfnLoadShadersFromDir;
180 PFN_LOADSHADERFILE m_pfnLoadShaderFile;
181 PFN_RELOADSHADERFILE m_pfnReloadShaderFile;
182 PFN_HASSHADER m_pfnHasShader;
183 PFN_TRYSHADERFORNAME m_pfnTry_Shader_ForName;
184 PFN_SHADERFORNAME m_pfnShader_ForName;
185 PFN_TRYTEXTUREFORNAME m_pfnTry_Texture_ForName;
186 PFN_TEXTUREFORNAME m_pfnTexture_ForName;
187 PFN_GETACTIVESHADERCOUNT m_pfnGetActiveShaderCount;
188 PFN_COLORSHADERFORNAME m_pfnColorShader_ForName;
189 PFN_SHADERFORNAMENOLOAD m_pfnShader_ForName_NoLoad;
190 PFN_ACTIVESHADERSSETINUSE m_pfnActiveShaders_SetInUse;
191 PFN_SORTACTIVESHADERS m_pfnSortActiveShaders;
192 PFN_ACTIVESHADERFORTEXTURENAME m_pfnActiveShader_ForTextureName;
193 PFN_CREATESHADERFORTEXTURENAME m_pfnCreateShader_ForTextureName;
194 PFN_ACTIVESHADERSSETDISPLAYED m_pfnActiveShaders_SetDisplayed;
195 PFN_ACTIVESHADERFORINDEX m_pfnActiveShader_ForIndex;
196 PFN_CLEANTEXTURENAME m_pfnCleanTextureName;
200 \todo FIXME fix the QERApp_ prototyping on shaders module
201 make it homogeneous with other modules, should be straight calls
204 #ifdef USE_SHADERSTABLE_DEFINE
205 #ifndef __SHADERSTABLENAME
206 #define __SHADERSTABLENAME g_ShadersTable
208 #define QERApp_Shader_ForName __SHADERSTABLENAME.m_pfnShader_ForName
209 #define QERApp_Texture_ForName2 __SHADERSTABLENAME.m_pfnTexture_ForName
210 #define QERApp_FreeShaders __SHADERSTABLENAME.m_pfnFreeShaders
211 #define QERApp_ReloadShaders __SHADERSTABLENAME.m_pfnReloadShaders
212 #define QERApp_SortActiveShaders __SHADERSTABLENAME.m_pfnSortActiveShaders
213 #define QERApp_ReloadShaderFile __SHADERSTABLENAME.m_pfnReloadShaderFile
214 #define QERApp_LoadShaderFile __SHADERSTABLENAME.m_pfnLoadShaderFile
215 #define QERApp_HasShader __SHADERSTABLENAME.m_pfnHasShader
216 #define QERApp_Try_Shader_ForName __SHADERSTABLENAME.m_pfnTry_Shader_ForName
217 #define QERApp_Try_Texture_ForName __SHADERSTABLENAME.m_pfnTry_Texture_ForName
218 #define QERApp_ColorShader_ForName __SHADERSTABLENAME.m_pfnColorShader_ForName
219 #define QERApp_Shader_ForName_NoLoad __SHADERSTABLENAME.m_pfnShader_ForName_NoLoad
220 #define QERApp_LoadShadersFromDir __SHADERSTABLENAME.m_pfnLoadShadersFromDir
221 #define QERApp_LoadShadersFromDir __SHADERSTABLENAME.m_pfnLoadShadersFromDir
222 #define QERApp_CreateShader_ForTextureName __SHADERSTABLENAME.m_pfnCreateShader_ForTextureName
223 #define QERApp_GetActiveShaderCount __SHADERSTABLENAME.m_pfnGetActiveShaderCount
224 #define QERApp_ActiveShaders_SetDisplayed __SHADERSTABLENAME.m_pfnActiveShaders_SetDisplayed
225 #define QERApp_ActiveShader_ForIndex __SHADERSTABLENAME.m_pfnActiveShader_ForIndex
226 #define QERApp_ActiveShaders_SetInUse __SHADERSTABLENAME.m_pfnActiveShaders_SetInUse
227 #define QERApp_ActiveShader_ForTextureName __SHADERSTABLENAME.m_pfnActiveShader_ForTextureName
228 #define QERApp_ActiveShader_ForIndex __SHADERSTABLENAME.m_pfnActiveShader_ForIndex
229 #define QERApp_CleanTextureName __SHADERSTABLENAME.m_pfnCleanTextureName
232 #define APPSHADERS_MAJOR "appshaders"
234 static const GUID QERAppShadersTable_GUID =
235 { 0xec3008a8, 0xbd0b, 0x11d4, { 0x82, 0x51, 0x20, 0x4c, 0x4f, 0x4f, 0x50, 0x20 } };
237 // g_qeglobals.d_qtextures is used internally by the editor for actual camera drawing
238 typedef qtexture_t** (WINAPI* PFN_QTEXTURES)();
239 // g_qeglobals.d_qtexmap is a map for fast access
240 typedef GHashTable* (WINAPI* PFN_QTEXMAP)();
242 //++timo NOTE: this same function is also in isurface.h table, we would eventually have to merge some stuff
243 typedef texturewin_t* (* PFN_QEGLOBALSTEXTUREWIN)();
244 // Texture_SetTexture
245 //++timo NOTE: this one may have to be reorganized too .. putting it here is a bit clumsy
246 // NOTE: the C++ function used internally has a lot of default values
247 typedef void (WINAPI* PFN_TEXTURESETTEXTURE)(texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef);
249 typedef void (WINAPI* PFN_TEXTURESHOWINUSE)();
251 typedef void (* PFN_BUILDSHADERLIST)();
253 typedef void (* PFN_PRELOADSHADERS)();
255 // a table that Radiant makes available to the shader module in return
256 struct _QERAppShadersTable
259 PFN_QTEXTURES m_pfnQTextures;
260 PFN_QTEXMAP m_pfnQTexmap;
261 PFN_QEGLOBALSTEXTUREWIN m_pfnQeglobalsTexturewin;
262 PFN_TEXTURESETTEXTURE m_pfnTexture_SetTexture;
263 PFN_TEXTURESHOWINUSE m_pfnTexture_ShowInuse;
264 PFN_BUILDSHADERLIST m_pfnBuildShaderList;
265 PFN_PRELOADSHADERS m_pfnPreloadShaders;
268 #ifdef USE_APPSHADERSTABLE_DEFINE
269 #ifndef __APPSHADERTABLENAME
270 #define __APPSHADERTABLENAME g_AppShadersTable
272 #define Texture_ShowInuse __APPSHADERTABLENAME.m_pfnTexture_ShowInuse
276 NOTE TTimo: there is an important distinction between SHADER_NOT_FOUND and SHADER_NOTEX:
277 SHADER_NOT_FOUND means we didn't find the raw texture or the shader for this
278 SHADER_NOTEX means we recognize this as a shader script, but we are missing the texture to represent it
279 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
281 #define SHADER_NOT_FOUND "textures/radiant/notex"
282 #define SHADER_NOTEX "textures/radiant/shadernotex" ///< Q3 tech specific