d45a0eef68132901ad828bcde10718d667434964
[divverent/darkplaces.git] / gl_rmain.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // r_main.c
21
22 #include "quakedef.h"
23 #include "cl_dyntexture.h"
24 #include "r_shadow.h"
25 #include "polygon.h"
26 #include "image.h"
27
28 mempool_t *r_main_mempool;
29 rtexturepool_t *r_main_texturepool;
30
31 static int r_frame = 0; ///< used only by R_GetCurrentTexture
32
33 qboolean r_loadnormalmap;
34 qboolean r_loadgloss;
35 qboolean r_loadfog;
36
37 //
38 // screen size info
39 //
40 r_refdef_t r_refdef;
41
42 cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "motionblur value scale - 0.5 recommended"};
43 cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "motionblur based on damage"};
44 cvar_t r_motionblur_vmin = {CVAR_SAVE, "r_motionblur_vmin", "300", "minimum influence from velocity"};
45 cvar_t r_motionblur_vmax = {CVAR_SAVE, "r_motionblur_vmax", "600", "maximum influence from velocity"};
46 cvar_t r_motionblur_bmin = {CVAR_SAVE, "r_motionblur_bmin", "0.5", "velocity at which there is no blur yet (may be negative to always have some blur)"};
47 cvar_t r_motionblur_vcoeff = {CVAR_SAVE, "r_motionblur_vcoeff", "0.05", "sliding average reaction time for velocity"};
48 cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.88", "cap for motionblur alpha value"};
49 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
50
51 // TODO do we want a r_equalize_entities cvar that works on all ents, or would that be a cheat?
52 cvar_t r_equalize_entities_fullbright = {CVAR_SAVE, "r_equalize_entities_fullbright", "0", "render fullbright entities by equalizing their lightness, not by not rendering light"};
53 cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio"};
54 cvar_t r_equalize_entities_by = {CVAR_SAVE, "r_equalize_entities_by", "0.7", "light equalizing: exponent of dynamics compression (0 = no compression, 1 = full compression)"};
55 cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level"};
56
57 cvar_t r_depthfirst = {CVAR_SAVE, "r_depthfirst", "0", "renders a depth-only version of the scene before normal rendering begins to eliminate overdraw, values: 0 = off, 1 = world depth, 2 = world and model depth"};
58 cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
59 cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
60 cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
61 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
62 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%,  10 = 100%)"};
63 cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"};
64 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
65 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
66 cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
67 cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
68 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
69 cvar_t r_showcollisionbrushes_polygonfactor = {0, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"};
70 cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"};
71 cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
72 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
73 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
74 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
75 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
76 cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling (in addition to center sample)"};
77 cvar_t r_cullentities_trace_tempentitysamples = {0, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"};
78 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
79 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
80 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
81 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
82 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
83 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
84 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
85 cvar_t r_shadows = {CVAR_SAVE, "r_shadows", "0", "casts fake stencil shadows from models onto the world (rtlights are unaffected by this); when set to 2, always cast the shadows in the direction set by r_shadows_throwdirection, otherwise use the model lighting."};
86 cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
87 cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
88 cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
89 cvar_t r_shadows_drawafterrtlighting = {CVAR_SAVE, "r_shadows_drawafterrtlighting", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."};
90 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
91 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
92 cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
93 cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "14", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
94 cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
95 cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
96 cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
97 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
98 cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
99
100 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
101 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
102 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
103 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
104 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
105 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
106 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
107 cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
108
109 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"};
110 static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
111 static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
112
113 cvar_t r_glsl_deluxemapping = {CVAR_SAVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
114 cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
115 cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
116 cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
117 cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
118 cvar_t r_glsl_postprocess_uservec1 = {CVAR_SAVE, "r_glsl_postprocess_uservec1", "0 0 0 0", "a 4-component vector to pass as uservec1 to the postprocessing shader (only useful if default.glsl has been customized)"};
119 cvar_t r_glsl_postprocess_uservec2 = {CVAR_SAVE, "r_glsl_postprocess_uservec2", "0 0 0 0", "a 4-component vector to pass as uservec2 to the postprocessing shader (only useful if default.glsl has been customized)"};
120 cvar_t r_glsl_postprocess_uservec3 = {CVAR_SAVE, "r_glsl_postprocess_uservec3", "0 0 0 0", "a 4-component vector to pass as uservec3 to the postprocessing shader (only useful if default.glsl has been customized)"};
121 cvar_t r_glsl_postprocess_uservec4 = {CVAR_SAVE, "r_glsl_postprocess_uservec4", "0 0 0 0", "a 4-component vector to pass as uservec4 to the postprocessing shader (only useful if default.glsl has been customized)"};
122
123 cvar_t r_water = {CVAR_SAVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
124 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
125 cvar_t r_water_resolutionmultiplier = {CVAR_SAVE, "r_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"};
126 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
127 cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
128
129 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites"};
130 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
131 cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
132 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
133
134 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
135 cvar_t r_bloom_colorscale = {CVAR_SAVE, "r_bloom_colorscale", "1", "how bright the glow is"};
136 cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
137 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
138 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
139 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exagerated the glow is"};
140 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
141
142 cvar_t r_hdr = {CVAR_SAVE, "r_hdr", "0", "enables High Dynamic Range bloom effect (higher quality version of r_bloom)"};
143 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
144 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
145 cvar_t r_hdr_range = {CVAR_SAVE, "r_hdr_range", "4", "how much dynamic range to render bloom with (equivilant to multiplying r_bloom_brighten by this value and dividing r_bloom_colorscale by this value)"};
146
147 cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1", "uses significantly faster (and supposedly higher quality) area-weighted vertex normals and tangent vectors rather than summing normalized triangle normals and tangents"};
148
149 cvar_t developer_texturelogging = {0, "developer_texturelogging", "0", "produces a textures.log file containing names of skins and map textures the engine tried to load"};
150
151 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
152
153 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
154 cvar_t r_batchmode = {0, "r_batchmode", "1", "selects method of rendering multiple surfaces with one driver call (values are 0, 1, 2, etc...)"};
155 cvar_t r_track_sprites = {CVAR_SAVE, "r_track_sprites", "1", "track SPR_LABEL* sprites by putting them as indicator at the screen border to rotate to"};
156 cvar_t r_track_sprites_flags = {CVAR_SAVE, "r_track_sprites_flags", "1", "1: Rotate sprites accodringly, 2: Make it a continuous rotation"};
157 cvar_t r_track_sprites_scalew = {CVAR_SAVE, "r_track_sprites_scalew", "1", "width scaling of tracked sprites"};
158 cvar_t r_track_sprites_scaleh = {CVAR_SAVE, "r_track_sprites_scaleh", "1", "height scaling of tracked sprites"};
159 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
160
161 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "1", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
162
163 extern cvar_t v_glslgamma;
164
165 extern qboolean v_flipped_state;
166
167 static struct r_bloomstate_s
168 {
169         qboolean enabled;
170         qboolean hdr;
171
172         int bloomwidth, bloomheight;
173
174         int screentexturewidth, screentextureheight;
175         rtexture_t *texture_screen; /// \note also used for motion blur if enabled!
176
177         int bloomtexturewidth, bloomtextureheight;
178         rtexture_t *texture_bloom;
179
180         // arrays for rendering the screen passes
181         float screentexcoord2f[8];
182         float bloomtexcoord2f[8];
183         float offsettexcoord2f[8];
184
185         r_viewport_t viewport;
186 }
187 r_bloomstate;
188
189 r_waterstate_t r_waterstate;
190
191 /// shadow volume bsp struct with automatically growing nodes buffer
192 svbsp_t r_svbsp;
193
194 rtexture_t *r_texture_blanknormalmap;
195 rtexture_t *r_texture_white;
196 rtexture_t *r_texture_grey128;
197 rtexture_t *r_texture_black;
198 rtexture_t *r_texture_notexture;
199 rtexture_t *r_texture_whitecube;
200 rtexture_t *r_texture_normalizationcube;
201 rtexture_t *r_texture_fogattenuation;
202 rtexture_t *r_texture_gammaramps;
203 unsigned int r_texture_gammaramps_serial;
204 //rtexture_t *r_texture_fogintensity;
205
206 unsigned int r_queries[MAX_OCCLUSION_QUERIES];
207 unsigned int r_numqueries;
208 unsigned int r_maxqueries;
209
210 typedef struct r_qwskincache_s
211 {
212         char name[MAX_QPATH];
213         skinframe_t *skinframe;
214 }
215 r_qwskincache_t;
216
217 static r_qwskincache_t *r_qwskincache;
218 static int r_qwskincache_size;
219
220 /// vertex coordinates for a quad that covers the screen exactly
221 const float r_screenvertex3f[12] =
222 {
223         0, 0, 0,
224         1, 0, 0,
225         1, 1, 0,
226         0, 1, 0
227 };
228
229 extern void R_DrawModelShadows(void);
230
231 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
232 {
233         int i;
234         for (i = 0;i < verts;i++)
235         {
236                 out[0] = in[0] * r;
237                 out[1] = in[1] * g;
238                 out[2] = in[2] * b;
239                 out[3] = in[3];
240                 in += 4;
241                 out += 4;
242         }
243 }
244
245 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
246 {
247         int i;
248         for (i = 0;i < verts;i++)
249         {
250                 out[0] = r;
251                 out[1] = g;
252                 out[2] = b;
253                 out[3] = a;
254                 out += 4;
255         }
256 }
257
258 // FIXME: move this to client?
259 void FOG_clear(void)
260 {
261         if (gamemode == GAME_NEHAHRA)
262         {
263                 Cvar_Set("gl_fogenable", "0");
264                 Cvar_Set("gl_fogdensity", "0.2");
265                 Cvar_Set("gl_fogred", "0.3");
266                 Cvar_Set("gl_foggreen", "0.3");
267                 Cvar_Set("gl_fogblue", "0.3");
268         }
269         r_refdef.fog_density = 0;
270         r_refdef.fog_red = 0;
271         r_refdef.fog_green = 0;
272         r_refdef.fog_blue = 0;
273         r_refdef.fog_alpha = 1;
274         r_refdef.fog_start = 0;
275         r_refdef.fog_end = 16384;
276         r_refdef.fog_height = 1<<30;
277         r_refdef.fog_fadedepth = 128;
278 }
279
280 static void R_BuildBlankTextures(void)
281 {
282         unsigned char data[4];
283         data[2] = 128; // normal X
284         data[1] = 128; // normal Y
285         data[0] = 255; // normal Z
286         data[3] = 128; // height
287         r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
288         data[0] = 255;
289         data[1] = 255;
290         data[2] = 255;
291         data[3] = 255;
292         r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
293         data[0] = 128;
294         data[1] = 128;
295         data[2] = 128;
296         data[3] = 255;
297         r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
298         data[0] = 0;
299         data[1] = 0;
300         data[2] = 0;
301         data[3] = 255;
302         r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
303 }
304
305 static void R_BuildNoTexture(void)
306 {
307         int x, y;
308         unsigned char pix[16][16][4];
309         // this makes a light grey/dark grey checkerboard texture
310         for (y = 0;y < 16;y++)
311         {
312                 for (x = 0;x < 16;x++)
313                 {
314                         if ((y < 8) ^ (x < 8))
315                         {
316                                 pix[y][x][0] = 128;
317                                 pix[y][x][1] = 128;
318                                 pix[y][x][2] = 128;
319                                 pix[y][x][3] = 255;
320                         }
321                         else
322                         {
323                                 pix[y][x][0] = 64;
324                                 pix[y][x][1] = 64;
325                                 pix[y][x][2] = 64;
326                                 pix[y][x][3] = 255;
327                         }
328                 }
329         }
330         r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, NULL);
331 }
332
333 static void R_BuildWhiteCube(void)
334 {
335         unsigned char data[6*1*1*4];
336         memset(data, 255, sizeof(data));
337         r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, NULL);
338 }
339
340 static void R_BuildNormalizationCube(void)
341 {
342         int x, y, side;
343         vec3_t v;
344         vec_t s, t, intensity;
345 #define NORMSIZE 64
346         unsigned char *data;
347         data = Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
348         for (side = 0;side < 6;side++)
349         {
350                 for (y = 0;y < NORMSIZE;y++)
351                 {
352                         for (x = 0;x < NORMSIZE;x++)
353                         {
354                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
355                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
356                                 switch(side)
357                                 {
358                                 default:
359                                 case 0:
360                                         v[0] = 1;
361                                         v[1] = -t;
362                                         v[2] = -s;
363                                         break;
364                                 case 1:
365                                         v[0] = -1;
366                                         v[1] = -t;
367                                         v[2] = s;
368                                         break;
369                                 case 2:
370                                         v[0] = s;
371                                         v[1] = 1;
372                                         v[2] = t;
373                                         break;
374                                 case 3:
375                                         v[0] = s;
376                                         v[1] = -1;
377                                         v[2] = -t;
378                                         break;
379                                 case 4:
380                                         v[0] = s;
381                                         v[1] = -t;
382                                         v[2] = 1;
383                                         break;
384                                 case 5:
385                                         v[0] = -s;
386                                         v[1] = -t;
387                                         v[2] = -1;
388                                         break;
389                                 }
390                                 intensity = 127.0f / sqrt(DotProduct(v, v));
391                                 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
392                                 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
393                                 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
394                                 data[((side*64+y)*64+x)*4+3] = 255;
395                         }
396                 }
397         }
398         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, NULL);
399         Mem_Free(data);
400 }
401
402 static void R_BuildFogTexture(void)
403 {
404         int x, b;
405 #define FOGWIDTH 256
406         unsigned char data1[FOGWIDTH][4];
407         //unsigned char data2[FOGWIDTH][4];
408         double d, r, alpha;
409
410         r_refdef.fogmasktable_start = r_refdef.fog_start;
411         r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
412         r_refdef.fogmasktable_range = r_refdef.fogrange;
413         r_refdef.fogmasktable_density = r_refdef.fog_density;
414
415         r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
416         for (x = 0;x < FOGMASKTABLEWIDTH;x++)
417         {
418                 d = (x * r - r_refdef.fogmasktable_start);
419                 if(developer.integer >= 100)
420                         Con_Printf("%f ", d);
421                 d = max(0, d);
422                 if (r_fog_exp2.integer)
423                         alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
424                 else
425                         alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
426                 if(developer.integer >= 100)
427                         Con_Printf(" : %f ", alpha);
428                 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
429                 if(developer.integer >= 100)
430                         Con_Printf(" = %f\n", alpha);
431                 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
432         }
433
434         for (x = 0;x < FOGWIDTH;x++)
435         {
436                 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
437                 data1[x][0] = b;
438                 data1[x][1] = b;
439                 data1[x][2] = b;
440                 data1[x][3] = 255;
441                 //data2[x][0] = 255 - b;
442                 //data2[x][1] = 255 - b;
443                 //data2[x][2] = 255 - b;
444                 //data2[x][3] = 255;
445         }
446         if (r_texture_fogattenuation)
447         {
448                 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, FOGWIDTH, 1);
449                 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, FOGWIDTH, 1);
450         }
451         else
452         {
453                 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT | TEXF_ALLOWUPDATES, NULL);
454                 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALLOWUPDATES, NULL);
455         }
456 }
457
458 static const char *builtinshaderstring =
459 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
460 "// written by Forest 'LordHavoc' Hale\n"
461 "\n"
462 "// enable various extensions depending on permutation:\n"
463 "\n"
464 "#ifdef VERTEX_SHADER\n"
465 "uniform mat4 ModelViewProjectionMatrix;\n"
466 "#endif\n"
467 "\n"
468 "#ifdef MODE_DEPTH_OR_SHADOW\n"
469 "#ifdef VERTEX_SHADER\n"
470 "void main(void)\n"
471 "{\n"
472 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
473 "}\n"
474 "#endif\n"
475 "#else // !MODE_DEPTH_ORSHADOW\n"
476 "#ifdef MODE_SHOWDEPTH\n"
477 "#ifdef VERTEX_SHADER\n"
478 "void main(void)\n"
479 "{\n"
480 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
481 "       gl_FrontColor = vec4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
482 "}\n"
483 "#endif\n"
484 "\n"
485 "#ifdef FRAGMENT_SHADER\n"
486 "void main(void)\n"
487 "{\n"
488 "       gl_FragColor = gl_Color;\n"
489 "}\n"
490 "#endif\n"
491 "#else // !MODE_SHOWDEPTH\n"
492 "#ifdef MODE_POSTPROCESS\n"
493 "varying vec2 TexCoord1;\n"
494 "varying vec2 TexCoord2;\n"
495 "\n"
496 "#ifdef VERTEX_SHADER\n"
497 "void main(void)\n"
498 "{\n"
499 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
500 "       TexCoord1 = gl_MultiTexCoord0.xy;\n"
501 "#ifdef USEBLOOM\n"
502 "       TexCoord2 = gl_MultiTexCoord1.xy;\n"
503 "#endif\n"
504 "}\n"
505 "#endif\n"
506 "\n"
507 "#ifdef FRAGMENT_SHADER\n"
508 "uniform sampler2D Texture_First;\n"
509 "#ifdef USEBLOOM\n"
510 "uniform sampler2D Texture_Second;\n"
511 "#endif\n"
512 "#ifdef USEGAMMARAMPS\n"
513 "uniform sampler2D Texture_GammaRamps;\n"
514 "#endif\n"
515 "#ifdef USESATURATION\n"
516 "uniform float Saturation;\n"
517 "#endif\n"
518 "#ifdef USEVIEWTINT\n"
519 "uniform vec4 ViewTintColor;\n"
520 "#endif\n"
521 "//uncomment these if you want to use them:\n"
522 "uniform vec4 UserVec1;\n"
523 "// uniform vec4 UserVec2;\n"
524 "// uniform vec4 UserVec3;\n"
525 "// uniform vec4 UserVec4;\n"
526 "// uniform float ClientTime;\n"
527 "uniform vec2 PixelSize;\n"
528 "void main(void)\n"
529 "{\n"
530 "       gl_FragColor = texture2D(Texture_First, TexCoord1);\n"
531 "#ifdef USEBLOOM\n"
532 "       gl_FragColor += texture2D(Texture_Second, TexCoord2);\n"
533 "#endif\n"
534 "#ifdef USEVIEWTINT\n"
535 "       gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
536 "#endif\n"
537 "\n"
538 "#ifdef USEPOSTPROCESSING\n"
539 "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
540 "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
541 "       gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
542 "       gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
543 "       gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
544 "       gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.707107,  0.707107)) * UserVec1.y;\n"
545 "       gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.453990,  0.891007)) * UserVec1.y;\n"
546 "       gl_FragColor /= (1 + 5 * UserVec1.y);\n"
547 "#endif\n"
548 "\n"
549 "#ifdef USESATURATION\n"
550 "       //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
551 "       float y = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));\n"
552 "       //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
553 "       gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
554 "#endif\n"
555 "\n"
556 "#ifdef USEGAMMARAMPS\n"
557 "       gl_FragColor.r = texture2D(Texture_GammaRamps, vec2(gl_FragColor.r, 0)).r;\n"
558 "       gl_FragColor.g = texture2D(Texture_GammaRamps, vec2(gl_FragColor.g, 0)).g;\n"
559 "       gl_FragColor.b = texture2D(Texture_GammaRamps, vec2(gl_FragColor.b, 0)).b;\n"
560 "#endif\n"
561 "}\n"
562 "#endif\n"
563 "#else // !MODE_POSTPROCESS\n"
564 "#ifdef MODE_GENERIC\n"
565 "#ifdef USEDIFFUSE\n"
566 "varying vec2 TexCoord1;\n"
567 "#endif\n"
568 "#ifdef USESPECULAR\n"
569 "varying vec2 TexCoord2;\n"
570 "#endif\n"
571 "#ifdef VERTEX_SHADER\n"
572 "void main(void)\n"
573 "{\n"
574 "       gl_FrontColor = gl_Color;\n"
575 "#ifdef USEDIFFUSE\n"
576 "       TexCoord1 = gl_MultiTexCoord0.xy;\n"
577 "#endif\n"
578 "#ifdef USESPECULAR\n"
579 "       TexCoord2 = gl_MultiTexCoord1.xy;\n"
580 "#endif\n"
581 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
582 "}\n"
583 "#endif\n"
584 "\n"
585 "#ifdef FRAGMENT_SHADER\n"
586 "#ifdef USEDIFFUSE\n"
587 "uniform sampler2D Texture_First;\n"
588 "#endif\n"
589 "#ifdef USESPECULAR\n"
590 "uniform sampler2D Texture_Second;\n"
591 "#endif\n"
592 "\n"
593 "void main(void)\n"
594 "{\n"
595 "       gl_FragColor = gl_Color;\n"
596 "#ifdef USEDIFFUSE\n"
597 "       gl_FragColor *= texture2D(Texture_First, TexCoord1);\n"
598 "#endif\n"
599 "\n"
600 "#ifdef USESPECULAR\n"
601 "       vec4 tex2 = texture2D(Texture_Second, TexCoord2);\n"
602 "# ifdef USECOLORMAPPING\n"
603 "       gl_FragColor *= tex2;\n"
604 "# endif\n"
605 "# ifdef USEGLOW\n"
606 "       gl_FragColor += tex2;\n"
607 "# endif\n"
608 "# ifdef USEVERTEXTEXTUREBLEND\n"
609 "       gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
610 "# endif\n"
611 "#endif\n"
612 "}\n"
613 "#endif\n"
614 "#else // !MODE_GENERIC\n"
615 "#ifdef MODE_BLOOMBLUR\n"
616 "varying TexCoord;\n"
617 "#ifdef VERTEX_SHADER\n"
618 "void main(void)\n"
619 "{\n"
620 "       gl_FrontColor = gl_Color;\n"
621 "       TexCoord = gl_MultiTexCoord0.xy;\n"
622 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
623 "}\n"
624 "#endif\n"
625 "\n"
626 "#ifdef FRAGMENT_SHADER\n"
627 "uniform sampler2D Texture_First;\n"
628 "uniform vec4 BloomBlur_Parameters;\n"
629 "\n"
630 "void main(void)\n"
631 "{\n"
632 "       int i;\n"
633 "       vec2 tc = TexCoord;\n"
634 "       vec3 color = texture2D(Texture_First, tc).rgb;\n"
635 "       tc += BloomBlur_Parameters.xy;\n"
636 "       for (i = 1;i < SAMPLES;i++)\n"
637 "       {\n"
638 "               color += texture2D(Texture_First, tc).rgb;\n"
639 "               tc += BloomBlur_Parameters.xy;\n"
640 "       }\n"
641 "       gl_FragColor = vec4(color * BloomBlur_Parameters.z + vec3(BloomBlur_Parameters.w), 1);\n"
642 "}\n"
643 "#endif\n"
644 "#else // !MODE_BLOOMBLUR\n"
645 "#ifdef MODE_REFRACTION\n"
646 "varying vec2 TexCoord;\n"
647 "varying vec4 ModelViewProjectionPosition;\n"
648 "uniform mat4 TexMatrix;\n"
649 "#ifdef VERTEX_SHADER\n"
650 "\n"
651 "void main(void)\n"
652 "{\n"
653 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
654 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
655 "       ModelViewProjectionPosition = gl_Position;\n"
656 "}\n"
657 "#endif\n"
658 "\n"
659 "#ifdef FRAGMENT_SHADER\n"
660 "uniform sampler2D Texture_Normal;\n"
661 "uniform sampler2D Texture_Refraction;\n"
662 "uniform sampler2D Texture_Reflection;\n"
663 "\n"
664 "uniform vec4 DistortScaleRefractReflect;\n"
665 "uniform vec4 ScreenScaleRefractReflect;\n"
666 "uniform vec4 ScreenCenterRefractReflect;\n"
667 "uniform vec4 RefractColor;\n"
668 "uniform vec4 ReflectColor;\n"
669 "uniform float ReflectFactor;\n"
670 "uniform float ReflectOffset;\n"
671 "\n"
672 "void main(void)\n"
673 "{\n"
674 "       vec2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
675 "       //vec2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
676 "       vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
677 "       vec2 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
678 "       // FIXME temporary hack to detect the case that the reflection\n"
679 "       // gets blackened at edges due to leaving the area that contains actual\n"
680 "       // content.\n"
681 "       // Remove this 'ack once we have a better way to stop this thing from\n"
682 "       // 'appening.\n"
683 "       float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
684 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
685 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
686 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
687 "       ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
688 "       gl_FragColor = texture2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
689 "}\n"
690 "#endif\n"
691 "#else // !MODE_REFRACTION\n"
692 "#ifdef MODE_WATER\n"
693 "varying vec2 TexCoord;\n"
694 "varying vec3 EyeVector;\n"
695 "varying vec4 ModelViewProjectionPosition;\n"
696 "#ifdef VERTEX_SHADER\n"
697 "uniform vec3 EyePosition;\n"
698 "uniform mat4 TexMatrix;\n"
699 "\n"
700 "void main(void)\n"
701 "{\n"
702 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
703 "       vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
704 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
705 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
706 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
707 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
708 "       ModelViewProjectionPosition = gl_Position;\n"
709 "}\n"
710 "#endif\n"
711 "\n"
712 "#ifdef FRAGMENT_SHADER\n"
713 "uniform sampler2D Texture_Normal;\n"
714 "uniform sampler2D Texture_Refraction;\n"
715 "uniform sampler2D Texture_Reflection;\n"
716 "\n"
717 "uniform vec4 DistortScaleRefractReflect;\n"
718 "uniform vec4 ScreenScaleRefractReflect;\n"
719 "uniform vec4 ScreenCenterRefractReflect;\n"
720 "uniform vec4 RefractColor;\n"
721 "uniform vec4 ReflectColor;\n"
722 "uniform float ReflectFactor;\n"
723 "uniform float ReflectOffset;\n"
724 "\n"
725 "void main(void)\n"
726 "{\n"
727 "       vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
728 "       //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
729 "       vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
730 "       vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
731 "       // FIXME temporary hack to detect the case that the reflection\n"
732 "       // gets blackened at edges due to leaving the area that contains actual\n"
733 "       // content.\n"
734 "       // Remove this 'ack once we have a better way to stop this thing from\n"
735 "       // 'appening.\n"
736 "       float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, 0.01)).rgb) / 0.05);\n"
737 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, -0.01)).rgb) / 0.05);\n"
738 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
739 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
740 "       ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
741 "       f       = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, 0.01)).rgb) / 0.05);\n"
742 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, -0.01)).rgb) / 0.05);\n"
743 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
744 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
745 "       ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
746 "       float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
747 "       gl_FragColor = mix(texture2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, texture2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
748 "}\n"
749 "#endif\n"
750 "#else // !MODE_WATER\n"
751 "\n"
752 "#if defined(USESHADOWMAPRECT) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USEDEFERREDLIGHTMAP)\n"
753 "# extension GL_ARB_texture_rectangle : enable\n"
754 "#endif\n"
755 "\n"
756 "#ifdef USESHADOWMAP2D\n"
757 "# ifdef GL_EXT_gpu_shader4\n"
758 "#   extension GL_EXT_gpu_shader4 : enable\n"
759 "# endif\n"
760 "# ifdef GL_ARB_texture_gather\n"
761 "#   extension GL_ARB_texture_gather : enable\n"
762 "# else\n"
763 "#   ifdef GL_AMD_texture_texture4\n"
764 "#     extension GL_AMD_texture_texture4 : enable\n"
765 "#   endif\n"
766 "# endif\n"
767 "#endif\n"
768 "\n"
769 "#ifdef USESHADOWMAPCUBE\n"
770 "# extension GL_EXT_gpu_shader4 : enable\n"
771 "#endif\n"
772 "\n"
773 "#ifdef USESHADOWSAMPLER\n"
774 "# extension GL_ARB_shadow : enable\n"
775 "#endif\n"
776 "\n"
777 "// common definitions between vertex shader and fragment shader:\n"
778 "\n"
779 "//#ifdef __GLSL_CG_DATA_TYPES\n"
780 "//# define myhalf half\n"
781 "//# define myhalf2 half2\n"
782 "//# define myhalf3half3\n"
783 "//# define myhalf4 half4\n"
784 "//#else\n"
785 "# define myhalf float\n"
786 "# define myhalf2 vec2\n"
787 "# define myhalf3 vec3\n"
788 "# define myhalf4 vec4\n"
789 "//#endif\n"
790 "\n"
791 "#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
792 "# define USEFOG\n"
793 "#endif\n"
794 "\n"
795 "varying vec2 TexCoord;\n"
796 "#ifdef USEVERTEXTEXTUREBLEND\n"
797 "varying vec2 TexCoord2;\n"
798 "#endif\n"
799 "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
800 "#define USELIGHTMAP\n"
801 "varying vec2 TexCoordLightmap;\n"
802 "#endif\n"
803 "\n"
804 "#ifdef MODE_LIGHTSOURCE\n"
805 "varying vec3 CubeVector;\n"
806 "#endif\n"
807 "\n"
808 "#ifdef MODE_LIGHTSOURCE\n"
809 "varying vec3 LightVector;\n"
810 "#endif\n"
811 "#if defined(MODE_LIGHTDIRECTION)\n"
812 "varying vec3 LightVector;\n"
813 "#endif\n"
814 "\n"
815 "#if defined(USEOFFSETMAPPING) || defined(USESPECULAR)\n"
816 "//#if defined(USEOFFSETMAPPING) || defined(USESPECULAR) || defined(MODE_LIGHTDIRECTION) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
817 "#define USEEYEVECTOR\n"
818 "varying vec3 EyeVector;\n"
819 "#endif\n"
820 "#ifdef USEFOG\n"
821 "varying vec3 EyeVectorModelSpace;\n"
822 "varying float FogPlaneVertexDist;\n"
823 "#endif\n"
824 "\n"
825 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
826 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
827 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
828 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
829 "#endif\n"
830 "\n"
831 "#ifdef USEREFLECTION\n"
832 "varying vec4 ModelViewProjectionPosition;\n"
833 "#endif\n"
834 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
835 "uniform vec3 LightPosition;\n"
836 "varying vec4 ModelViewPosition;\n"
837 "#endif\n"
838 "\n"
839 "#ifdef MODE_LIGHTSOURCE\n"
840 "uniform vec3 LightPosition;\n"
841 "#endif\n"
842 "uniform vec3 EyePosition;\n"
843 "#ifdef MODE_LIGHTDIRECTION\n"
844 "uniform vec3 LightDir;\n"
845 "#endif\n"
846 "uniform vec4 FogPlane;\n"
847 "\n"
848 "\n"
849 "\n"
850 "\n"
851 "\n"
852 "// vertex shader specific:\n"
853 "#ifdef VERTEX_SHADER\n"
854 "\n"
855 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
856 "\n"
857 "#ifdef MODE_DEFERREDGEOMETRY\n"
858 "uniform mat4 TexMatrix;\n"
859 "#ifdef USEVERTEXTEXTUREBLEND\n"
860 "uniform mat4 BackgroundTexMatrix;\n"
861 "#endif\n"
862 "uniform mat4 ModelViewMatrix;\n"
863 "void main(void)\n"
864 "{\n"
865 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
866 "#ifdef USEVERTEXTEXTUREBLEND\n"
867 "       gl_FrontColor = gl_Color;\n"
868 "       TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
869 "#endif\n"
870 "\n"
871 "       // transform unnormalized eye direction into tangent space\n"
872 "#ifdef USEOFFSETMAPPING\n"
873 "       vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
874 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
875 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
876 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
877 "#endif\n"
878 "\n"
879 "       VectorS = (ModelViewMatrix * vec4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
880 "       VectorT = (ModelViewMatrix * vec4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
881 "       VectorR = (ModelViewMatrix * vec4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
882 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
883 "}\n"
884 "#else // !MODE_DEFERREDGEOMETRY\n"
885 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
886 "uniform mat4 ModelViewMatrix;\n"
887 "void main(void)\n"
888 "{\n"
889 "       ModelViewPosition = ModelViewMatrix * gl_Vertex;\n"
890 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
891 "}\n"
892 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
893 "uniform mat4 TexMatrix;\n"
894 "#ifdef USEVERTEXTEXTUREBLEND\n"
895 "uniform mat4 BackgroundTexMatrix;\n"
896 "#endif\n"
897 "#ifdef MODE_LIGHTSOURCE\n"
898 "uniform mat4 ModelToLight;\n"
899 "#endif\n"
900 "void main(void)\n"
901 "{\n"
902 "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
903 "       gl_FrontColor = gl_Color;\n"
904 "#endif\n"
905 "       // copy the surface texcoord\n"
906 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
907 "#ifdef USEVERTEXTEXTUREBLEND\n"
908 "       TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
909 "#endif\n"
910 "#ifdef USELIGHTMAP\n"
911 "       TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
912 "#endif\n"
913 "\n"
914 "#ifdef MODE_LIGHTSOURCE\n"
915 "       // transform vertex position into light attenuation/cubemap space\n"
916 "       // (-1 to +1 across the light box)\n"
917 "       CubeVector = vec3(ModelToLight * gl_Vertex);\n"
918 "\n"
919 "# ifdef USEDIFFUSE\n"
920 "       // transform unnormalized light direction into tangent space\n"
921 "       // (we use unnormalized to ensure that it interpolates correctly and then\n"
922 "       //  normalize it per pixel)\n"
923 "       vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
924 "       LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
925 "       LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
926 "       LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
927 "# endif\n"
928 "#endif\n"
929 "\n"
930 "#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
931 "       LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
932 "       LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
933 "       LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
934 "#endif\n"
935 "\n"
936 "       // transform unnormalized eye direction into tangent space\n"
937 "#ifdef USEEYEVECTOR\n"
938 "#ifndef USEFOG\n"
939 "       vec3 EyeVectorModelSpace;\n"
940 "#endif\n"
941 "       EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
942 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
943 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
944 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
945 "#endif\n"
946 "\n"
947 "#ifdef USEFOG\n"
948 "#ifndef USEEYEVECTOR\n"
949 "       EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
950 "#endif\n"
951 "       FogPlaneVertexDist = dot(FogPlane, gl_Vertex);\n"
952 "#endif\n"
953 "\n"
954 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
955 "       VectorS = gl_MultiTexCoord1.xyz;\n"
956 "       VectorT = gl_MultiTexCoord2.xyz;\n"
957 "       VectorR = gl_MultiTexCoord3.xyz;\n"
958 "#endif\n"
959 "\n"
960 "       // transform vertex to camera space, using ftransform to match non-VS rendering\n"
961 "       gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
962 "\n"
963 "#ifdef USEREFLECTION\n"
964 "       ModelViewProjectionPosition = gl_Position;\n"
965 "#endif\n"
966 "}\n"
967 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
968 "#endif // !MODE_DEFERREDGEOMETRY\n"
969 "\n"
970 "#endif // VERTEX_SHADER\n"
971 "\n"
972 "\n"
973 "\n"
974 "\n"
975 "// fragment shader specific:\n"
976 "#ifdef FRAGMENT_SHADER\n"
977 "\n"
978 "uniform sampler2D Texture_Normal;\n"
979 "uniform sampler2D Texture_Color;\n"
980 "//#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
981 "uniform sampler2D Texture_Gloss;\n"
982 "//#endif\n"
983 "#ifdef USEGLOW\n"
984 "uniform sampler2D Texture_Glow;\n"
985 "#endif\n"
986 "#ifdef USEVERTEXTEXTUREBLEND\n"
987 "uniform sampler2D Texture_SecondaryNormal;\n"
988 "uniform sampler2D Texture_SecondaryColor;\n"
989 "//#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
990 "uniform sampler2D Texture_SecondaryGloss;\n"
991 "//#endif\n"
992 "#ifdef USEGLOW\n"
993 "uniform sampler2D Texture_SecondaryGlow;\n"
994 "#endif\n"
995 "#endif\n"
996 "#ifdef USECOLORMAPPING\n"
997 "uniform sampler2D Texture_Pants;\n"
998 "uniform sampler2D Texture_Shirt;\n"
999 "#endif\n"
1000 "#ifdef USEFOG\n"
1001 "uniform sampler2D Texture_FogMask;\n"
1002 "#endif\n"
1003 "#ifdef USELIGHTMAP\n"
1004 "uniform sampler2D Texture_Lightmap;\n"
1005 "#endif\n"
1006 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
1007 "uniform sampler2D Texture_Deluxemap;\n"
1008 "#endif\n"
1009 "#ifdef USEREFLECTION\n"
1010 "uniform sampler2D Texture_Reflection;\n"
1011 "#endif\n"
1012 "\n"
1013 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
1014 "uniform sampler2DRect Texture_ScreenDepth;\n"
1015 "uniform sampler2DRect Texture_ScreenNormalMap;\n"
1016 "#endif\n"
1017 "#ifdef USEDEFERREDLIGHTMAP\n"
1018 "uniform sampler2DRect Texture_ScreenDiffuse;\n"
1019 "uniform sampler2DRect Texture_ScreenSpecular;\n"
1020 "#endif\n"
1021 "\n"
1022 "uniform myhalf3 Color_Pants;\n"
1023 "uniform myhalf3 Color_Shirt;\n"
1024 "uniform myhalf3 FogColor;\n"
1025 "\n"
1026 "#ifdef USEFOG\n"
1027 "uniform float FogRangeRecip;\n"
1028 "uniform float FogPlaneViewDist;\n"
1029 "uniform float FogHeightFade;\n"
1030 "myhalf FogVertex(void)\n"
1031 "{\n"
1032 "       float fogfrac;\n"
1033 "#ifdef USEFOGOUTSIDE\n"
1034 "       fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
1035 "#else\n"
1036 "       fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
1037 "#endif\n"
1038 "       return myhalf(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
1039 "}\n"
1040 "#endif\n"
1041 "\n"
1042 "#ifdef USEOFFSETMAPPING\n"
1043 "uniform float OffsetMapping_Scale;\n"
1044 "vec2 OffsetMapping(vec2 TexCoord)\n"
1045 "{\n"
1046 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
1047 "       // 14 sample relief mapping: linear search and then binary search\n"
1048 "       // this basically steps forward a small amount repeatedly until it finds\n"
1049 "       // itself inside solid, then jitters forward and back using decreasing\n"
1050 "       // amounts to find the impact\n"
1051 "       //vec3 OffsetVector = vec3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1), -1);\n"
1052 "       //vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
1053 "       vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
1054 "       vec3 RT = vec3(TexCoord, 1);\n"
1055 "       OffsetVector *= 0.1;\n"
1056 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1057 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1058 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1059 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1060 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1061 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1062 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1063 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1064 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1065 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z)          - 0.5);\n"
1066 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.5    - 0.25);\n"
1067 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.25   - 0.125);\n"
1068 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.125  - 0.0625);\n"
1069 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
1070 "       return RT.xy;\n"
1071 "#else\n"
1072 "       // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
1073 "       // this basically moves forward the full distance, and then backs up based\n"
1074 "       // on height of samples\n"
1075 "       //vec2 OffsetVector = vec2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1));\n"
1076 "       //vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1));\n"
1077 "       vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1));\n"
1078 "       TexCoord += OffsetVector;\n"
1079 "       OffsetVector *= 0.333;\n"
1080 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1081 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1082 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1083 "       return TexCoord;\n"
1084 "#endif\n"
1085 "}\n"
1086 "#endif // USEOFFSETMAPPING\n"
1087 "\n"
1088 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
1089 "uniform sampler2D Texture_Attenuation;\n"
1090 "uniform samplerCube Texture_Cube;\n"
1091 "\n"
1092 "#ifdef USESHADOWMAPRECT\n"
1093 "# ifdef USESHADOWSAMPLER\n"
1094 "uniform sampler2DRectShadow Texture_ShadowMapRect;\n"
1095 "# else\n"
1096 "uniform sampler2DRect Texture_ShadowMapRect;\n"
1097 "# endif\n"
1098 "#endif\n"
1099 "\n"
1100 "#ifdef USESHADOWMAP2D\n"
1101 "# ifdef USESHADOWSAMPLER\n"
1102 "uniform sampler2DShadow Texture_ShadowMap2D;\n"
1103 "# else\n"
1104 "uniform sampler2D Texture_ShadowMap2D;\n"
1105 "# endif\n"
1106 "#endif\n"
1107 "\n"
1108 "#ifdef USESHADOWMAPVSDCT\n"
1109 "uniform samplerCube Texture_CubeProjection;\n"
1110 "#endif\n"
1111 "\n"
1112 "#ifdef USESHADOWMAPCUBE\n"
1113 "# ifdef USESHADOWSAMPLER\n"
1114 "uniform samplerCubeShadow Texture_ShadowMapCube;\n"
1115 "# else\n"
1116 "uniform samplerCube Texture_ShadowMapCube;\n"
1117 "# endif\n"
1118 "#endif\n"
1119 "\n"
1120 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
1121 "uniform vec2 ShadowMap_TextureScale;\n"
1122 "uniform vec4 ShadowMap_Parameters;\n"
1123 "#endif\n"
1124 "\n"
1125 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
1126 "vec3 GetShadowMapTC2D(vec3 dir)\n"
1127 "{\n"
1128 "       vec3 adir = abs(dir);\n"
1129 "# ifndef USESHADOWMAPVSDCT\n"
1130 "       vec2 tc;\n"
1131 "       vec2 offset;\n"
1132 "       float ma;\n"
1133 "       if (adir.x > adir.y)\n"
1134 "       {\n"
1135 "               if (adir.x > adir.z) // X\n"
1136 "               {\n"
1137 "                       ma = adir.x;\n"
1138 "                       tc = dir.zy;\n"
1139 "                       offset = vec2(mix(0.5, 1.5, dir.x < 0.0), 0.5);\n"
1140 "               }\n"
1141 "               else // Z\n"
1142 "               {\n"
1143 "                       ma = adir.z;\n"
1144 "                       tc = dir.xy;\n"
1145 "                       offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
1146 "               }\n"
1147 "       }\n"
1148 "       else\n"
1149 "       {\n"
1150 "               if (adir.y > adir.z) // Y\n"
1151 "               {\n"
1152 "                       ma = adir.y;\n"
1153 "                       tc = dir.xz;\n"
1154 "                       offset = vec2(mix(0.5, 1.5, dir.y < 0.0), 1.5);\n"
1155 "               }\n"
1156 "               else // Z\n"
1157 "               {\n"
1158 "                       ma = adir.z;\n"
1159 "                       tc = dir.xy;\n"
1160 "                       offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
1161 "               }\n"
1162 "       }\n"
1163 "\n"
1164 "       vec3 stc = vec3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
1165 "       stc.xy += offset * ShadowMap_Parameters.y;\n"
1166 "       stc.z += ShadowMap_Parameters.z;\n"
1167 "       return stc;\n"
1168 "# else\n"
1169 "       vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
1170 "       float ma = max(max(adir.x, adir.y), adir.z);\n"
1171 "       vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
1172 "       stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
1173 "       stc.z += ShadowMap_Parameters.z;\n"
1174 "       return stc;\n"
1175 "# endif\n"
1176 "}\n"
1177 "#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
1178 "\n"
1179 "#ifdef USESHADOWMAPCUBE\n"
1180 "vec4 GetShadowMapTCCube(vec3 dir)\n"
1181 "{\n"
1182 "    vec3 adir = abs(dir);\n"
1183 "    return vec4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
1184 "}\n"
1185 "#endif\n"
1186 "\n"
1187 "# ifdef USESHADOWMAPRECT\n"
1188 "float ShadowMapCompare(vec3 dir)\n"
1189 "{\n"
1190 "       vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
1191 "       float f;\n"
1192 "#  ifdef USESHADOWSAMPLER\n"
1193 "\n"
1194 "#    ifdef USESHADOWMAPPCF\n"
1195 "#      define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + vec3(x, y, 0.0)).r\n"
1196 "    f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
1197 "#    else\n"
1198 "    f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
1199 "#    endif\n"
1200 "\n"
1201 "#  else\n"
1202 "\n"
1203 "#    ifdef USESHADOWMAPPCF\n"
1204 "#      if USESHADOWMAPPCF > 1\n"
1205 "#        define texval(x, y) texture2DRect(Texture_ShadowMapRect, center + vec2(x, y)).r\n"
1206 "    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
1207 "    vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
1208 "    vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
1209 "    vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
1210 "    vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
1211 "    vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
1212 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1213 "#      else\n"
1214 "#        define texval(x, y) texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(x, y)).r\n"
1215 "    vec2 offset = fract(shadowmaptc.xy);\n"
1216 "    vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
1217 "    vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
1218 "    vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
1219 "    vec3 cols = row2 + mix(row1, row3, offset.y);\n"
1220 "    f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
1221 "#      endif\n"
1222 "#    else\n"
1223 "    f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
1224 "#    endif\n"
1225 "\n"
1226 "#  endif\n"
1227 "       return f;\n"
1228 "}\n"
1229 "# endif\n"
1230 "\n"
1231 "# ifdef USESHADOWMAP2D\n"
1232 "float ShadowMapCompare(vec3 dir)\n"
1233 "{\n"
1234 "    vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
1235 "    float f;\n"
1236 "\n"
1237 "#  ifdef USESHADOWSAMPLER\n"
1238 "#    ifdef USESHADOWMAPPCF\n"
1239 "#      define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r  \n"
1240 "    vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
1241 "    f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
1242 "#    else\n"
1243 "    f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
1244 "#    endif\n"
1245 "#  else\n"
1246 "#    ifdef USESHADOWMAPPCF\n"
1247 "#     if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
1248 "#      ifdef GL_ARB_texture_gather\n"
1249 "#        define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec(x, y))\n"
1250 "#      else\n"
1251 "#        define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x,y)*ShadowMap_TextureScale)\n"
1252 "#      endif\n"
1253 "    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
1254 "    center *= ShadowMap_TextureScale;\n"
1255 "    vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
1256 "    vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
1257 "    vec4 group3 = step(shadowmaptc.z, texval(-1.0,  1.0));\n"
1258 "    vec4 group4 = step(shadowmaptc.z, texval( 1.0,  1.0));\n"
1259 "    vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
1260 "                mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
1261 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1262 "#     else\n"
1263 "#      ifdef GL_EXT_gpu_shader4\n"
1264 "#        define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n"
1265 "#      else\n"
1266 "#        define texval(x, y) texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r  \n"
1267 "#      endif\n"
1268 "#      if USESHADOWMAPPCF > 1\n"
1269 "    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
1270 "    center *= ShadowMap_TextureScale;\n"
1271 "    vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
1272 "    vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0), texval( 2.0,  0.0)));\n"
1273 "    vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0), texval( 2.0,  1.0)));\n"
1274 "    vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0,  2.0), texval( 0.0,  2.0), texval( 1.0,  2.0), texval( 2.0,  2.0)));\n"
1275 "    vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
1276 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1277 "#      else\n"
1278 "    vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
1279 "    vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
1280 "    vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
1281 "    vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
1282 "    vec3 cols = row2 + mix(row1, row3, offset.y);\n"
1283 "    f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
1284 "#      endif\n"
1285 "#     endif\n"
1286 "#    else\n"
1287 "    f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
1288 "#    endif\n"
1289 "#  endif\n"
1290 "    return f;\n"
1291 "}\n"
1292 "# endif\n"
1293 "\n"
1294 "# ifdef USESHADOWMAPCUBE\n"
1295 "float ShadowMapCompare(vec3 dir)\n"
1296 "{\n"
1297 "    // apply depth texture cubemap as light filter\n"
1298 "    vec4 shadowmaptc = GetShadowMapTCCube(dir);\n"
1299 "    float f;\n"
1300 "#  ifdef USESHADOWSAMPLER\n"
1301 "    f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
1302 "#  else\n"
1303 "    f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
1304 "#  endif\n"
1305 "    return f;\n"
1306 "}\n"
1307 "# endif\n"
1308 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
1309 "\n"
1310 "#ifdef MODE_DEFERREDGEOMETRY\n"
1311 "void main(void)\n"
1312 "{\n"
1313 "#ifdef USEOFFSETMAPPING\n"
1314 "       // apply offsetmapping\n"
1315 "       vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1316 "#define TexCoord TexCoordOffset\n"
1317 "#endif\n"
1318 "\n"
1319 "#ifdef USEALPHAKILL\n"
1320 "       if (texture2D(Texture_Color, TexCoord).a < 0.5)\n"
1321 "               discard;\n"
1322 "#endif\n"
1323 "\n"
1324 "#ifdef USEVERTEXTEXTUREBLEND\n"
1325 "       float alpha = texture2D(Texture_Color, TexCoord).a;\n"
1326 "       float terrainblend = clamp(float(gl_Color.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
1327 "       //float terrainblend = min(float(gl_Color.a) * alpha * 2.0, float(1.0));\n"
1328 "       //float terrainblend = float(gl_Color.a) * alpha > 0.5;\n"
1329 "#endif\n"
1330 "\n"
1331 "#ifdef USEVERTEXTEXTUREBLEND\n"
1332 "       vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(texture2D(Texture_Normal, TexCoord)), terrainblend) - vec3(0.5, 0.5, 0.5);\n"
1333 "#else\n"
1334 "       vec3 surfacenormal = vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5, 0.5, 0.5);\n"
1335 "#endif\n"
1336 "\n"
1337 "       gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), 1);\n"
1338 "}\n"
1339 "#else // !MODE_DEFERREDGEOMETRY\n"
1340 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
1341 "uniform mat4 ViewToLight;\n"
1342 "// ScreenToDepth = vec2(Far / (Far - Near), Far * Near / (Near - Far));\n"
1343 "uniform vec2 ScreenToDepth;\n"
1344 "uniform myhalf3 DeferredColor_Ambient;\n"
1345 "uniform myhalf3 DeferredColor_Diffuse;\n"
1346 "#ifdef USESPECULAR\n"
1347 "uniform myhalf3 DeferredColor_Specular;\n"
1348 "uniform myhalf SpecularPower;\n"
1349 "#endif\n"
1350 "void main(void)\n"
1351 "{\n"
1352 "       // calculate viewspace pixel position\n"
1353 "       vec3 position;\n"
1354 "       position.z = ScreenToDepth.y / (texture2DRect(Texture_ScreenDepth, gl_FragCoord.xy).r + ScreenToDepth.x);\n"
1355 "       position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
1356 "       // decode viewspace pixel normal\n"
1357 "       myhalf4 normalmap = texture2DRect(Texture_ScreenNormalMap, gl_FragCoord.xy);\n"
1358 "       myhalf3 surfacenormal = normalize(normalmap.rgb - myhalf3(0.5,0.5,0.5));\n"
1359 "       // surfacenormal = pixel normal in viewspace\n"
1360 "       // LightVector = pixel to light in viewspace\n"
1361 "       // CubeVector = position in lightspace\n"
1362 "       // eyevector = pixel to view in viewspace\n"
1363 "       vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n"
1364 "       myhalf fade = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
1365 "#ifdef USEDIFFUSE\n"
1366 "       // calculate diffuse shading\n"
1367 "       myhalf3 lightnormal = myhalf3(normalize(LightPosition - position));\n"
1368 "       myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1369 "#endif\n"
1370 "#ifdef USESPECULAR\n"
1371 "       // calculate directional shading\n"
1372 "       vec3 eyevector = position * -1.0;\n"
1373 "#  ifdef USEEXACTSPECULARMATH\n"
1374 "       myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower);\n"
1375 "#  else\n"
1376 "       myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(eyevector)));\n"
1377 "       myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1378 "#  endif\n"
1379 "#endif\n"
1380 "\n"
1381 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
1382 "       fade *= ShadowMapCompare(CubeVector);\n"
1383 "#endif\n"
1384 "\n"
1385 "#ifdef USEDIFFUSE\n"
1386 "       gl_FragData[0] = vec4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
1387 "#else\n"
1388 "       gl_FragData[0] = vec4(DeferredColor_Ambient * fade, 1.0);\n"
1389 "#endif\n"
1390 "#ifdef USESPECULAR\n"
1391 "       gl_FragData[1] = vec4(DeferredColor_Specular * (specular * fade), 1.0);\n"
1392 "#else\n"
1393 "       gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0);\n"
1394 "#endif\n"
1395 "\n"
1396 "# ifdef USECUBEFILTER\n"
1397 "       vec3 cubecolor = textureCube(Texture_Cube, CubeVector).rgb;\n"
1398 "       gl_FragData[0] *= cubecolor;\n"
1399 "       gl_FragData[1] *= cubecolor;\n"
1400 "# endif\n"
1401 "}\n"
1402 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
1403 "#ifdef USEDEFERREDLIGHTMAP\n"
1404 "uniform myhalf3 DeferredMod_Diffuse;\n"
1405 "uniform myhalf3 DeferredMod_Specular;\n"
1406 "#endif\n"
1407 "uniform myhalf3 Color_Ambient;\n"
1408 "uniform myhalf3 Color_Diffuse;\n"
1409 "uniform myhalf3 Color_Specular;\n"
1410 "uniform myhalf SpecularPower;\n"
1411 "#ifdef USEGLOW\n"
1412 "uniform myhalf3 Color_Glow;\n"
1413 "#endif\n"
1414 "uniform myhalf Alpha;\n"
1415 "#ifdef USEREFLECTION\n"
1416 "uniform vec4 DistortScaleRefractReflect;\n"
1417 "uniform vec4 ScreenScaleRefractReflect;\n"
1418 "uniform vec4 ScreenCenterRefractReflect;\n"
1419 "uniform myhalf4 ReflectColor;\n"
1420 "#endif\n"
1421 "#ifdef MODE_LIGHTDIRECTION\n"
1422 "uniform myhalf3 LightColor;\n"
1423 "#endif\n"
1424 "#ifdef MODE_LIGHTSOURCE\n"
1425 "uniform myhalf3 LightColor;\n"
1426 "#endif\n"
1427 "void main(void)\n"
1428 "{\n"
1429 "#ifdef USEOFFSETMAPPING\n"
1430 "       // apply offsetmapping\n"
1431 "       vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1432 "#define TexCoord TexCoordOffset\n"
1433 "#endif\n"
1434 "\n"
1435 "       // combine the diffuse textures (base, pants, shirt)\n"
1436 "       myhalf4 color = myhalf4(texture2D(Texture_Color, TexCoord));\n"
1437 "#ifdef USEALPHAKILL\n"
1438 "       if (color.a < 0.5)\n"
1439 "               discard;\n"
1440 "#endif\n"
1441 "       color.a *= Alpha;\n"
1442 "#ifdef USECOLORMAPPING\n"
1443 "       color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
1444 "#endif\n"
1445 "#ifdef USEVERTEXTEXTUREBLEND\n"
1446 "       myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
1447 "       //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n"
1448 "       //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n"
1449 "       color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord2)), color.rgb, terrainblend);\n"
1450 "       color.a = 1.0;\n"
1451 "       //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
1452 "#endif\n"
1453 "\n"
1454 "       // get the surface normal\n"
1455 "#ifdef USEVERTEXTEXTUREBLEND\n"
1456 "       myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n"
1457 "#else\n"
1458 "       myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n"
1459 "#endif\n"
1460 "\n"
1461 "       // get the material colors\n"
1462 "       myhalf3 diffusetex = color.rgb;\n"
1463 "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
1464 "# ifdef USEVERTEXTEXTUREBLEND\n"
1465 "       myhalf3 glosstex = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
1466 "# else\n"
1467 "       myhalf3 glosstex = myhalf3(texture2D(Texture_Gloss, TexCoord));\n"
1468 "# endif\n"
1469 "#endif\n"
1470 "\n"
1471 "\n"
1472 "\n"
1473 "\n"
1474 "#ifdef MODE_LIGHTSOURCE\n"
1475 "       // light source\n"
1476 "       myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
1477 "       myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1478 "       color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
1479 "#ifdef USESPECULAR\n"
1480 "#ifdef USEEXACTSPECULARMATH\n"
1481 "       myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
1482 "#else\n"
1483 "       myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
1484 "       myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1485 "#endif\n"
1486 "       color.rgb += glosstex * (specular * Color_Specular);\n"
1487 "#endif\n"
1488 "       color.rgb *= LightColor;\n"
1489 "       color.rgb *= myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
1490 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
1491 "       color.rgb *= ShadowMapCompare(CubeVector);\n"
1492 "#endif\n"
1493 "# ifdef USECUBEFILTER\n"
1494 "       color.rgb *= myhalf3(textureCube(Texture_Cube, CubeVector));\n"
1495 "# endif\n"
1496 "#endif // MODE_LIGHTSOURCE\n"
1497 "\n"
1498 "\n"
1499 "\n"
1500 "\n"
1501 "#ifdef MODE_LIGHTDIRECTION\n"
1502 "#define SHADING\n"
1503 "       myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
1504 "#define lightcolor LightColor\n"
1505 "#endif // MODE_LIGHTDIRECTION\n"
1506 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1507 "#define SHADING\n"
1508 "       // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
1509 "       myhalf3 lightnormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1510 "       myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1511 "       // convert modelspace light vector to tangentspace\n"
1512 "       myhalf3 lightnormal;\n"
1513 "       lightnormal.x = dot(lightnormal_modelspace, myhalf3(VectorS));\n"
1514 "       lightnormal.y = dot(lightnormal_modelspace, myhalf3(VectorT));\n"
1515 "       lightnormal.z = dot(lightnormal_modelspace, myhalf3(VectorR));\n"
1516 "       // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
1517 "       // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
1518 "       // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
1519 "       // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
1520 "       // to map the luxels to coordinates on the draw surfaces), which also causes\n"
1521 "       // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
1522 "       // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
1523 "       // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
1524 "       // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
1525 "       lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
1526 "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1527 "#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
1528 "#define SHADING\n"
1529 "       // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
1530 "       myhalf3 lightnormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1531 "       myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1532 "#endif\n"
1533 "\n"
1534 "\n"
1535 "\n"
1536 "\n"
1537 "#ifdef MODE_LIGHTMAP\n"
1538 "       color.rgb = diffusetex * (Color_Ambient + myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
1539 "#endif // MODE_LIGHTMAP\n"
1540 "#ifdef MODE_VERTEXCOLOR\n"
1541 "       color.rgb = diffusetex * (Color_Ambient + myhalf3(gl_Color.rgb) * Color_Diffuse);\n"
1542 "#endif // MODE_VERTEXCOLOR\n"
1543 "#ifdef MODE_FLATCOLOR\n"
1544 "       color.rgb = diffusetex * Color_Ambient;\n"
1545 "#endif // MODE_FLATCOLOR\n"
1546 "\n"
1547 "\n"
1548 "\n"
1549 "\n"
1550 "#ifdef SHADING\n"
1551 "# ifdef USEDIFFUSE\n"
1552 "       myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1553 "#  ifdef USESPECULAR\n"
1554 "#   ifdef USEEXACTSPECULARMATH\n"
1555 "       myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
1556 "#   else\n"
1557 "       myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
1558 "       myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1559 "#   endif\n"
1560 "       color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex * Color_Specular * specular) * lightcolor;\n"
1561 "#  else\n"
1562 "       color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
1563 "#  endif\n"
1564 "# else\n"
1565 "       color.rgb = diffusetex * Color_Ambient;\n"
1566 "# endif\n"
1567 "#endif\n"
1568 "\n"
1569 "#ifdef USEDEFERREDLIGHTMAP\n"
1570 "       color.rgb += diffusetex * myhalf3(texture2DRect(Texture_ScreenDiffuse, gl_FragCoord.xy)) * DeferredMod_Diffuse;\n"
1571 "       color.rgb += glosstex * myhalf3(texture2DRect(Texture_ScreenSpecular, gl_FragCoord.xy)) * DeferredMod_Specular;\n"
1572 "#endif\n"
1573 "\n"
1574 "#ifdef USEGLOW\n"
1575 "#ifdef USEVERTEXTEXTUREBLEND\n"
1576 "       color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
1577 "#else\n"
1578 "       color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
1579 "#endif\n"
1580 "#endif\n"
1581 "\n"
1582 "#ifdef USEFOG\n"
1583 "       color.rgb = mix(FogColor, color.rgb, FogVertex());\n"
1584 "#endif\n"
1585 "\n"
1586 "       // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
1587 "#ifdef USEREFLECTION\n"
1588 "       vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
1589 "       //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
1590 "       vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
1591 "       vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
1592 "       // FIXME temporary hack to detect the case that the reflection\n"
1593 "       // gets blackened at edges due to leaving the area that contains actual\n"
1594 "       // content.\n"
1595 "       // Remove this 'ack once we have a better way to stop this thing from\n"
1596 "       // 'appening.\n"
1597 "       float f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
1598 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
1599 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
1600 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
1601 "       ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
1602 "       color.rgb = mix(color.rgb, myhalf3(texture2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
1603 "#endif\n"
1604 "\n"
1605 "       gl_FragColor = vec4(color);\n"
1606 "}\n"
1607 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
1608 "#endif // !MODE_DEFERREDGEOMETRY\n"
1609 "\n"
1610 "#endif // FRAGMENT_SHADER\n"
1611 "\n"
1612 "#endif // !MODE_WATER\n"
1613 "#endif // !MODE_REFRACTION\n"
1614 "#endif // !MODE_BLOOMBLUR\n"
1615 "#endif // !MODE_GENERIC\n"
1616 "#endif // !MODE_POSTPROCESS\n"
1617 "#endif // !MODE_SHOWDEPTH\n"
1618 "#endif // !MODE_DEPTH_OR_SHADOW\n"
1619 ;
1620
1621 const char *builtincgshaderstring = "";
1622
1623 typedef struct shaderpermutationinfo_s
1624 {
1625         const char *pretext;
1626         const char *name;
1627 }
1628 shaderpermutationinfo_t;
1629
1630 typedef struct shadermodeinfo_s
1631 {
1632         const char *vertexfilename;
1633         const char *geometryfilename;
1634         const char *fragmentfilename;
1635         const char *pretext;
1636         const char *name;
1637 }
1638 shadermodeinfo_t;
1639
1640 typedef enum shaderpermutation_e
1641 {
1642         SHADERPERMUTATION_DIFFUSE = 1<<0, ///< (lightsource) whether to use directional shading
1643         SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, ///< indicates this is a two-layer material blend based on vertex alpha (q3bsp)
1644         SHADERPERMUTATION_VIEWTINT = 1<<2, ///< view tint (postprocessing only)
1645         SHADERPERMUTATION_COLORMAPPING = 1<<3, ///< indicates this is a colormapped skin
1646         SHADERPERMUTATION_SATURATION = 1<<4, ///< saturation (postprocessing only)
1647         SHADERPERMUTATION_FOGINSIDE = 1<<5, ///< tint the color by fog color or black if using additive blend mode
1648         SHADERPERMUTATION_FOGOUTSIDE = 1<<6, ///< tint the color by fog color or black if using additive blend mode
1649         SHADERPERMUTATION_GAMMARAMPS = 1<<7, ///< gamma (postprocessing only)
1650         SHADERPERMUTATION_CUBEFILTER = 1<<8, ///< (lightsource) use cubemap light filter
1651         SHADERPERMUTATION_GLOW = 1<<9, ///< (lightmap) blend in an additive glow texture
1652         SHADERPERMUTATION_BLOOM = 1<<10, ///< bloom (postprocessing only)
1653         SHADERPERMUTATION_SPECULAR = 1<<11, ///< (lightsource or deluxemapping) render specular effects
1654         SHADERPERMUTATION_POSTPROCESSING = 1<<12, ///< user defined postprocessing (postprocessing only)
1655         SHADERPERMUTATION_EXACTSPECULARMATH = 1<<13, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
1656         SHADERPERMUTATION_REFLECTION = 1<<14, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
1657         SHADERPERMUTATION_OFFSETMAPPING = 1<<15, ///< adjust texcoords to roughly simulate a displacement mapped surface
1658         SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<16, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
1659         SHADERPERMUTATION_SHADOWMAPRECT = 1<<17, ///< (lightsource) use shadowmap rectangle texture as light filter
1660         SHADERPERMUTATION_SHADOWMAPCUBE = 1<<18, ///< (lightsource) use shadowmap cubemap texture as light filter
1661         SHADERPERMUTATION_SHADOWMAP2D = 1<<19, ///< (lightsource) use shadowmap rectangle texture as light filter
1662         SHADERPERMUTATION_SHADOWMAPPCF = 1<<20, ///< (lightsource) use percentage closer filtering on shadowmap test results
1663         SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<21, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
1664         SHADERPERMUTATION_SHADOWSAMPLER = 1<<22, ///< (lightsource) use hardware shadowmap test
1665         SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<23, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
1666         SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<24, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
1667         SHADERPERMUTATION_ALPHAKILL = 1<<25, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
1668         SHADERPERMUTATION_LIMIT = 1<<26, ///< size of permutations array
1669         SHADERPERMUTATION_COUNT = 27 ///< size of shaderpermutationinfo array
1670 }
1671 shaderpermutation_t;
1672
1673 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
1674 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
1675 {
1676         {"#define USEDIFFUSE\n", " diffuse"},
1677         {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
1678         {"#define USEVIEWTINT\n", " viewtint"},
1679         {"#define USECOLORMAPPING\n", " colormapping"},
1680         {"#define USESATURATION\n", " saturation"},
1681         {"#define USEFOGINSIDE\n", " foginside"},
1682         {"#define USEFOGOUTSIDE\n", " fogoutside"},
1683         {"#define USEGAMMARAMPS\n", " gammaramps"},
1684         {"#define USECUBEFILTER\n", " cubefilter"},
1685         {"#define USEGLOW\n", " glow"},
1686         {"#define USEBLOOM\n", " bloom"},
1687         {"#define USESPECULAR\n", " specular"},
1688         {"#define USEPOSTPROCESSING\n", " postprocessing"},
1689         {"#define USEEXACTSPECULARMATH\n", " exactspecularmath"},
1690         {"#define USEREFLECTION\n", " reflection"},
1691         {"#define USEOFFSETMAPPING\n", " offsetmapping"},
1692         {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
1693         {"#define USESHADOWMAPRECT\n", " shadowmaprect"},
1694         {"#define USESHADOWMAPCUBE\n", " shadowmapcube"},
1695         {"#define USESHADOWMAP2D\n", " shadowmap2d"},
1696         {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"},
1697         {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"},
1698         {"#define USESHADOWSAMPLER\n", " shadowsampler"},
1699         {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"},
1700         {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
1701         {"#define USEALPHAKILL\n", " alphakill"},
1702 };
1703
1704 /// this enum is multiplied by SHADERPERMUTATION_MODEBASE
1705 typedef enum shadermode_e
1706 {
1707         SHADERMODE_GENERIC, ///< (particles/HUD/etc) vertex color, optionally multiplied by one texture
1708         SHADERMODE_POSTPROCESS, ///< postprocessing shader (r_glsl_postprocess)
1709         SHADERMODE_DEPTH_OR_SHADOW, ///< (depthfirst/shadows) vertex shader only
1710         SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp)
1711         SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp)
1712         SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp)
1713         SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap)
1714         SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap)
1715         SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp)
1716         SHADERMODE_LIGHTSOURCE, ///< (lightsource) use directional pixel shading from light source (rtlight)
1717         SHADERMODE_REFRACTION, ///< refract background (the material is rendered normally after this pass)
1718         SHADERMODE_WATER, ///< refract background and reflection (the material is rendered normally after this pass)
1719         SHADERMODE_SHOWDEPTH, ///< (debugging) renders depth as color
1720         SHADERMODE_DEFERREDGEOMETRY, ///< (deferred) render material properties to screenspace geometry buffers
1721         SHADERMODE_DEFERREDLIGHTSOURCE, ///< (deferred) use directional pixel shading from light source (rtlight) on screenspace geometry buffers
1722         SHADERMODE_COUNT
1723 }
1724 shadermode_t;
1725
1726 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
1727 shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
1728 {
1729         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
1730         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
1731         {"glsl/default.glsl", NULL, NULL               , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
1732         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
1733         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
1734         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
1735         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
1736         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
1737         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
1738         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
1739         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
1740         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_WATER\n", " water"},
1741         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
1742         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
1743         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
1744 };
1745
1746 #ifdef SUPPORTCG
1747 shadermodeinfo_t cgshadermodeinfo[SHADERMODE_COUNT] =
1748 {
1749         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_GENERIC\n", " generic"},
1750         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_POSTPROCESS\n", " postprocess"},
1751         {"cg/default.cg", NULL, NULL           , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
1752         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FLATCOLOR\n", " flatcolor"},
1753         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
1754         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTMAP\n", " lightmap"},
1755         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
1756         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
1757         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
1758         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTSOURCE\n", " lightsource"},
1759         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_REFRACTION\n", " refraction"},
1760         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_WATER\n", " water"},
1761         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_SHOWDEPTH\n", " showdepth"},
1762         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
1763         {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
1764 };
1765 #endif
1766
1767 struct r_glsl_permutation_s;
1768 typedef struct r_glsl_permutation_s
1769 {
1770         /// hash lookup data
1771         struct r_glsl_permutation_s *hashnext;
1772         unsigned int mode;
1773         unsigned int permutation;
1774
1775         /// indicates if we have tried compiling this permutation already
1776         qboolean compiled;
1777         /// 0 if compilation failed
1778         int program;
1779         /// locations of detected uniforms in program object, or -1 if not found
1780         int loc_Texture_First;
1781         int loc_Texture_Second;
1782         int loc_Texture_GammaRamps;
1783         int loc_Texture_Normal;
1784         int loc_Texture_Color;
1785         int loc_Texture_Gloss;
1786         int loc_Texture_Glow;
1787         int loc_Texture_SecondaryNormal;
1788         int loc_Texture_SecondaryColor;
1789         int loc_Texture_SecondaryGloss;
1790         int loc_Texture_SecondaryGlow;
1791         int loc_Texture_Pants;
1792         int loc_Texture_Shirt;
1793         int loc_Texture_FogMask;
1794         int loc_Texture_Lightmap;
1795         int loc_Texture_Deluxemap;
1796         int loc_Texture_Attenuation;
1797         int loc_Texture_Cube;
1798         int loc_Texture_Refraction;
1799         int loc_Texture_Reflection;
1800         int loc_Texture_ShadowMapRect;
1801         int loc_Texture_ShadowMapCube;
1802         int loc_Texture_ShadowMap2D;
1803         int loc_Texture_CubeProjection;
1804         int loc_Texture_ScreenDepth;
1805         int loc_Texture_ScreenNormalMap;
1806         int loc_Texture_ScreenDiffuse;
1807         int loc_Texture_ScreenSpecular;
1808         int loc_Alpha;
1809         int loc_BloomBlur_Parameters;
1810         int loc_ClientTime;
1811         int loc_Color_Ambient;
1812         int loc_Color_Diffuse;
1813         int loc_Color_Specular;
1814         int loc_Color_Glow;
1815         int loc_Color_Pants;
1816         int loc_Color_Shirt;
1817         int loc_DeferredColor_Ambient;
1818         int loc_DeferredColor_Diffuse;
1819         int loc_DeferredColor_Specular;
1820         int loc_DeferredMod_Diffuse;
1821         int loc_DeferredMod_Specular;
1822         int loc_DistortScaleRefractReflect;
1823         int loc_EyePosition;
1824         int loc_FogColor;
1825         int loc_FogHeightFade;
1826         int loc_FogPlane;
1827         int loc_FogPlaneViewDist;
1828         int loc_FogRangeRecip;
1829         int loc_LightColor;
1830         int loc_LightDir;
1831         int loc_LightPosition;
1832         int loc_OffsetMapping_Scale;
1833         int loc_PixelSize;
1834         int loc_ReflectColor;
1835         int loc_ReflectFactor;
1836         int loc_ReflectOffset;
1837         int loc_RefractColor;
1838         int loc_Saturation;
1839         int loc_ScreenCenterRefractReflect;
1840         int loc_ScreenScaleRefractReflect;
1841         int loc_ScreenToDepth;
1842         int loc_ShadowMap_Parameters;
1843         int loc_ShadowMap_TextureScale;
1844         int loc_SpecularPower;
1845         int loc_UserVec1;
1846         int loc_UserVec2;
1847         int loc_UserVec3;
1848         int loc_UserVec4;
1849         int loc_ViewTintColor;
1850         int loc_ViewToLight;
1851         int loc_ModelToLight;
1852         int loc_TexMatrix;
1853         int loc_BackgroundTexMatrix;
1854         int loc_ModelViewProjectionMatrix;
1855         int loc_ModelViewMatrix;
1856 }
1857 r_glsl_permutation_t;
1858
1859 #define SHADERPERMUTATION_HASHSIZE 256
1860
1861 /// information about each possible shader permutation
1862 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
1863 /// currently selected permutation
1864 r_glsl_permutation_t *r_glsl_permutation;
1865 /// storage for permutations linked in the hash table
1866 memexpandablearray_t r_glsl_permutationarray;
1867
1868 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation)
1869 {
1870         //unsigned int hashdepth = 0;
1871         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
1872         r_glsl_permutation_t *p;
1873         for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1874         {
1875                 if (p->mode == mode && p->permutation == permutation)
1876                 {
1877                         //if (hashdepth > 10)
1878                         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1879                         return p;
1880                 }
1881                 //hashdepth++;
1882         }
1883         p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
1884         p->mode = mode;
1885         p->permutation = permutation;
1886         p->hashnext = r_glsl_permutationhash[mode][hashindex];
1887         r_glsl_permutationhash[mode][hashindex] = p;
1888         //if (hashdepth > 10)
1889         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1890         return p;
1891 }
1892
1893 static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice)
1894 {
1895         char *shaderstring;
1896         if (!filename || !filename[0])
1897                 return NULL;
1898         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1899         if (shaderstring)
1900         {
1901                 if (printfromdisknotice)
1902                         Con_DPrintf("from disk %s... ", filename);
1903                 return shaderstring;
1904         }
1905         else if (!strcmp(filename, "glsl/default.glsl"))
1906         {
1907                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(builtinshaderstring) + 1);
1908                 memcpy(shaderstring, builtinshaderstring, strlen(builtinshaderstring) + 1);
1909         }
1910         return shaderstring;
1911 }
1912
1913 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1914 {
1915         int i;
1916         shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
1917         int vertstrings_count = 0;
1918         int geomstrings_count = 0;
1919         int fragstrings_count = 0;
1920         char *vertexstring, *geometrystring, *fragmentstring;
1921         const char *vertstrings_list[32+3];
1922         const char *geomstrings_list[32+3];
1923         const char *fragstrings_list[32+3];
1924         char permutationname[256];
1925
1926         if (p->compiled)
1927                 return;
1928         p->compiled = true;
1929         p->program = 0;
1930
1931         permutationname[0] = 0;
1932         vertexstring   = R_GLSL_GetText(modeinfo->vertexfilename, true);
1933         geometrystring = R_GLSL_GetText(modeinfo->geometryfilename, false);
1934         fragmentstring = R_GLSL_GetText(modeinfo->fragmentfilename, false);
1935
1936         strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
1937
1938         // the first pretext is which type of shader to compile as
1939         // (later these will all be bound together as a program object)
1940         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1941         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1942         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1943
1944         // the second pretext is the mode (for example a light source)
1945         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1946         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1947         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1948         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1949
1950         // now add all the permutation pretexts
1951         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1952         {
1953                 if (permutation & (1<<i))
1954                 {
1955                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1956                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1957                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1958                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1959                 }
1960                 else
1961                 {
1962                         // keep line numbers correct
1963                         vertstrings_list[vertstrings_count++] = "\n";
1964                         geomstrings_list[geomstrings_count++] = "\n";
1965                         fragstrings_list[fragstrings_count++] = "\n";
1966                 }
1967         }
1968
1969         // now append the shader text itself
1970         vertstrings_list[vertstrings_count++] = vertexstring;
1971         geomstrings_list[geomstrings_count++] = geometrystring;
1972         fragstrings_list[fragstrings_count++] = fragmentstring;
1973
1974         // if any sources were NULL, clear the respective list
1975         if (!vertexstring)
1976                 vertstrings_count = 0;
1977         if (!geometrystring)
1978                 geomstrings_count = 0;
1979         if (!fragmentstring)
1980                 fragstrings_count = 0;
1981
1982         // compile the shader program
1983         if (vertstrings_count + geomstrings_count + fragstrings_count)
1984                 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1985         if (p->program)
1986         {
1987                 CHECKGLERROR
1988                 qglUseProgramObjectARB(p->program);CHECKGLERROR
1989                 // look up all the uniform variable names we care about, so we don't
1990                 // have to look them up every time we set them
1991
1992                 p->loc_Texture_First              = qglGetUniformLocationARB(p->program, "Texture_First");
1993                 p->loc_Texture_Second             = qglGetUniformLocationARB(p->program, "Texture_Second");
1994                 p->loc_Texture_GammaRamps         = qglGetUniformLocationARB(p->program, "Texture_GammaRamps");
1995                 p->loc_Texture_Normal             = qglGetUniformLocationARB(p->program, "Texture_Normal");
1996                 p->loc_Texture_Color              = qglGetUniformLocationARB(p->program, "Texture_Color");
1997                 p->loc_Texture_Gloss              = qglGetUniformLocationARB(p->program, "Texture_Gloss");
1998                 p->loc_Texture_Glow               = qglGetUniformLocationARB(p->program, "Texture_Glow");
1999                 p->loc_Texture_SecondaryNormal    = qglGetUniformLocationARB(p->program, "Texture_SecondaryNormal");
2000                 p->loc_Texture_SecondaryColor     = qglGetUniformLocationARB(p->program, "Texture_SecondaryColor");
2001                 p->loc_Texture_SecondaryGloss     = qglGetUniformLocationARB(p->program, "Texture_SecondaryGloss");
2002                 p->loc_Texture_SecondaryGlow      = qglGetUniformLocationARB(p->program, "Texture_SecondaryGlow");
2003                 p->loc_Texture_Pants              = qglGetUniformLocationARB(p->program, "Texture_Pants");
2004                 p->loc_Texture_Shirt              = qglGetUniformLocationARB(p->program, "Texture_Shirt");
2005                 p->loc_Texture_FogMask            = qglGetUniformLocationARB(p->program, "Texture_FogMask");
2006                 p->loc_Texture_Lightmap           = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
2007                 p->loc_Texture_Deluxemap          = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
2008                 p->loc_Texture_Attenuation        = qglGetUniformLocationARB(p->program, "Texture_Attenuation");
2009                 p->loc_Texture_Cube               = qglGetUniformLocationARB(p->program, "Texture_Cube");
2010                 p->loc_Texture_Refraction         = qglGetUniformLocationARB(p->program, "Texture_Refraction");
2011                 p->loc_Texture_Reflection         = qglGetUniformLocationARB(p->program, "Texture_Reflection");
2012                 p->loc_Texture_ShadowMapRect      = qglGetUniformLocationARB(p->program, "Texture_ShadowMapRect");
2013                 p->loc_Texture_ShadowMapCube      = qglGetUniformLocationARB(p->program, "Texture_ShadowMapCube");
2014                 p->loc_Texture_ShadowMap2D        = qglGetUniformLocationARB(p->program, "Texture_ShadowMap2D");
2015                 p->loc_Texture_CubeProjection     = qglGetUniformLocationARB(p->program, "Texture_CubeProjection");
2016                 p->loc_Texture_ScreenDepth        = qglGetUniformLocationARB(p->program, "Texture_ScreenDepth");
2017                 p->loc_Texture_ScreenNormalMap    = qglGetUniformLocationARB(p->program, "Texture_ScreenNormalMap");
2018                 p->loc_Texture_ScreenDiffuse      = qglGetUniformLocationARB(p->program, "Texture_ScreenDiffuse");
2019                 p->loc_Texture_ScreenSpecular     = qglGetUniformLocationARB(p->program, "Texture_ScreenSpecular");
2020                 p->loc_Alpha                      = qglGetUniformLocationARB(p->program, "Alpha");
2021                 p->loc_BloomBlur_Parameters       = qglGetUniformLocationARB(p->program, "BloomBlur_Parameters");
2022                 p->loc_ClientTime                 = qglGetUniformLocationARB(p->program, "ClientTime");
2023                 p->loc_Color_Ambient              = qglGetUniformLocationARB(p->program, "Color_Ambient");
2024                 p->loc_Color_Diffuse              = qglGetUniformLocationARB(p->program, "Color_Diffuse");
2025                 p->loc_Color_Specular             = qglGetUniformLocationARB(p->program, "Color_Specular");
2026                 p->loc_Color_Glow                 = qglGetUniformLocationARB(p->program, "Color_Glow");
2027                 p->loc_Color_Pants                = qglGetUniformLocationARB(p->program, "Color_Pants");
2028                 p->loc_Color_Shirt                = qglGetUniformLocationARB(p->program, "Color_Shirt");
2029                 p->loc_DeferredColor_Ambient      = qglGetUniformLocationARB(p->program, "DeferredColor_Ambient");
2030                 p->loc_DeferredColor_Diffuse      = qglGetUniformLocationARB(p->program, "DeferredColor_Diffuse");
2031                 p->loc_DeferredColor_Specular     = qglGetUniformLocationARB(p->program, "DeferredColor_Specular");
2032                 p->loc_DeferredMod_Diffuse        = qglGetUniformLocationARB(p->program, "DeferredMod_Diffuse");
2033                 p->loc_DeferredMod_Specular       = qglGetUniformLocationARB(p->program, "DeferredMod_Specular");
2034                 p->loc_DistortScaleRefractReflect = qglGetUniformLocationARB(p->program, "DistortScaleRefractReflect");
2035                 p->loc_EyePosition                = qglGetUniformLocationARB(p->program, "EyePosition");
2036                 p->loc_FogColor                   = qglGetUniformLocationARB(p->program, "FogColor");
2037                 p->loc_FogHeightFade              = qglGetUniformLocationARB(p->program, "FogHeightFade");
2038                 p->loc_FogPlane                   = qglGetUniformLocationARB(p->program, "FogPlane");
2039                 p->loc_FogPlaneViewDist           = qglGetUniformLocationARB(p->program, "FogPlaneViewDist");
2040                 p->loc_FogRangeRecip              = qglGetUniformLocationARB(p->program, "FogRangeRecip");
2041                 p->loc_LightColor                 = qglGetUniformLocationARB(p->program, "LightColor");
2042                 p->loc_LightDir                   = qglGetUniformLocationARB(p->program, "LightDir");
2043                 p->loc_LightPosition              = qglGetUniformLocationARB(p->program, "LightPosition");
2044                 p->loc_OffsetMapping_Scale        = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
2045                 p->loc_PixelSize                  = qglGetUniformLocationARB(p->program, "PixelSize");
2046                 p->loc_ReflectColor               = qglGetUniformLocationARB(p->program, "ReflectColor");
2047                 p->loc_ReflectFactor              = qglGetUniformLocationARB(p->program, "ReflectFactor");
2048                 p->loc_ReflectOffset              = qglGetUniformLocationARB(p->program, "ReflectOffset");
2049                 p->loc_RefractColor               = qglGetUniformLocationARB(p->program, "RefractColor");
2050                 p->loc_Saturation                 = qglGetUniformLocationARB(p->program, "Saturation");
2051                 p->loc_ScreenCenterRefractReflect = qglGetUniformLocationARB(p->program, "ScreenCenterRefractReflect");
2052                 p->loc_ScreenScaleRefractReflect  = qglGetUniformLocationARB(p->program, "ScreenScaleRefractReflect");
2053                 p->loc_ScreenToDepth              = qglGetUniformLocationARB(p->program, "ScreenToDepth");
2054                 p->loc_ShadowMap_Parameters       = qglGetUniformLocationARB(p->program, "ShadowMap_Parameters");
2055                 p->loc_ShadowMap_TextureScale     = qglGetUniformLocationARB(p->program, "ShadowMap_TextureScale");
2056                 p->loc_SpecularPower              = qglGetUniformLocationARB(p->program, "SpecularPower");
2057                 p->loc_UserVec1                   = qglGetUniformLocationARB(p->program, "UserVec1");
2058                 p->loc_UserVec2                   = qglGetUniformLocationARB(p->program, "UserVec2");
2059                 p->loc_UserVec3                   = qglGetUniformLocationARB(p->program, "UserVec3");
2060                 p->loc_UserVec4                   = qglGetUniformLocationARB(p->program, "UserVec4");
2061                 p->loc_ViewTintColor              = qglGetUniformLocationARB(p->program, "ViewTintColor");
2062                 p->loc_ViewToLight                = qglGetUniformLocationARB(p->program, "ViewToLight");
2063                 p->loc_ModelToLight               = qglGetUniformLocationARB(p->program, "ModelToLight");
2064                 p->loc_TexMatrix                  = qglGetUniformLocationARB(p->program, "TexMatrix");
2065                 p->loc_BackgroundTexMatrix        = qglGetUniformLocationARB(p->program, "BackgroundTexMatrix");
2066                 p->loc_ModelViewMatrix            = qglGetUniformLocationARB(p->program, "ModelViewMatrix");
2067                 p->loc_ModelViewProjectionMatrix  = qglGetUniformLocationARB(p->program, "ModelViewProjectionMatrix");
2068                 // initialize the samplers to refer to the texture units we use
2069                 if (p->loc_Texture_First           >= 0) qglUniform1iARB(p->loc_Texture_First          , GL20TU_FIRST);
2070                 if (p->loc_Texture_Second          >= 0) qglUniform1iARB(p->loc_Texture_Second         , GL20TU_SECOND);
2071                 if (p->loc_Texture_GammaRamps      >= 0) qglUniform1iARB(p->loc_Texture_GammaRamps     , GL20TU_GAMMARAMPS);
2072                 if (p->loc_Texture_Normal          >= 0) qglUniform1iARB(p->loc_Texture_Normal         , GL20TU_NORMAL);
2073                 if (p->loc_Texture_Color           >= 0) qglUniform1iARB(p->loc_Texture_Color          , GL20TU_COLOR);
2074                 if (p->loc_Texture_Gloss           >= 0) qglUniform1iARB(p->loc_Texture_Gloss          , GL20TU_GLOSS);
2075                 if (p->loc_Texture_Glow            >= 0) qglUniform1iARB(p->loc_Texture_Glow           , GL20TU_GLOW);
2076                 if (p->loc_Texture_SecondaryNormal >= 0) qglUniform1iARB(p->loc_Texture_SecondaryNormal, GL20TU_SECONDARY_NORMAL);
2077                 if (p->loc_Texture_SecondaryColor  >= 0) qglUniform1iARB(p->loc_Texture_SecondaryColor , GL20TU_SECONDARY_COLOR);
2078                 if (p->loc_Texture_SecondaryGloss  >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGloss , GL20TU_SECONDARY_GLOSS);
2079                 if (p->loc_Texture_SecondaryGlow   >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGlow  , GL20TU_SECONDARY_GLOW);
2080                 if (p->loc_Texture_Pants           >= 0) qglUniform1iARB(p->loc_Texture_Pants          , GL20TU_PANTS);
2081                 if (p->loc_Texture_Shirt           >= 0) qglUniform1iARB(p->loc_Texture_Shirt          , GL20TU_SHIRT);
2082                 if (p->loc_Texture_FogMask         >= 0) qglUniform1iARB(p->loc_Texture_FogMask        , GL20TU_FOGMASK);
2083                 if (p->loc_Texture_Lightmap        >= 0) qglUniform1iARB(p->loc_Texture_Lightmap       , GL20TU_LIGHTMAP);
2084                 if (p->loc_Texture_Deluxemap       >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap      , GL20TU_DELUXEMAP);
2085                 if (p->loc_Texture_Attenuation     >= 0) qglUniform1iARB(p->loc_Texture_Attenuation    , GL20TU_ATTENUATION);
2086                 if (p->loc_Texture_Cube            >= 0) qglUniform1iARB(p->loc_Texture_Cube           , GL20TU_CUBE);
2087                 if (p->loc_Texture_Refraction      >= 0) qglUniform1iARB(p->loc_Texture_Refraction     , GL20TU_REFRACTION);
2088                 if (p->loc_Texture_Reflection      >= 0) qglUniform1iARB(p->loc_Texture_Reflection     , GL20TU_REFLECTION);
2089                 if (p->loc_Texture_ShadowMapRect   >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapRect  , GL20TU_SHADOWMAPRECT);
2090                 if (p->loc_Texture_ShadowMapCube   >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapCube  , GL20TU_SHADOWMAPCUBE);
2091                 if (p->loc_Texture_ShadowMap2D     >= 0) qglUniform1iARB(p->loc_Texture_ShadowMap2D    , GL20TU_SHADOWMAP2D);
2092                 if (p->loc_Texture_CubeProjection  >= 0) qglUniform1iARB(p->loc_Texture_CubeProjection , GL20TU_CUBEPROJECTION);
2093                 if (p->loc_Texture_ScreenDepth     >= 0) qglUniform1iARB(p->loc_Texture_ScreenDepth    , GL20TU_SCREENDEPTH);
2094                 if (p->loc_Texture_ScreenNormalMap >= 0) qglUniform1iARB(p->loc_Texture_ScreenNormalMap, GL20TU_SCREENNORMALMAP);
2095                 if (p->loc_Texture_ScreenDiffuse   >= 0) qglUniform1iARB(p->loc_Texture_ScreenDiffuse  , GL20TU_SCREENDIFFUSE);
2096                 if (p->loc_Texture_ScreenSpecular  >= 0) qglUniform1iARB(p->loc_Texture_ScreenSpecular , GL20TU_SCREENSPECULAR);
2097                 CHECKGLERROR
2098                 if (developer.integer)
2099                         Con_Printf("^5GLSL shader %s compiled.\n", permutationname);
2100         }
2101         else
2102                 Con_Printf("^1GLSL shader %s failed!  some features may not work properly.\n", permutationname);
2103
2104         // free the strings
2105         if (vertexstring)
2106                 Mem_Free(vertexstring);
2107         if (geometrystring)
2108                 Mem_Free(geometrystring);
2109         if (fragmentstring)
2110                 Mem_Free(fragmentstring);
2111 }
2112
2113 void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
2114 {
2115         r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
2116         if (r_glsl_permutation != perm)
2117         {
2118                 r_glsl_permutation = perm;
2119                 if (!r_glsl_permutation->program)
2120                 {
2121                         if (!r_glsl_permutation->compiled)
2122                                 R_GLSL_CompilePermutation(perm, mode, permutation);
2123                         if (!r_glsl_permutation->program)
2124                         {
2125                                 // remove features until we find a valid permutation
2126                                 int i;
2127                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2128                                 {
2129                                         // reduce i more quickly whenever it would not remove any bits
2130                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
2131                                         if (!(permutation & j))
2132                                                 continue;
2133                                         permutation -= j;
2134                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
2135                                         if (!r_glsl_permutation->compiled)
2136                                                 R_GLSL_CompilePermutation(perm, mode, permutation);
2137                                         if (r_glsl_permutation->program)
2138                                                 break;
2139                                 }
2140                                 if (i >= SHADERPERMUTATION_COUNT)
2141                                 {
2142                                         //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
2143                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
2144                                         qglUseProgramObjectARB(0);CHECKGLERROR
2145                                         return; // no bit left to clear, entire mode is broken
2146                                 }
2147                         }
2148                 }
2149                 CHECKGLERROR
2150                 qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
2151         }
2152         if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
2153 }
2154
2155 #ifdef SUPPORTCG
2156 #include <Cg/cgGL.h>
2157 struct r_cg_permutation_s;
2158 typedef struct r_cg_permutation_s
2159 {
2160         /// hash lookup data
2161         struct r_cg_permutation_s *hashnext;
2162         unsigned int mode;
2163         unsigned int permutation;
2164
2165         /// indicates if we have tried compiling this permutation already
2166         qboolean compiled;
2167         /// 0 if compilation failed
2168         CGprogram vprogram;
2169         CGprogram fprogram;
2170         /// locations of detected parameters in programs, or NULL if not found
2171         CGparameter vp_EyePosition;
2172         CGparameter vp_FogPlane;
2173         CGparameter vp_LightDir;
2174         CGparameter vp_LightPosition;
2175         CGparameter vp_ModelToLight;
2176         CGparameter vp_TexMatrix;
2177         CGparameter vp_BackgroundTexMatrix;
2178         CGparameter vp_ModelViewProjectionMatrix;
2179         CGparameter vp_ModelViewMatrix;
2180
2181         CGparameter fp_Texture_First;
2182         CGparameter fp_Texture_Second;
2183         CGparameter fp_Texture_GammaRamps;
2184         CGparameter fp_Texture_Normal;
2185         CGparameter fp_Texture_Color;
2186         CGparameter fp_Texture_Gloss;
2187         CGparameter fp_Texture_Glow;
2188         CGparameter fp_Texture_SecondaryNormal;
2189         CGparameter fp_Texture_SecondaryColor;
2190         CGparameter fp_Texture_SecondaryGloss;
2191         CGparameter fp_Texture_SecondaryGlow;
2192         CGparameter fp_Texture_Pants;
2193         CGparameter fp_Texture_Shirt;
2194         CGparameter fp_Texture_FogMask;
2195         CGparameter fp_Texture_Lightmap;
2196         CGparameter fp_Texture_Deluxemap;
2197         CGparameter fp_Texture_Attenuation;
2198         CGparameter fp_Texture_Cube;
2199         CGparameter fp_Texture_Refraction;
2200         CGparameter fp_Texture_Reflection;
2201         CGparameter fp_Texture_ShadowMapRect;
2202         CGparameter fp_Texture_ShadowMapCube;
2203         CGparameter fp_Texture_ShadowMap2D;
2204         CGparameter fp_Texture_CubeProjection;
2205         CGparameter fp_Texture_ScreenDepth;
2206         CGparameter fp_Texture_ScreenNormalMap;
2207         CGparameter fp_Texture_ScreenDiffuse;
2208         CGparameter fp_Texture_ScreenSpecular;
2209         CGparameter fp_Alpha;
2210         CGparameter fp_BloomBlur_Parameters;
2211         CGparameter fp_ClientTime;
2212         CGparameter fp_Color_Ambient;
2213         CGparameter fp_Color_Diffuse;
2214         CGparameter fp_Color_Specular;
2215         CGparameter fp_Color_Glow;
2216         CGparameter fp_Color_Pants;
2217         CGparameter fp_Color_Shirt;
2218         CGparameter fp_DeferredColor_Ambient;
2219         CGparameter fp_DeferredColor_Diffuse;
2220         CGparameter fp_DeferredColor_Specular;
2221         CGparameter fp_DeferredMod_Diffuse;
2222         CGparameter fp_DeferredMod_Specular;
2223         CGparameter fp_DistortScaleRefractReflect;
2224         CGparameter fp_EyePosition;
2225         CGparameter fp_FogColor;
2226         CGparameter fp_FogHeightFade;
2227         CGparameter fp_FogPlane;
2228         CGparameter fp_FogPlaneViewDist;
2229         CGparameter fp_FogRangeRecip;
2230         CGparameter fp_LightColor;
2231         CGparameter fp_LightDir;
2232         CGparameter fp_LightPosition;
2233         CGparameter fp_OffsetMapping_Scale;
2234         CGparameter fp_PixelSize;
2235         CGparameter fp_ReflectColor;
2236         CGparameter fp_ReflectFactor;
2237         CGparameter fp_ReflectOffset;
2238         CGparameter fp_RefractColor;
2239         CGparameter fp_Saturation;
2240         CGparameter fp_ScreenCenterRefractReflect;
2241         CGparameter fp_ScreenScaleRefractReflect;
2242         CGparameter fp_ScreenToDepth;
2243         CGparameter fp_ShadowMap_Parameters;
2244         CGparameter fp_ShadowMap_TextureScale;
2245         CGparameter fp_SpecularPower;
2246         CGparameter fp_UserVec1;
2247         CGparameter fp_UserVec2;
2248         CGparameter fp_UserVec3;
2249         CGparameter fp_UserVec4;
2250         CGparameter fp_ViewTintColor;
2251         CGparameter fp_ViewToLight;
2252 }
2253 r_cg_permutation_t;
2254
2255 /// information about each possible shader permutation
2256 r_cg_permutation_t *r_cg_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
2257 /// currently selected permutation
2258 r_cg_permutation_t *r_cg_permutation;
2259 /// storage for permutations linked in the hash table
2260 memexpandablearray_t r_cg_permutationarray;
2261
2262 static r_cg_permutation_t *R_CG_FindPermutation(unsigned int mode, unsigned int permutation)
2263 {
2264         //unsigned int hashdepth = 0;
2265         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
2266         r_cg_permutation_t *p;
2267         for (p = r_cg_permutationhash[mode][hashindex];p;p = p->hashnext)
2268         {
2269                 if (p->mode == mode && p->permutation == permutation)
2270                 {
2271                         //if (hashdepth > 10)
2272                         //      Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
2273                         return p;
2274                 }
2275                 //hashdepth++;
2276         }
2277         p = (r_cg_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_cg_permutationarray);
2278         p->mode = mode;
2279         p->permutation = permutation;
2280         p->hashnext = r_cg_permutationhash[mode][hashindex];
2281         r_cg_permutationhash[mode][hashindex] = p;
2282         //if (hashdepth > 10)
2283         //      Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
2284         return p;
2285 }
2286
2287 static char *R_CG_GetText(const char *filename, qboolean printfromdisknotice)
2288 {
2289         char *shaderstring;
2290         if (!filename || !filename[0])
2291                 return NULL;
2292         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
2293         if (shaderstring)
2294         {
2295                 if (printfromdisknotice)
2296                         Con_DPrintf("from disk %s... ", filename);
2297                 return shaderstring;
2298         }
2299         else if (!strcmp(filename, "cg/default.cg"))
2300         {
2301                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(builtincgshaderstring) + 1);
2302                 memcpy(shaderstring, builtincgshaderstring, strlen(builtincgshaderstring) + 1);
2303         }
2304         return shaderstring;
2305 }
2306
2307 static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, unsigned int permutation)
2308 {
2309         int i;
2310         shadermodeinfo_t *modeinfo = cgshadermodeinfo + mode;
2311         int vertstrings_count = 0, vertstring_length = 0;
2312         int geomstrings_count = 0, geomstring_length = 0;
2313         int fragstrings_count = 0, fragstring_length = 0;
2314         char *t;
2315         char *vertexstring, *geometrystring, *fragmentstring;
2316         char *vertstring, *geomstring, *fragstring;
2317         const char *vertstrings_list[32+3];
2318         const char *geomstrings_list[32+3];
2319         const char *fragstrings_list[32+3];
2320         char permutationname[256];
2321
2322         if (p->compiled)
2323                 return;
2324         p->compiled = true;
2325         p->vprogram = NULL;
2326         p->fprogram = NULL;
2327
2328         permutationname[0] = 0;
2329         vertexstring   = R_CG_GetText(modeinfo->vertexfilename, true);
2330         geometrystring = R_CG_GetText(modeinfo->geometryfilename, false);
2331         fragmentstring = R_CG_GetText(modeinfo->fragmentfilename, false);
2332
2333         strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
2334
2335         // the first pretext is which type of shader to compile as
2336         // (later these will all be bound together as a program object)
2337         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
2338         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
2339         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
2340
2341         // the second pretext is the mode (for example a light source)
2342         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
2343         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
2344         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
2345         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
2346
2347         // now add all the permutation pretexts
2348         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2349         {
2350                 if (permutation & (1<<i))
2351                 {
2352                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
2353                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
2354                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
2355                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
2356                 }
2357                 else
2358                 {
2359                         // keep line numbers correct
2360                         vertstrings_list[vertstrings_count++] = "\n";
2361                         geomstrings_list[geomstrings_count++] = "\n";
2362                         fragstrings_list[fragstrings_count++] = "\n";
2363                 }
2364         }
2365
2366         // now append the shader text itself
2367         vertstrings_list[vertstrings_count++] = vertexstring;
2368         geomstrings_list[geomstrings_count++] = geometrystring;
2369         fragstrings_list[fragstrings_count++] = fragmentstring;
2370
2371         // if any sources were NULL, clear the respective list
2372         if (!vertexstring)
2373                 vertstrings_count = 0;
2374         if (!geometrystring)
2375                 geomstrings_count = 0;
2376         if (!fragmentstring)
2377                 fragstrings_count = 0;
2378
2379         vertstring_length = 0;
2380         for (i = 0;i < vertstrings_count;i++)
2381                 vertstring_length += strlen(vertstrings_list[i]);
2382         vertstring = t = Mem_Alloc(tempmempool, vertstring_length + 1);
2383         for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
2384                 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
2385
2386         geomstring_length = 0;
2387         for (i = 0;i < geomstrings_count;i++)
2388                 geomstring_length += strlen(geomstrings_list[i]);
2389         geomstring = t = Mem_Alloc(tempmempool, geomstring_length + 1);
2390         for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
2391                 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
2392
2393         fragstring_length = 0;
2394         for (i = 0;i < fragstrings_count;i++)
2395                 fragstring_length += strlen(fragstrings_list[i]);
2396         fragstring = t = Mem_Alloc(tempmempool, fragstring_length + 1);
2397         for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
2398                 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
2399
2400         // compile the shader program
2401         if (vertstring[0] || geomstring[0] || fragstring[0])
2402         {
2403                 if (vertstring[0])
2404                         p->vprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, vertstring, CG_PROFILE_ARBVP1, NULL, NULL);
2405                 if (fragstring[0])
2406                         p->fprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, fragstring, CG_PROFILE_ARBFP1, NULL, NULL);
2407         }
2408
2409         if (p->vprogram)
2410         {
2411                 cgGLBindProgram(p->vprogram);
2412                 cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));
2413         }
2414         else
2415                 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));
2416         if (p->fprogram)
2417         {
2418                 cgGLBindProgram(p->fprogram);
2419                 cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));
2420         }
2421         else
2422                 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));
2423
2424         if (p->vprogram || p->fprogram)
2425         {
2426                 // look up all the uniform variable names we care about, so we don't
2427                 // have to look them up every time we set them
2428                 p->vp_EyePosition                = cgGetNamedParameter(p->vprogram, "EyePosition");
2429                 p->vp_FogPlane                   = cgGetNamedParameter(p->vprogram, "FogPlane");
2430                 p->vp_LightDir                   = cgGetNamedParameter(p->vprogram, "LightDir");
2431                 p->vp_LightPosition              = cgGetNamedParameter(p->vprogram, "LightPosition");
2432                 p->vp_ModelToLight               = cgGetNamedParameter(p->vprogram, "ModelToLight");
2433                 p->vp_TexMatrix                  = cgGetNamedParameter(p->vprogram, "TexMatrix");
2434                 p->vp_BackgroundTexMatrix        = cgGetNamedParameter(p->vprogram, "BackgroundTexMatrix");
2435                 p->vp_ModelViewProjectionMatrix  = cgGetNamedParameter(p->vprogram, "ModelViewProjectionMatrix");
2436                 p->vp_ModelViewMatrix            = cgGetNamedParameter(p->vprogram, "ModelViewMatrix");
2437
2438                 p->fp_Texture_First              = cgGetNamedParameter(p->fprogram, "Texture_First");
2439                 p->fp_Texture_Second             = cgGetNamedParameter(p->fprogram, "Texture_Second");
2440                 p->fp_Texture_GammaRamps         = cgGetNamedParameter(p->fprogram, "Texture_GammaRamps");
2441                 p->fp_Texture_Normal             = cgGetNamedParameter(p->fprogram, "Texture_Normal");
2442                 p->fp_Texture_Color              = cgGetNamedParameter(p->fprogram, "Texture_Color");
2443                 p->fp_Texture_Gloss              = cgGetNamedParameter(p->fprogram, "Texture_Gloss");
2444                 p->fp_Texture_Glow               = cgGetNamedParameter(p->fprogram, "Texture_Glow");
2445                 p->fp_Texture_SecondaryNormal    = cgGetNamedParameter(p->fprogram, "Texture_SecondaryNormal");
2446                 p->fp_Texture_SecondaryColor     = cgGetNamedParameter(p->fprogram, "Texture_SecondaryColor");
2447                 p->fp_Texture_SecondaryGloss     = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGloss");
2448                 p->fp_Texture_SecondaryGlow      = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGlow");
2449                 p->fp_Texture_Pants              = cgGetNamedParameter(p->fprogram, "Texture_Pants");
2450                 p->fp_Texture_Shirt              = cgGetNamedParameter(p->fprogram, "Texture_Shirt");
2451                 p->fp_Texture_FogMask            = cgGetNamedParameter(p->fprogram, "Texture_FogMask");
2452                 p->fp_Texture_Lightmap           = cgGetNamedParameter(p->fprogram, "Texture_Lightmap");
2453                 p->fp_Texture_Deluxemap          = cgGetNamedParameter(p->fprogram, "Texture_Deluxemap");
2454                 p->fp_Texture_Attenuation        = cgGetNamedParameter(p->fprogram, "Texture_Attenuation");
2455                 p->fp_Texture_Cube               = cgGetNamedParameter(p->fprogram, "Texture_Cube");
2456                 p->fp_Texture_Refraction         = cgGetNamedParameter(p->fprogram, "Texture_Refraction");
2457                 p->fp_Texture_Reflection         = cgGetNamedParameter(p->fprogram, "Texture_Reflection");
2458                 p->fp_Texture_ShadowMapRect      = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapRect");
2459                 p->fp_Texture_ShadowMapCube      = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapCube");
2460                 p->fp_Texture_ShadowMap2D        = cgGetNamedParameter(p->fprogram, "Texture_ShadowMap2D");
2461                 p->fp_Texture_CubeProjection     = cgGetNamedParameter(p->fprogram, "Texture_CubeProjection");
2462                 p->fp_Texture_ScreenDepth        = cgGetNamedParameter(p->fprogram, "Texture_ScreenDepth");
2463                 p->fp_Texture_ScreenNormalMap    = cgGetNamedParameter(p->fprogram, "Texture_ScreenNormalMap");
2464                 p->fp_Texture_ScreenDiffuse      = cgGetNamedParameter(p->fprogram, "Texture_ScreenDiffuse");
2465                 p->fp_Texture_ScreenSpecular     = cgGetNamedParameter(p->fprogram, "Texture_ScreenSpecular");
2466                 p->fp_Alpha                      = cgGetNamedParameter(p->fprogram, "Alpha");
2467                 p->fp_BloomBlur_Parameters       = cgGetNamedParameter(p->fprogram, "BloomBlur_Parameters");
2468                 p->fp_ClientTime                 = cgGetNamedParameter(p->fprogram, "ClientTime");
2469                 p->fp_Color_Ambient              = cgGetNamedParameter(p->fprogram, "Color_Ambient");
2470                 p->fp_Color_Diffuse              = cgGetNamedParameter(p->fprogram, "Color_Diffuse");
2471                 p->fp_Color_Specular             = cgGetNamedParameter(p->fprogram, "Color_Specular");
2472                 p->fp_Color_Glow                 = cgGetNamedParameter(p->fprogram, "Color_Glow");
2473                 p->fp_Color_Pants                = cgGetNamedParameter(p->fprogram, "Color_Pants");
2474                 p->fp_Color_Shirt                = cgGetNamedParameter(p->fprogram, "Color_Shirt");
2475                 p->fp_DeferredColor_Ambient      = cgGetNamedParameter(p->fprogram, "DeferredColor_Ambient");
2476                 p->fp_DeferredColor_Diffuse      = cgGetNamedParameter(p->fprogram, "DeferredColor_Diffuse");
2477                 p->fp_DeferredColor_Specular     = cgGetNamedParameter(p->fprogram, "DeferredColor_Specular");
2478                 p->fp_DeferredMod_Diffuse        = cgGetNamedParameter(p->fprogram, "DeferredMod_Diffuse");
2479                 p->fp_DeferredMod_Specular       = cgGetNamedParameter(p->fprogram, "DeferredMod_Specular");
2480                 p->fp_DistortScaleRefractReflect = cgGetNamedParameter(p->fprogram, "DistortScaleRefractReflect");
2481                 p->fp_EyePosition                = cgGetNamedParameter(p->fprogram, "EyePosition");
2482                 p->fp_FogColor                   = cgGetNamedParameter(p->fprogram, "FogColor");
2483                 p->fp_FogHeightFade              = cgGetNamedParameter(p->fprogram, "FogHeightFade");
2484                 p->fp_FogPlane                   = cgGetNamedParameter(p->fprogram, "FogPlane");
2485                 p->fp_FogPlaneViewDist           = cgGetNamedParameter(p->fprogram, "FogPlaneViewDist");
2486                 p->fp_FogRangeRecip              = cgGetNamedParameter(p->fprogram, "FogRangeRecip");
2487                 p->fp_LightColor                 = cgGetNamedParameter(p->fprogram, "LightColor");
2488                 p->fp_LightDir                   = cgGetNamedParameter(p->fprogram, "LightDir");
2489                 p->fp_LightPosition              = cgGetNamedParameter(p->fprogram, "LightPosition");
2490                 p->fp_OffsetMapping_Scale        = cgGetNamedParameter(p->fprogram, "OffsetMapping_Scale");
2491                 p->fp_PixelSize                  = cgGetNamedParameter(p->fprogram, "PixelSize");
2492                 p->fp_ReflectColor               = cgGetNamedParameter(p->fprogram, "ReflectColor");
2493                 p->fp_ReflectFactor              = cgGetNamedParameter(p->fprogram, "ReflectFactor");
2494                 p->fp_ReflectOffset              = cgGetNamedParameter(p->fprogram, "ReflectOffset");
2495                 p->fp_RefractColor               = cgGetNamedParameter(p->fprogram, "RefractColor");
2496                 p->fp_Saturation                 = cgGetNamedParameter(p->fprogram, "Saturation");
2497                 p->fp_ScreenCenterRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenCenterRefractReflect");
2498                 p->fp_ScreenScaleRefractReflect  = cgGetNamedParameter(p->fprogram, "ScreenScaleRefractReflect");
2499                 p->fp_ScreenToDepth              = cgGetNamedParameter(p->fprogram, "ScreenToDepth");
2500                 p->fp_ShadowMap_Parameters       = cgGetNamedParameter(p->fprogram, "ShadowMap_Parameters");
2501                 p->fp_ShadowMap_TextureScale     = cgGetNamedParameter(p->fprogram, "ShadowMap_TextureScale");
2502                 p->fp_SpecularPower              = cgGetNamedParameter(p->fprogram, "SpecularPower");
2503                 p->fp_UserVec1                   = cgGetNamedParameter(p->fprogram, "UserVec1");
2504                 p->fp_UserVec2                   = cgGetNamedParameter(p->fprogram, "UserVec2");
2505                 p->fp_UserVec3                   = cgGetNamedParameter(p->fprogram, "UserVec3");
2506                 p->fp_UserVec4                   = cgGetNamedParameter(p->fprogram, "UserVec4");
2507                 p->fp_ViewTintColor              = cgGetNamedParameter(p->fprogram, "ViewTintColor");
2508                 p->fp_ViewToLight                = cgGetNamedParameter(p->fprogram, "ViewToLight");
2509                 CHECKGLERROR
2510                 if (developer.integer)
2511                         Con_Printf("^5CG shader %s compiled.\n", permutationname);
2512         }
2513         else
2514                 Con_Printf("^1CG shader %s failed!  some features may not work properly.\n", permutationname);
2515
2516         // free the strings
2517         if (vertstring)
2518                 Mem_Free(vertstring);
2519         if (geomstring)
2520                 Mem_Free(geomstring);
2521         if (fragstring)
2522                 Mem_Free(fragstring);
2523         if (vertexstring)
2524                 Mem_Free(vertexstring);
2525         if (geometrystring)
2526                 Mem_Free(geometrystring);
2527         if (fragmentstring)
2528                 Mem_Free(fragmentstring);
2529 }
2530
2531 void R_SetupShader_SetPermutationCG(unsigned int mode, unsigned int permutation)
2532 {
2533         r_cg_permutation_t *perm = R_CG_FindPermutation(mode, permutation);
2534         if (r_cg_permutation != perm)
2535         {
2536                 r_cg_permutation = perm;
2537                 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));
2538                 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));
2539                 if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
2540                 {
2541                         cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));
2542                         cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));
2543                         if (!r_cg_permutation->compiled)
2544                                 R_CG_CompilePermutation(perm, mode, permutation);
2545                         if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
2546                         {
2547                                 // remove features until we find a valid permutation
2548                                 int i;
2549                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2550                                 {
2551                                         // reduce i more quickly whenever it would not remove any bits
2552                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
2553                                         if (!(permutation & j))
2554                                                 continue;
2555                                         permutation -= j;
2556                                         r_cg_permutation = R_CG_FindPermutation(mode, permutation);
2557                                         if (!r_cg_permutation->compiled)
2558                                                 R_CG_CompilePermutation(perm, mode, permutation);
2559                                         if (r_cg_permutation->vprogram || r_cg_permutation->fprogram)
2560                                                 break;
2561                                 }
2562                                 if (i >= SHADERPERMUTATION_COUNT)
2563                                 {
2564                                         //Con_Printf("Could not find a working Cg shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
2565                                         r_cg_permutation = R_CG_FindPermutation(mode, permutation);
2566                                         return; // no bit left to clear, entire mode is broken
2567                                 }
2568                         }
2569                 }
2570                 CHECKGLERROR
2571                 if (r_cg_permutation->vprogram)
2572                 {
2573                         cgGLBindProgram(r_cg_permutation->vprogram);
2574                         cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));
2575                 }
2576                 else
2577                         cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));
2578                 if (r_cg_permutation->fprogram)
2579                 {
2580                         cgGLBindProgram(r_cg_permutation->fprogram);
2581                         cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));
2582                 }
2583                 else
2584                         cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));
2585         }
2586         if (r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);
2587 }
2588 #endif
2589
2590 void R_GLSL_Restart_f(void)
2591 {
2592         unsigned int i, limit;
2593         r_glsl_permutation_t *p;
2594         limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
2595         for (i = 0;i < limit;i++)
2596         {
2597                 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
2598                 {
2599                         GL_Backend_FreeProgram(p->program);
2600                         Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
2601                 }
2602         }
2603         memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
2604 #ifdef SUPPORTCG
2605         if (vid.cgcontext)
2606         {
2607                 r_cg_permutation_t *p;
2608                 limit = Mem_ExpandableArray_IndexRange(&r_cg_permutationarray);
2609                 for (i = 0;i < limit;i++)
2610                 {
2611                         if ((p = (r_cg_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_cg_permutationarray, i)))
2612                         {
2613                                 if (p->vprogram)
2614                                         cgDestroyProgram(p->vprogram);
2615                                 if (p->fprogram)
2616                                         cgDestroyProgram(p->fprogram);
2617                                 Mem_ExpandableArray_FreeRecord(&r_cg_permutationarray, (void*)p);
2618                         }
2619                 }
2620                 memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
2621         }
2622 #endif
2623 }
2624
2625 void R_GLSL_DumpShader_f(void)
2626 {
2627         int i;
2628         qfile_t *file;
2629
2630         file = FS_OpenRealFile("glsl/default.glsl", "w", false);
2631         if (file)
2632         {
2633                 FS_Print(file, "/* The engine may define the following macros:\n");
2634                 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
2635                 for (i = 0;i < SHADERMODE_COUNT;i++)
2636                         FS_Print(file, glslshadermodeinfo[i].pretext);
2637                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2638                         FS_Print(file, shaderpermutationinfo[i].pretext);
2639                 FS_Print(file, "*/\n");
2640                 FS_Print(file, builtinshaderstring);
2641                 FS_Close(file);
2642                 Con_Printf("glsl/default.glsl written\n");
2643         }
2644         else
2645                 Con_Printf("failed to write to glsl/default.glsl\n");
2646
2647 #ifdef SUPPORTCG
2648         file = FS_OpenRealFile("cg/default.cg", "w", false);
2649         if (file)
2650         {
2651                 FS_Print(file, "/* The engine may define the following macros:\n");
2652                 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
2653                 for (i = 0;i < SHADERMODE_COUNT;i++)
2654                         FS_Print(file, cgshadermodeinfo[i].pretext);
2655                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2656                         FS_Print(file, shaderpermutationinfo[i].pretext);
2657                 FS_Print(file, "*/\n");
2658                 FS_Print(file, builtincgshaderstring);
2659                 FS_Close(file);
2660                 Con_Printf("cg/default.cg written\n");
2661         }
2662         else
2663                 Con_Printf("failed to write to cg/default.cg\n");
2664 #endif
2665 }
2666
2667 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale)
2668 {
2669         if (!second)
2670                 texturemode = GL_MODULATE;
2671         switch (vid.renderpath)
2672         {
2673         case RENDERPATH_GL20:
2674                 R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
2675                 if (r_glsl_permutation->loc_Texture_First ) R_Mesh_TexBind(GL20TU_FIRST , R_GetTexture(first ));
2676                 if (r_glsl_permutation->loc_Texture_Second) R_Mesh_TexBind(GL20TU_SECOND, R_GetTexture(second));
2677                 break;
2678         case RENDERPATH_CGGL:
2679 #ifdef SUPPORTCG
2680                 R_SetupShader_SetPermutationCG(SHADERMODE_GENERIC, (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
2681                 if (r_cg_permutation->fp_Texture_First ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_First , R_GetTexture(first ));
2682                 if (r_cg_permutation->fp_Texture_Second) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Second, R_GetTexture(second));
2683 #endif
2684                 break;
2685         case RENDERPATH_GL13:
2686                 R_Mesh_TexBind(0, R_GetTexture(first ));
2687                 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
2688                 R_Mesh_TexBind(1, R_GetTexture(second));
2689                 if (second)
2690                         R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
2691                 break;
2692         case RENDERPATH_GL11:
2693                 R_Mesh_TexBind(0, R_GetTexture(first ));
2694                 break;
2695         }
2696 }
2697
2698 void R_SetupShader_DepthOrShadow(void)
2699 {
2700         switch (vid.renderpath)
2701         {
2702         case RENDERPATH_GL20:
2703                 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, 0);
2704                 break;
2705         case RENDERPATH_CGGL:
2706 #ifdef SUPPORTCG
2707                 R_SetupShader_SetPermutationCG(SHADERMODE_DEPTH_OR_SHADOW, 0);
2708 #endif
2709                 break;
2710         case RENDERPATH_GL13:
2711                 R_Mesh_TexBind(0, 0);
2712                 R_Mesh_TexBind(1, 0);
2713                 break;
2714         case RENDERPATH_GL11:
2715                 R_Mesh_TexBind(0, 0);
2716                 break;
2717         }
2718 }
2719
2720 void R_SetupShader_ShowDepth(void)
2721 {
2722         switch (vid.renderpath)
2723         {
2724         case RENDERPATH_GL20:
2725                 R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, 0);
2726                 break;
2727         case RENDERPATH_CGGL:
2728 #ifdef SUPPORTCG
2729                 R_SetupShader_SetPermutationCG(SHADERMODE_SHOWDEPTH, 0);
2730 #endif
2731                 break;
2732         case RENDERPATH_GL13:
2733                 break;
2734         case RENDERPATH_GL11:
2735                 break;
2736         }
2737 }
2738
2739 extern qboolean r_shadow_usingdeferredprepass;
2740 extern cvar_t r_shadow_deferred_8bitrange;
2741 extern rtexture_t *r_shadow_attenuationgradienttexture;
2742 extern rtexture_t *r_shadow_attenuation2dtexture;
2743 extern rtexture_t *r_shadow_attenuation3dtexture;
2744 extern qboolean r_shadow_usingshadowmaprect;
2745 extern qboolean r_shadow_usingshadowmapcube;
2746 extern qboolean r_shadow_usingshadowmap2d;
2747 extern float r_shadow_shadowmap_texturescale[2];
2748 extern float r_shadow_shadowmap_parameters[4];
2749 extern qboolean r_shadow_shadowmapvsdct;
2750 extern qboolean r_shadow_shadowmapsampler;
2751 extern int r_shadow_shadowmappcf;
2752 extern rtexture_t *r_shadow_shadowmaprectangletexture;
2753 extern rtexture_t *r_shadow_shadowmap2dtexture;
2754 extern rtexture_t *r_shadow_shadowmapcubetexture[R_SHADOW_SHADOWMAP_NUMCUBEMAPS];
2755 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
2756 extern int r_shadow_shadowmaplod; // changes for each light based on distance
2757 extern int r_shadow_prepass_width;
2758 extern int r_shadow_prepass_height;
2759 extern rtexture_t *r_shadow_prepassgeometrydepthtexture;
2760 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
2761 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
2762 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
2763 void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass)
2764 {
2765         // select a permutation of the lighting shader appropriate to this
2766         // combination of texture, entity, light source, and fogging, only use the
2767         // minimum features necessary to avoid wasting rendering time in the
2768         // fragment shader on features that are not being used
2769         unsigned int permutation = 0;
2770         unsigned int mode = 0;
2771         float m16f[16];
2772         // TODO: implement geometry-shader based shadow volumes someday
2773         if (r_glsl_offsetmapping.integer)
2774         {
2775                 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
2776                 if (r_glsl_offsetmapping_reliefmapping.integer)
2777                         permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
2778         }
2779         if (rsurfacepass == RSURFPASS_BACKGROUND)
2780         {
2781                 // distorted background
2782                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2783                         mode = SHADERMODE_WATER;
2784                 else
2785                         mode = SHADERMODE_REFRACTION;
2786         }
2787         else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2788         {
2789                 // normalmap (deferred prepass), may use alpha test on diffuse
2790                 mode = SHADERMODE_DEFERREDGEOMETRY;
2791                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2792                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2793                 if (r_glsl_offsetmapping.integer)
2794                 {
2795                         permutation |= SHADERPERMUTATION_OFFSETMAPPING;
2796                         if (r_glsl_offsetmapping_reliefmapping.integer)
2797                                 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
2798                 }
2799         }
2800         else if (rsurfacepass == RSURFPASS_RTLIGHT)
2801         {
2802                 // light source
2803                 mode = SHADERMODE_LIGHTSOURCE;
2804                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2805                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2806                 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2807                         permutation |= SHADERPERMUTATION_CUBEFILTER;
2808                 if (diffusescale > 0)
2809                         permutation |= SHADERPERMUTATION_DIFFUSE;
2810                 if (specularscale > 0)
2811                         permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2812                 if (r_refdef.fogenabled)
2813                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2814                 if (rsurface.texture->colormapping)
2815                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2816                 if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
2817                 {
2818                         if (r_shadow_usingshadowmaprect)
2819                                 permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
2820                         if (r_shadow_usingshadowmap2d)
2821                                 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2822                         if (r_shadow_usingshadowmapcube)
2823                                 permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
2824                         else if(r_shadow_shadowmapvsdct)
2825                                 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2826
2827                         if (r_shadow_shadowmapsampler)
2828                                 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2829                         if (r_shadow_shadowmappcf > 1)
2830                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2831                         else if (r_shadow_shadowmappcf)
2832                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2833                 }
2834         }
2835         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2836         {
2837                 // unshaded geometry (fullbright or ambient model lighting)
2838                 mode = SHADERMODE_FLATCOLOR;
2839                 ambientscale = diffusescale = specularscale = 0;
2840                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2841                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2842                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2843                         permutation |= SHADERPERMUTATION_GLOW;
2844                 if (r_refdef.fogenabled)
2845                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2846                 if (rsurface.texture->colormapping)
2847                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2848                 if (r_glsl_offsetmapping.integer)
2849                 {
2850                         permutation |= SHADERPERMUTATION_OFFSETMAPPING;
2851                         if (r_glsl_offsetmapping_reliefmapping.integer)
2852                                 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
2853                 }
2854                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2855                         permutation |= SHADERPERMUTATION_REFLECTION;
2856         }
2857         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2858         {
2859                 // directional model lighting
2860                 mode = SHADERMODE_LIGHTDIRECTION;
2861                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2862                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2863                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2864                         permutation |= SHADERPERMUTATION_GLOW;
2865                 permutation |= SHADERPERMUTATION_DIFFUSE;
2866                 if (specularscale > 0)
2867                         permutation |= SHADERPERMUTATION_SPECULAR;
2868                 if (r_refdef.fogenabled)
2869                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2870                 if (rsurface.texture->colormapping)
2871                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2872                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2873                         permutation |= SHADERPERMUTATION_REFLECTION;
2874                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2875                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2876         }
2877         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2878         {
2879                 // ambient model lighting
2880                 mode = SHADERMODE_LIGHTDIRECTION;
2881                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2882                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2883                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2884                         permutation |= SHADERPERMUTATION_GLOW;
2885                 if (r_refdef.fogenabled)
2886                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2887                 if (rsurface.texture->colormapping)
2888                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2889                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2890                         permutation |= SHADERPERMUTATION_REFLECTION;
2891                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2892                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2893         }
2894         else
2895         {
2896                 // lightmapped wall
2897                 if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2898                 {
2899                         // deluxemapping (light direction texture)
2900                         if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2901                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2902                         else
2903                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2904                         permutation |= SHADERPERMUTATION_DIFFUSE;
2905                         if (specularscale > 0)
2906                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2907                 }
2908                 else if (r_glsl_deluxemapping.integer >= 2)
2909                 {
2910                         // fake deluxemapping (uniform light direction in tangentspace)
2911                         mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2912                         permutation |= SHADERPERMUTATION_DIFFUSE;
2913                         if (specularscale > 0)
2914                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2915                 }
2916                 else if (rsurface.uselightmaptexture)
2917                 {
2918                         // ordinary lightmapping (q1bsp, q3bsp)
2919                         mode = SHADERMODE_LIGHTMAP;
2920                 }
2921                 else
2922                 {
2923                         // ordinary vertex coloring (q3bsp)
2924                         mode = SHADERMODE_VERTEXCOLOR;
2925                 }
2926                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2927                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2928                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2929                         permutation |= SHADERPERMUTATION_GLOW;
2930                 if (r_refdef.fogenabled)
2931                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2932                 if (rsurface.texture->colormapping)
2933                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2934                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2935                         permutation |= SHADERPERMUTATION_REFLECTION;
2936                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2937                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2938         }
2939         if(permutation & SHADERPERMUTATION_SPECULAR)
2940                 if(r_shadow_glossexact.integer)
2941                         permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
2942         if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) && r_shadow_usingdeferredprepass)
2943                 permutation |= SHADERPERMUTATION_ALPHAKILL;
2944         switch(vid.renderpath)
2945         {
2946         case RENDERPATH_GL20:
2947                 R_SetupShader_SetPermutationGLSL(mode, permutation);
2948                 if (mode == SHADERMODE_LIGHTSOURCE)
2949                 {
2950                         if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2951                         if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2952                         if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2953                         if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);
2954                         if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);
2955                         if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, specularscale, specularscale, specularscale);
2956         
2957                         // additive passes are only darkened by fog, not tinted
2958                         if (r_glsl_permutation->loc_FogColor >= 0)
2959                                 qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2960                         if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2fARB(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2961                         if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4fARB(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2962                         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
2963                 }
2964                 else
2965                 {
2966                         if (mode == SHADERMODE_FLATCOLOR)
2967                         {
2968                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);
2969                         }
2970                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2971                         {
2972                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);
2973                                 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity, r_refdef.lightmapintensity, r_refdef.lightmapintensity);
2974                                 if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale);
2975                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);
2976                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
2977                                 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
2978                                 if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2979                         }
2980                         else
2981                         {
2982                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);
2983                                 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2984                                 if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale);
2985                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
2986                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
2987                         }
2988                         // additive passes are only darkened by fog, not tinted
2989                         if (r_glsl_permutation->loc_FogColor >= 0)
2990                         {
2991                                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
2992                                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2993                                 else
2994                                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2995                         }
2996                         if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
2997                         if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
2998                         if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
2999                         if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
3000                         if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
3001                         if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
3002                         if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
3003                         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
3004                 }
3005                 if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
3006                 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
3007                 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
3008                 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
3009                 if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1fARB(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3]);
3010                 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
3011                 if (r_glsl_permutation->loc_Color_Pants >= 0)
3012                 {
3013                         if (rsurface.texture->pantstexture)
3014                                 qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
3015                         else
3016                                 qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
3017                 }
3018                 if (r_glsl_permutation->loc_Color_Shirt >= 0)
3019                 {
3020                         if (rsurface.texture->shirttexture)
3021                                 qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
3022                         else
3023                                 qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
3024                 }
3025                 if (r_glsl_permutation->loc_FogPlane >= 0) qglUniform4fARB(r_glsl_permutation->loc_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
3026                 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
3027                 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
3028                 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
3029                 if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
3030                 if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2fARB(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3031
3032         //      if (r_glsl_permutation->loc_Texture_First           >= 0) R_Mesh_TexBind(GL20TU_FIRST             ,          R_GetTexture(r_texture_white                                     ));
3033         //      if (r_glsl_permutation->loc_Texture_Second          >= 0) R_Mesh_TexBind(GL20TU_SECOND            ,          R_GetTexture(r_texture_white                                     ));
3034         //      if (r_glsl_permutation->loc_Texture_GammaRamps      >= 0) R_Mesh_TexBind(GL20TU_GAMMARAMPS        ,          R_GetTexture(r_texture_gammaramps                                ));
3035                 if (r_glsl_permutation->loc_Texture_Normal          >= 0) R_Mesh_TexBind(GL20TU_NORMAL            ,          R_GetTexture(rsurface.texture->nmaptexture                       ));
3036                 if (r_glsl_permutation->loc_Texture_Color           >= 0) R_Mesh_TexBind(GL20TU_COLOR             ,          R_GetTexture(rsurface.texture->basetexture                       ));
3037                 if (r_glsl_permutation->loc_Texture_Gloss           >= 0) R_Mesh_TexBind(GL20TU_GLOSS             ,          R_GetTexture(rsurface.texture->glosstexture                      ));
3038                 if (r_glsl_permutation->loc_Texture_Glow            >= 0) R_Mesh_TexBind(GL20TU_GLOW              ,          R_GetTexture(rsurface.texture->glowtexture                       ));
3039                 if (r_glsl_permutation->loc_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL  ,          R_GetTexture(rsurface.texture->backgroundnmaptexture             ));
3040                 if (r_glsl_permutation->loc_Texture_SecondaryColor  >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR   ,          R_GetTexture(rsurface.texture->backgroundbasetexture             ));
3041                 if (r_glsl_permutation->loc_Texture_SecondaryGloss  >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS   ,          R_GetTexture(rsurface.texture->backgroundglosstexture            ));
3042                 if (r_glsl_permutation->loc_Texture_SecondaryGlow   >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW    ,          R_GetTexture(rsurface.texture->backgroundglowtexture             ));
3043                 if (r_glsl_permutation->loc_Texture_Pants           >= 0) R_Mesh_TexBind(GL20TU_PANTS             ,          R_GetTexture(rsurface.texture->pantstexture                      ));
3044                 if (r_glsl_permutation->loc_Texture_Shirt           >= 0) R_Mesh_TexBind(GL20TU_SHIRT             ,          R_GetTexture(rsurface.texture->shirttexture                      ));
3045                 if (r_glsl_permutation->loc_Texture_FogMask         >= 0) R_Mesh_TexBind(GL20TU_FOGMASK           ,          R_GetTexture(r_texture_fogattenuation                            ));
3046                 if (r_glsl_permutation->loc_Texture_Lightmap        >= 0) R_Mesh_TexBind(GL20TU_LIGHTMAP          ,          R_GetTexture(r_texture_white                                     ));
3047                 if (r_glsl_permutation->loc_Texture_Deluxemap       >= 0) R_Mesh_TexBind(GL20TU_LIGHTMAP          ,          R_GetTexture(r_texture_blanknormalmap                            ));
3048                 if (r_glsl_permutation->loc_Texture_Attenuation     >= 0) R_Mesh_TexBind(GL20TU_ATTENUATION       ,          R_GetTexture(r_shadow_attenuationgradienttexture                 ));
3049                 if (r_glsl_permutation->loc_Texture_Refraction      >= 0) R_Mesh_TexBind(GL20TU_REFRACTION        ,          R_GetTexture(r_texture_white                                     ));
3050                 if (r_glsl_permutation->loc_Texture_Reflection      >= 0) R_Mesh_TexBind(GL20TU_REFLECTION        ,          R_GetTexture(r_texture_white                                     ));
3051                 if (r_glsl_permutation->loc_Texture_ScreenDepth     >= 0) R_Mesh_TexBindAll(GL20TU_SCREENDEPTH    , 0, 0, 0, R_GetTexture(r_shadow_prepassgeometrydepthtexture                ));
3052                 if (r_glsl_permutation->loc_Texture_ScreenNormalMap >= 0) R_Mesh_TexBindAll(GL20TU_SCREENNORMALMAP, 0, 0, 0, R_GetTexture(r_shadow_prepassgeometrynormalmaptexture            ));
3053                 if (r_glsl_permutation->loc_Texture_ScreenDiffuse   >= 0) R_Mesh_TexBindAll(GL20TU_SCREENDIFFUSE  , 0, 0, 0, R_GetTexture(r_shadow_prepasslightingdiffusetexture              ));
3054                 if (r_glsl_permutation->loc_Texture_ScreenSpecular  >= 0) R_Mesh_TexBindAll(GL20TU_SCREENSPECULAR , 0, 0, 0, R_GetTexture(r_shadow_prepasslightingspeculartexture             ));
3055                 if (rsurface.rtlight)
3056                 {
3057                         if (r_glsl_permutation->loc_Texture_Cube            >= 0) R_Mesh_TexBindAll(GL20TU_CUBE           , 0, 0,    R_GetTexture(rsurface.rtlight->currentcubemap                    ), 0);
3058                         if (r_glsl_permutation->loc_Texture_ShadowMapRect   >= 0) R_Mesh_TexBindAll(GL20TU_SHADOWMAPRECT  , 0, 0, 0, R_GetTexture(r_shadow_shadowmaprectangletexture                  ));
3059                         if (r_shadow_usingshadowmapcube)
3060                                 if (r_glsl_permutation->loc_Texture_ShadowMapCube   >= 0) R_Mesh_TexBindAll(GL20TU_SHADOWMAPCUBE  , 0, 0,    R_GetTexture(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]), 0);
3061                         if (r_glsl_permutation->loc_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAP2D       ,          R_GetTexture(r_shadow_shadowmap2dtexture                         ));
3062                         if (r_glsl_permutation->loc_Texture_CubeProjection  >= 0) R_Mesh_TexBindAll(GL20TU_CUBEPROJECTION , 0, 0,    R_GetTexture(r_shadow_shadowmapvsdcttexture                      ), 0);
3063                 }
3064                 CHECKGLERROR
3065                 break;
3066         case RENDERPATH_CGGL:
3067 #ifdef SUPPORTCG
3068                 R_SetupShader_SetPermutationGLSL(mode, permutation);
3069                 if (mode == SHADERMODE_LIGHTSOURCE)
3070                 {
3071                         if (r_cg_permutation->vp_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelToLight, m16f);}
3072                         if (r_cg_permutation->vp_LightPosition >= 0) cgGLSetParameter3f(r_cg_permutation->vp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
3073                 }
3074                 else
3075                 {
3076                         if (mode == SHADERMODE_LIGHTDIRECTION)
3077                         {
3078                                 if (r_cg_permutation->vp_LightDir >= 0) cgGLSetParameter3f(r_cg_permutation->vp_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
3079                         }
3080                 }
3081                 if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelviewprojection16f);
3082                 if (r_cg_permutation->vp_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_TexMatrix, m16f);}
3083                 if (r_cg_permutation->vp_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_BackgroundTexMatrix, m16f);}
3084                 if (r_cg_permutation->vp_EyePosition >= 0) cgGLSetParameter3f(r_cg_permutation->vp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
3085                 if (r_cg_permutation->vp_FogPlane >= 0) cgGLSetParameter4f(r_cg_permutation->vp_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
3086                 CHECKGLERROR
3087
3088                 if (mode == SHADERMODE_LIGHTSOURCE)
3089                 {
3090                         if (r_cg_permutation->fp_LightPosition >= 0) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
3091                         if (r_cg_permutation->fp_LightColor >= 0) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
3092                         if (r_cg_permutation->fp_Color_Ambient >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);
3093                         if (r_cg_permutation->fp_Color_Diffuse >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);
3094                         if (r_cg_permutation->fp_Color_Specular >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, specularscale, specularscale, specularscale);
3095
3096                         // additive passes are only darkened by fog, not tinted
3097                         if (r_cg_permutation->fp_FogColor >= 0)
3098                                 cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);
3099                         if (r_cg_permutation->fp_ShadowMap_TextureScale >= 0) cgGLSetParameter2f(r_cg_permutation->fp_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3100                         if (r_cg_permutation->fp_ShadowMap_Parameters >= 0) cgGLSetParameter4f(r_cg_permutation->fp_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
3101                         if (r_cg_permutation->fp_SpecularPower >= 0) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
3102                 }
3103                 else
3104                 {
3105                         if (mode == SHADERMODE_FLATCOLOR)
3106                         {
3107                                 if (r_cg_permutation->fp_Color_Ambient >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);
3108                         }
3109                         else if (mode == SHADERMODE_LIGHTDIRECTION)
3110                         {
3111                                 if (r_cg_permutation->fp_Color_Ambient >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);
3112                                 if (r_cg_permutation->fp_Color_Diffuse >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, r_refdef.lightmapintensity, r_refdef.lightmapintensity, r_refdef.lightmapintensity);
3113                                 if (r_cg_permutation->fp_Color_Specular >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale);
3114                                 if (r_cg_permutation->fp_DeferredMod_Diffuse >= 0) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);
3115                                 if (r_cg_permutation->fp_DeferredMod_Specular >= 0) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
3116                                 if (r_cg_permutation->fp_LightColor >= 0) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
3117                                 if (r_cg_permutation->fp_LightDir >= 0) cgGLSetParameter3f(r_cg_permutation->fp_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
3118                         }
3119                         else
3120                         {
3121                                 if (r_cg_permutation->fp_Color_Ambient >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);
3122                                 if (r_cg_permutation->fp_Color_Diffuse >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
3123                                 if (r_cg_permutation->fp_Color_Specular >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale);
3124                                 if (r_cg_permutation->fp_DeferredMod_Diffuse >= 0) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
3125                                 if (r_cg_permutation->fp_DeferredMod_Specular >= 0) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
3126                         }
3127                         // additive passes are only darkened by fog, not tinted
3128                         if (r_cg_permutation->fp_FogColor >= 0)
3129                         {
3130                                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
3131                                         cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);
3132                                 else
3133                                         cgGLSetParameter3f(r_cg_permutation->fp_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
3134                         }
3135                         if (r_cg_permutation->fp_DistortScaleRefractReflect >= 0) cgGLSetParameter4f(r_cg_permutation->fp_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
3136                         if (r_cg_permutation->fp_ScreenScaleRefractReflect >= 0) cgGLSetParameter4f(r_cg_permutation->fp_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
3137                         if (r_cg_permutation->fp_ScreenCenterRefractReflect >= 0) cgGLSetParameter4f(r_cg_permutation->fp_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
3138                         if (r_cg_permutation->fp_RefractColor >= 0) cgGLSetParameter4fv(r_cg_permutation->fp_RefractColor, rsurface.texture->refractcolor4f);
3139                         if (r_cg_permutation->fp_ReflectColor >= 0) cgGLSetParameter4fv(r_cg_permutation->fp_ReflectColor, rsurface.texture->reflectcolor4f);
3140                         if (r_cg_permutation->fp_ReflectFactor >= 0) cgGLSetParameter1f(r_cg_permutation->fp_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
3141                         if (r_cg_permutation->fp_ReflectOffset >= 0) cgGLSetParameter1f(r_cg_permutation->fp_ReflectOffset, rsurface.texture->reflectmin);
3142                         if (r_cg_permutation->fp_SpecularPower >= 0) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
3143                 }
3144                 if (r_cg_permutation->fp_Color_Glow >= 0) cgGLSetParameter3f(r_cg_permutation->fp_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
3145                 if (r_cg_permutation->fp_Alpha >= 0) cgGLSetParameter1f(r_cg_permutation->fp_Alpha, rsurface.texture->lightmapcolor[3]);
3146                 if (r_cg_permutation->fp_EyePosition >= 0) cgGLSetParameter3f(r_cg_permutation->fp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
3147                 if (r_cg_permutation->fp_Color_Pants >= 0)
3148                 {
3149                         if (rsurface.texture->pantstexture)
3150                                 cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
3151                         else
3152                                 cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, 0, 0, 0);
3153                 }
3154                 if (r_cg_permutation->fp_Color_Shirt >= 0)
3155                 {
3156                         if (rsurface.texture->shirttexture)
3157                                 cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
3158                         else
3159                                 cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, 0, 0, 0);
3160                 }
3161                 if (r_cg_permutation->fp_FogPlane >= 0) cgGLSetParameter4f(r_cg_permutation->fp_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
3162                 if (r_cg_permutation->fp_FogPlaneViewDist >= 0) cgGLSetParameter1f(r_cg_permutation->fp_FogPlaneViewDist, rsurface.fogplaneviewdist);
3163                 if (r_cg_permutation->fp_FogRangeRecip >= 0) cgGLSetParameter1f(r_cg_permutation->fp_FogRangeRecip, rsurface.fograngerecip);
3164                 if (r_cg_permutation->fp_FogHeightFade >= 0) cgGLSetParameter1f(r_cg_permutation->fp_FogHeightFade, rsurface.fogheightfade);
3165                 if (r_cg_permutation->fp_OffsetMapping_Scale >= 0) cgGLSetParameter1f(r_cg_permutation->fp_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
3166                 if (r_cg_permutation->fp_ScreenToDepth >= 0) cgGLSetParameter2f(r_cg_permutation->fp_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3167
3168         //      if (r_cg_permutation->fp_Texture_First          ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_First          , R_GetTexture(r_texture_white                                     ));
3169         //      if (r_cg_permutation->fp_Texture_Second         ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Second         , R_GetTexture(r_texture_white                                     ));
3170         //      if (r_cg_permutation->fp_Texture_GammaRamps     ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_GammaRamps     , R_GetTexture(r_texture_gammaramps                                ));
3171                 if (r_cg_permutation->fp_Texture_Normal         ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Normal         , R_GetTexture(rsurface.texture->nmaptexture                       ));
3172                 if (r_cg_permutation->fp_Texture_Color          ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Color          , R_GetTexture(rsurface.texture->basetexture                       ));
3173                 if (r_cg_permutation->fp_Texture_Gloss          ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Gloss          , R_GetTexture(rsurface.texture->glosstexture                      ));
3174                 if (r_cg_permutation->fp_Texture_Glow           ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Glow           , R_GetTexture(rsurface.texture->glowtexture                       ));
3175                 if (r_cg_permutation->fp_Texture_SecondaryNormal) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_SecondaryNormal, R_GetTexture(rsurface.texture->backgroundnmaptexture             ));
3176                 if (r_cg_permutation->fp_Texture_SecondaryColor ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_SecondaryColor , R_GetTexture(rsurface.texture->backgroundbasetexture             ));
3177                 if (r_cg_permutation->fp_Texture_SecondaryGloss ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_SecondaryGloss , R_GetTexture(rsurface.texture->backgroundglosstexture            ));
3178                 if (r_cg_permutation->fp_Texture_SecondaryGlow  ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_SecondaryGlow  , R_GetTexture(rsurface.texture->backgroundglowtexture             ));
3179                 if (r_cg_permutation->fp_Texture_Pants          ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Pants          , R_GetTexture(rsurface.texture->pantstexture                      ));
3180                 if (r_cg_permutation->fp_Texture_Shirt          ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Shirt          , R_GetTexture(rsurface.texture->shirttexture                      ));
3181                 if (r_cg_permutation->fp_Texture_FogMask        ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_FogMask        , R_GetTexture(r_texture_fogattenuation                            ));
3182                 if (r_cg_permutation->fp_Texture_Lightmap       ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Lightmap       , R_GetTexture(r_texture_white                                     ));
3183                 if (r_cg_permutation->fp_Texture_Deluxemap      ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Deluxemap      , R_GetTexture(r_texture_blanknormalmap                            ));
3184                 if (r_cg_permutation->fp_Texture_Attenuation    ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Attenuation    , R_GetTexture(r_shadow_attenuationgradienttexture                 ));
3185                 if (r_cg_permutation->fp_Texture_Refraction     ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Refraction     , R_GetTexture(r_texture_white                                     ));
3186                 if (r_cg_permutation->fp_Texture_Reflection     ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Reflection     , R_GetTexture(r_texture_white                                     ));
3187                 if (r_cg_permutation->fp_Texture_ScreenDepth    ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ScreenDepth    , R_GetTexture(r_shadow_prepassgeometrydepthtexture                ));
3188                 if (r_cg_permutation->fp_Texture_ScreenNormalMap) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ScreenNormalMap, R_GetTexture(r_shadow_prepassgeometrynormalmaptexture            ));
3189                 if (r_cg_permutation->fp_Texture_ScreenDiffuse  ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ScreenDiffuse  , R_GetTexture(r_shadow_prepasslightingdiffusetexture              ));
3190                 if (r_cg_permutation->fp_Texture_ScreenSpecular ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ScreenSpecular , R_GetTexture(r_shadow_prepasslightingspeculartexture             ));
3191                 if (rsurface.rtlight)
3192                 {
3193                         if (r_cg_permutation->fp_Texture_Cube       ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Cube           , R_GetTexture(rsurface.rtlight->currentcubemap                    ));
3194                         if (r_cg_permutation->fp_Texture_ShadowMapRect  ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ShadowMapRect  , R_GetTexture(r_shadow_shadowmaprectangletexture                  ));
3195                         if (r_shadow_usingshadowmapcube)
3196                                 if (r_cg_permutation->fp_Texture_ShadowMapCube  ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ShadowMapCube  , R_GetTexture(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]));
3197                         if (r_cg_permutation->fp_Texture_ShadowMap2D    ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ShadowMap2D    , R_GetTexture(r_shadow_shadowmap2dtexture                         ));
3198                         if (r_cg_permutation->fp_Texture_CubeProjection ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_CubeProjection , R_GetTexture(r_shadow_shadowmapvsdcttexture                      ));
3199                 }
3200
3201                 CHECKGLERROR
3202 #endif
3203                 break;
3204         case RENDERPATH_GL13:
3205         case RENDERPATH_GL11:
3206                 break;
3207         }
3208 }
3209
3210 void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
3211 {
3212         // select a permutation of the lighting shader appropriate to this
3213         // combination of texture, entity, light source, and fogging, only use the
3214         // minimum features necessary to avoid wasting rendering time in the
3215         // fragment shader on features that are not being used
3216         unsigned int permutation = 0;
3217         unsigned int mode = 0;
3218         const float *lightcolorbase = rtlight->currentcolor;
3219         float ambientscale = rtlight->ambientscale;
3220         float diffusescale = rtlight->diffusescale;
3221         float specularscale = rtlight->specularscale;
3222         // this is the location of the light in view space
3223         vec3_t viewlightorigin;
3224         // this transforms from view space (camera) to light space (cubemap)
3225         matrix4x4_t viewtolight;
3226         matrix4x4_t lighttoview;
3227         float viewtolight16f[16];
3228         float range = 1.0f / r_shadow_deferred_8bitrange.value;
3229         // light source
3230         mode = SHADERMODE_DEFERREDLIGHTSOURCE;
3231         if (rtlight->currentcubemap != r_texture_whitecube)
3232                 permutation |= SHADERPERMUTATION_CUBEFILTER;
3233         if (diffusescale > 0)
3234                 permutation |= SHADERPERMUTATION_DIFFUSE;
3235         if (specularscale > 0)
3236         {
3237                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
3238                 if (r_shadow_glossexact.integer)
3239                         permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
3240         }
3241         if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
3242         {
3243                 if (r_shadow_usingshadowmaprect)
3244                         permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
3245                 if (r_shadow_usingshadowmap2d)
3246                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
3247                 if (r_shadow_usingshadowmapcube)
3248                         permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
3249                 else if(r_shadow_shadowmapvsdct)
3250                         permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
3251
3252                 if (r_shadow_shadowmapsampler)
3253                         permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
3254                 if (r_shadow_shadowmappcf > 1)
3255                         permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
3256                 else if (r_shadow_shadowmappcf)
3257                         permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
3258         }
3259         Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
3260         Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
3261         Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
3262         Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
3263         switch(vid.renderpath)
3264         {
3265         case RENDERPATH_GL20:
3266                 R_SetupShader_SetPermutationGLSL(mode, permutation);
3267                 if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
3268                 if (r_glsl_permutation->loc_LightPosition             >= 0) qglUniform3fARB(       r_glsl_permutation->loc_LightPosition            , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3269                 if (r_glsl_permutation->loc_ViewToLight               >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ViewToLight              , 1, false, viewtolight16f);
3270                 if (r_glsl_permutation->loc_DeferredColor_Ambient     >= 0) qglUniform3fARB(       r_glsl_permutation->loc_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale  * range, lightcolorbase[1] * ambientscale  * range, lightcolorbase[2] * ambientscale  * range);
3271                 if (r_glsl_permutation->loc_DeferredColor_Diffuse     >= 0) qglUniform3fARB(       r_glsl_permutation->loc_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale  * range, lightcolorbase[1] * diffusescale  * range, lightcolorbase[2] * diffusescale  * range);
3272                 if (r_glsl_permutation->loc_DeferredColor_Specular    >= 0) qglUniform3fARB(       r_glsl_permutation->loc_DeferredColor_Specular   , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
3273                 if (r_glsl_permutation->loc_ShadowMap_TextureScale    >= 0) qglUniform2fARB(       r_glsl_permutation->loc_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3274                 if (r_glsl_permutation->loc_ShadowMap_Parameters      >= 0) qglUniform4fARB(       r_glsl_permutation->loc_ShadowMap_Parameters     , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
3275                 if (r_glsl_permutation->loc_SpecularPower             >= 0) qglUniform1fARB(       r_glsl_permutation->loc_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
3276                 if (r_glsl_permutation->loc_ScreenToDepth             >= 0) qglUniform2fARB(       r_glsl_permutation->loc_ScreenToDepth            , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3277
3278                 if (r_glsl_permutation->loc_Texture_Attenuation       >= 0) R_Mesh_TexBind(GL20TU_ATTENUATION       ,          R_GetTexture(r_shadow_attenuationgradienttexture                 ));
3279                 if (r_glsl_permutation->loc_Texture_ScreenDepth       >= 0) R_Mesh_TexBindAll(GL20TU_SCREENDEPTH    , 0, 0, 0, R_GetTexture(r_shadow_prepassgeometrydepthtexture                ));
3280                 if (r_glsl_permutation->loc_Texture_ScreenNormalMap   >= 0) R_Mesh_TexBindAll(GL20TU_SCREENNORMALMAP, 0, 0, 0, R_GetTexture(r_shadow_prepassgeometrynormalmaptexture            ));
3281                 if (r_glsl_permutation->loc_Texture_Cube              >= 0) R_Mesh_TexBindAll(GL20TU_CUBE           , 0, 0,    R_GetTexture(rsurface.rtlight->currentcubemap                    ), 0);
3282                 if (r_glsl_permutation->loc_Texture_ShadowMapRect     >= 0) R_Mesh_TexBindAll(GL20TU_SHADOWMAPRECT  , 0, 0, 0, R_GetTexture(r_shadow_shadowmaprectangletexture                  ));
3283                 if (r_shadow_usingshadowmapcube)
3284                         if (r_glsl_permutation->loc_Texture_ShadowMapCube     >= 0) R_Mesh_TexBindAll(GL20TU_SHADOWMAPCUBE  , 0, 0,    R_GetTexture(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]), 0);
3285                 if (r_glsl_permutation->loc_Texture_ShadowMap2D       >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAP2D       ,          R_GetTexture(r_shadow_shadowmap2dtexture                         ));
3286                 if (r_glsl_permutation->loc_Texture_CubeProjection    >= 0) R_Mesh_TexBindAll(GL20TU_CUBEPROJECTION , 0, 0,    R_GetTexture(r_shadow_shadowmapvsdcttexture                      ), 0);
3287                 break;
3288         case RENDERPATH_CGGL:
3289 #ifdef SUPPORTCG
3290                 R_SetupShader_SetPermutationCG(mode, permutation);
3291                 if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelviewprojection16f);
3292                 if (r_cg_permutation->fp_LightPosition            ) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3293                 if (r_cg_permutation->fp_ViewToLight              ) cgGLSetMatrixParameterfc(r_cg_permutation->fp_ViewToLight, viewtolight16f);
3294                 if (r_cg_permutation->fp_DeferredColor_Ambient    ) cgGLSetParameter3f(r_cg_permutation->fp_DeferredColor_Ambient , lightcolorbase[0] * ambientscale  * range, lightcolorbase[1] * ambientscale  * range, lightcolorbase[2] * ambientscale  * range);
3295                 if (r_cg_permutation->fp_DeferredColor_Diffuse    ) cgGLSetParameter3f(r_cg_permutation->fp_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale  * range, lightcolorbase[1] * diffusescale  * range, lightcolorbase[2] * diffusescale  * range);
3296                 if (r_cg_permutation->fp_DeferredColor_Specular   ) cgGLSetParameter3f(r_cg_permutation->fp_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
3297                 if (r_cg_permutation->fp_ShadowMap_TextureScale   ) cgGLSetParameter2f(r_cg_permutation->fp_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3298                 if (r_cg_permutation->fp_ShadowMap_Parameters     ) cgGLSetParameter4f(r_cg_permutation->fp_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
3299                 if (r_cg_permutation->fp_SpecularPower            ) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
3300                 if (r_cg_permutation->fp_ScreenToDepth            ) cgGLSetParameter2f(r_cg_permutation->fp_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3301
3302                 if (r_cg_permutation->fp_Texture_Attenuation      ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Attenuation    , R_GetTexture(r_shadow_attenuationgradienttexture                 ));
3303                 if (r_cg_permutation->fp_Texture_ScreenDepth      ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ScreenDepth    , R_GetTexture(r_shadow_prepassgeometrydepthtexture                ));
3304                 if (r_cg_permutation->fp_Texture_ScreenNormalMap  ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ScreenNormalMap, R_GetTexture(r_shadow_prepassgeometrynormalmaptexture            ));
3305                 if (r_cg_permutation->fp_Texture_Cube             ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_Cube           , R_GetTexture(rsurface.rtlight->currentcubemap                    ));
3306                 if (r_cg_permutation->fp_Texture_ShadowMapRect    ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ShadowMapRect  , R_GetTexture(r_shadow_shadowmaprectangletexture                  ));
3307                 if (r_shadow_usingshadowmapcube)
3308                         if (r_cg_permutation->fp_Texture_ShadowMapCube    ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ShadowMapCube  , R_GetTexture(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]));
3309                 if (r_cg_permutation->fp_Texture_ShadowMap2D      ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_ShadowMap2D    , R_GetTexture(r_shadow_shadowmap2dtexture                         ));
3310                 if (r_cg_permutation->fp_Texture_CubeProjection   ) cgGLSetTextureParameter(r_cg_permutation->fp_Texture_CubeProjection , R_GetTexture(r_shadow_shadowmapvsdcttexture                      ));
3311 #endif
3312                 break;
3313         case RENDERPATH_GL13:
3314         case RENDERPATH_GL11:
3315                 break;
3316         }
3317 }
3318
3319 #define SKINFRAME_HASH 1024
3320
3321 typedef struct
3322 {
3323         int loadsequence; // incremented each level change
3324         memexpandablearray_t array;
3325         skinframe_t *hash[SKINFRAME_HASH];
3326 }
3327 r_skinframe_t;
3328 r_skinframe_t r_skinframe;
3329
3330 void R_SkinFrame_PrepareForPurge(void)
3331 {
3332         r_skinframe.loadsequence++;
3333         // wrap it without hitting zero
3334         if (r_skinframe.loadsequence >= 200)
3335                 r_skinframe.loadsequence = 1;
3336 }
3337
3338 void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
3339 {
3340         if (!skinframe)
3341                 return;
3342         // mark the skinframe as used for the purging code
3343         skinframe->loadsequence = r_skinframe.loadsequence;
3344 }
3345
3346 void R_SkinFrame_Purge(void)
3347 {
3348         int i;
3349         skinframe_t *s;
3350         for (i = 0;i < SKINFRAME_HASH;i++)
3351         {
3352                 for (s = r_skinframe.hash[i];s;s = s->next)
3353                 {
3354                         if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
3355                         {
3356                                 if (s->merged == s->base)
3357                                         s->merged = NULL;
3358                                 // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
3359                                 R_PurgeTexture(s->stain );s->stain  = NULL;
3360                                 R_PurgeTexture(s->merged);s->merged = NULL;
3361                                 R_PurgeTexture(s->base  );s->base   = NULL;
3362                                 R_PurgeTexture(s->pants );s->pants  = NULL;
3363                                 R_PurgeTexture(s->shirt );s->shirt  = NULL;
3364                                 R_PurgeTexture(s->nmap  );s->nmap   = NULL;
3365                                 R_PurgeTexture(s->gloss );s->gloss  = NULL;
3366                                 R_PurgeTexture(s->glow  );s->glow   = NULL;
3367                                 R_PurgeTexture(s->fog   );s->fog    = NULL;
3368                                 s->loadsequence = 0;
3369                         }
3370                 }
3371         }
3372 }
3373
3374 skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
3375         skinframe_t *item;
3376         char basename[MAX_QPATH];
3377
3378         Image_StripImageExtension(name, basename, sizeof(basename));
3379
3380         if( last == NULL ) {
3381                 int hashindex;
3382                 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
3383                 item = r_skinframe.hash[hashindex];
3384         } else {
3385                 item = last->next;
3386         }
3387
3388         // linearly search through the hash bucket
3389         for( ; item ; item = item->next ) {
3390                 if( !strcmp( item->basename, basename ) ) {
3391                         return item;
3392                 }
3393         }
3394         return NULL;
3395 }
3396
3397 skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
3398 {
3399         skinframe_t *item;
3400         int hashindex;
3401         char basename[MAX_QPATH];
3402
3403         Image_StripImageExtension(name, basename, sizeof(basename));
3404
3405         hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
3406         for (item = r_skinframe.hash[hashindex];item;item = item->next)
3407                 if (!strcmp(item->basename, basename) && item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)
3408                         break;
3409
3410         if (!item) {
3411                 rtexture_t *dyntexture;
3412                 // check whether its a dynamic texture
3413                 dyntexture = CL_GetDynTexture( basename );
3414                 if (!add && !dyntexture)
3415                         return NULL;
3416                 item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
3417                 memset(item, 0, sizeof(*item));
3418                 strlcpy(item->basename, basename, sizeof(item->basename));
3419                 item->base = dyntexture; // either NULL or dyntexture handle
3420                 item->textureflags = textureflags;
3421                 item->comparewidth = comparewidth;
3422                 item->compareheight = compareheight;
3423                 item->comparecrc = comparecrc;
3424                 item->next = r_skinframe.hash[hashindex];
3425                 r_skinframe.hash[hashindex] = item;
3426         }
3427         else if( item->base == NULL )
3428         {
3429                 rtexture_t *dyntexture;
3430                 // check whether its a dynamic texture
3431                 // this only needs to be done because Purge doesnt delete skinframes - only sets the texture pointers to NULL and we need to restore it before returing.. [11/29/2007 Black]
3432                 dyntexture = CL_GetDynTexture( basename );
3433                 item->base = dyntexture; // either NULL or dyntexture handle
3434         }
3435
3436         R_SkinFrame_MarkUsed(item);
3437         return item;
3438 }
3439
3440 #define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \
3441         { \
3442                 unsigned long long avgcolor[5], wsum; \
3443                 int pix, comp, w; \
3444                 avgcolor[0] = 0; \
3445                 avgcolor[1] = 0; \
3446                 avgcolor[2] = 0; \
3447                 avgcolor[3] = 0; \
3448                 avgcolor[4] = 0; \
3449                 wsum = 0; \
3450                 for(pix = 0; pix < cnt; ++pix) \
3451                 { \
3452                         w = 0; \
3453                         for(comp = 0; comp < 3; ++comp) \
3454                                 w += getpixel; \
3455                         if(w) /* ignore perfectly black pixels because that is better for model skins */ \
3456                         { \
3457                                 ++wsum; \
3458                                 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
3459                                 w = getpixel; \
3460                                 for(comp = 0; comp < 3; ++comp) \
3461                                         avgcolor[comp] += getpixel * w; \
3462                                 avgcolor[3] += w; \
3463                         } \
3464                         /* comp = 3; -- not needed, comp is always 3 when we get here */ \
3465                         avgcolor[4] += getpixel; \
3466                 } \
3467                 if(avgcolor[3] == 0) /* no pixels seen? even worse */ \
3468                         avgcolor[3] = 1; \
3469                 skinframe->avgcolor[0] = avgcolor[2] / (255.0 * avgcolor[3]); \
3470                 skinframe->avgcolor[1] = avgcolor[1] / (255.0 * avgcolor[3]); \
3471                 skinframe->avgcolor[2] = avgcolor[0] / (255.0 * avgcolor[3]); \
3472                 skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \
3473         }
3474
3475 skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain)
3476 {
3477         int j;
3478         unsigned char *pixels;
3479         unsigned char *bumppixels;
3480         unsigned char *basepixels = NULL;