GLSL shaders no longer use gl_TextureMatrix, now all matrix parameters
[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", "1", "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_PRECACHE | 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_PRECACHE | 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_PRECACHE | 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_PRECACHE | 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_PRECACHE | 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_PRECACHE | 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[6][NORMSIZE][NORMSIZE][4];
347         for (side = 0;side < 6;side++)
348         {
349                 for (y = 0;y < NORMSIZE;y++)
350                 {
351                         for (x = 0;x < NORMSIZE;x++)
352                         {
353                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
354                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
355                                 switch(side)
356                                 {
357                                 default:
358                                 case 0:
359                                         v[0] = 1;
360                                         v[1] = -t;
361                                         v[2] = -s;
362                                         break;
363                                 case 1:
364                                         v[0] = -1;
365                                         v[1] = -t;
366                                         v[2] = s;
367                                         break;
368                                 case 2:
369                                         v[0] = s;
370                                         v[1] = 1;
371                                         v[2] = t;
372                                         break;
373                                 case 3:
374                                         v[0] = s;
375                                         v[1] = -1;
376                                         v[2] = -t;
377                                         break;
378                                 case 4:
379                                         v[0] = s;
380                                         v[1] = -t;
381                                         v[2] = 1;
382                                         break;
383                                 case 5:
384                                         v[0] = -s;
385                                         v[1] = -t;
386                                         v[2] = -1;
387                                         break;
388                                 }
389                                 intensity = 127.0f / sqrt(DotProduct(v, v));
390                                 data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[0]);
391                                 data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]);
392                                 data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[2]);
393                                 data[side][y][x][3] = 255;
394                         }
395                 }
396         }
397         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
398 }
399
400 static void R_BuildFogTexture(void)
401 {
402         int x, b;
403 #define FOGWIDTH 256
404         unsigned char data1[FOGWIDTH][4];
405         //unsigned char data2[FOGWIDTH][4];
406         double d, r, alpha;
407
408         r_refdef.fogmasktable_start = r_refdef.fog_start;
409         r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
410         r_refdef.fogmasktable_range = r_refdef.fogrange;
411         r_refdef.fogmasktable_density = r_refdef.fog_density;
412
413         r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
414         for (x = 0;x < FOGMASKTABLEWIDTH;x++)
415         {
416                 d = (x * r - r_refdef.fogmasktable_start);
417                 if(developer.integer >= 100)
418                         Con_Printf("%f ", d);
419                 d = max(0, d);
420                 if (r_fog_exp2.integer)
421                         alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
422                 else
423                         alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
424                 if(developer.integer >= 100)
425                         Con_Printf(" : %f ", alpha);
426                 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
427                 if(developer.integer >= 100)
428                         Con_Printf(" = %f\n", alpha);
429                 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
430         }
431
432         for (x = 0;x < FOGWIDTH;x++)
433         {
434                 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
435                 data1[x][0] = b;
436                 data1[x][1] = b;
437                 data1[x][2] = b;
438                 data1[x][3] = 255;
439                 //data2[x][0] = 255 - b;
440                 //data2[x][1] = 255 - b;
441                 //data2[x][2] = 255 - b;
442                 //data2[x][3] = 255;
443         }
444         if (r_texture_fogattenuation)
445         {
446                 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, FOGWIDTH, 1);
447                 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, FOGWIDTH, 1);
448         }
449         else
450         {
451                 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
452                 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
453         }
454 }
455
456 static const char *builtinshaderstring =
457 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
458 "// written by Forest 'LordHavoc' Hale\n"
459 "\n"
460 "// enable various extensions depending on permutation:\n"
461 "\n"
462 "#ifdef MODE_DEPTH_OR_SHADOW\n"
463 "#ifdef VERTEX_SHADER\n"
464 "void main(void)\n"
465 "{\n"
466 "       gl_Position = ftransform();\n"
467 "}\n"
468 "#endif\n"
469 "#else // !MODE_DEPTH_ORSHADOW\n"
470 "#ifdef MODE_SHOWDEPTH\n"
471 "#ifdef VERTEX_SHADER\n"
472 "void main(void)\n"
473 "{\n"
474 "       gl_Position = ftransform();\n"
475 "       gl_FrontColor = vec4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
476 "}\n"
477 "#endif\n"
478 "\n"
479 "#ifdef FRAGMENT_SHADER\n"
480 "void main(void)\n"
481 "{\n"
482 "       gl_FragColor = gl_Color;\n"
483 "}\n"
484 "#endif\n"
485 "#else // !MODE_SHOWDEPTH\n"
486 "#ifdef MODE_POSTPROCESS\n"
487 "#ifdef VERTEX_SHADER\n"
488 "void main(void)\n"
489 "{\n"
490 "       gl_Position = ftransform();\n"
491 "       gl_TexCoord[0] = gl_MultiTexCoord0;\n"
492 "#ifdef USEBLOOM\n"
493 "       gl_TexCoord[1] = gl_MultiTexCoord1;\n"
494 "#endif\n"
495 "}\n"
496 "#endif\n"
497 "\n"
498 "#ifdef FRAGMENT_SHADER\n"
499 "uniform sampler2D Texture_First;\n"
500 "#ifdef USEBLOOM\n"
501 "uniform sampler2D Texture_Second;\n"
502 "#endif\n"
503 "#ifdef USEGAMMARAMPS\n"
504 "uniform sampler2D Texture_GammaRamps;\n"
505 "#endif\n"
506 "#ifdef USESATURATION\n"
507 "uniform float Saturation;\n"
508 "#endif\n"
509 "#ifdef USEVIEWTINT\n"
510 "uniform vec4 ViewTintColor;\n"
511 "#endif\n"
512 "//uncomment these if you want to use them:\n"
513 "uniform vec4 UserVec1;\n"
514 "// uniform vec4 UserVec2;\n"
515 "// uniform vec4 UserVec3;\n"
516 "// uniform vec4 UserVec4;\n"
517 "// uniform float ClientTime;\n"
518 "uniform vec2 PixelSize;\n"
519 "void main(void)\n"
520 "{\n"
521 "       gl_FragColor = texture2D(Texture_First, gl_TexCoord[0].xy);\n"
522 "#ifdef USEBLOOM\n"
523 "       gl_FragColor += texture2D(Texture_Second, gl_TexCoord[1].xy);\n"
524 "#endif\n"
525 "#ifdef USEVIEWTINT\n"
526 "       gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
527 "#endif\n"
528 "\n"
529 "#ifdef USEPOSTPROCESSING\n"
530 "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
531 "// 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"
532 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
533 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
534 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
535 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.707107,  0.707107)) * UserVec1.y;\n"
536 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.453990,  0.891007)) * UserVec1.y;\n"
537 "       gl_FragColor /= (1 + 5 * UserVec1.y);\n"
538 "#endif\n"
539 "\n"
540 "#ifdef USESATURATION\n"
541 "       //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
542 "       float y = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));\n"
543 "       //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
544 "       gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
545 "#endif\n"
546 "\n"
547 "#ifdef USEGAMMARAMPS\n"
548 "       gl_FragColor.r = texture2D(Texture_GammaRamps, vec2(gl_FragColor.r, 0)).r;\n"
549 "       gl_FragColor.g = texture2D(Texture_GammaRamps, vec2(gl_FragColor.g, 0)).g;\n"
550 "       gl_FragColor.b = texture2D(Texture_GammaRamps, vec2(gl_FragColor.b, 0)).b;\n"
551 "#endif\n"
552 "}\n"
553 "#endif\n"
554 "#else // !MODE_POSTPROCESS\n"
555 "#ifdef MODE_GENERIC\n"
556 "#ifdef VERTEX_SHADER\n"
557 "void main(void)\n"
558 "{\n"
559 "       gl_FrontColor = gl_Color;\n"
560 "#ifdef USEDIFFUSE\n"
561 "       gl_TexCoord[0] = gl_MultiTexCoord0;\n"
562 "#endif\n"
563 "#ifdef USESPECULAR\n"
564 "       gl_TexCoord[1] = gl_MultiTexCoord1;\n"
565 "#endif\n"
566 "       gl_Position = ftransform();\n"
567 "}\n"
568 "#endif\n"
569 "\n"
570 "#ifdef FRAGMENT_SHADER\n"
571 "#ifdef USEDIFFUSE\n"
572 "uniform sampler2D Texture_First;\n"
573 "#endif\n"
574 "#ifdef USESPECULAR\n"
575 "uniform sampler2D Texture_Second;\n"
576 "#endif\n"
577 "\n"
578 "void main(void)\n"
579 "{\n"
580 "       gl_FragColor = gl_Color;\n"
581 "#ifdef USEDIFFUSE\n"
582 "       gl_FragColor *= texture2D(Texture_First, gl_TexCoord[0].xy);\n"
583 "#endif\n"
584 "\n"
585 "#ifdef USESPECULAR\n"
586 "       vec4 tex2 = texture2D(Texture_Second, gl_TexCoord[1].xy);\n"
587 "#endif\n"
588 "#ifdef USECOLORMAPPING\n"
589 "       gl_FragColor *= tex2;\n"
590 "#endif\n"
591 "#ifdef USEGLOW\n"
592 "       gl_FragColor += tex2;\n"
593 "#endif\n"
594 "#ifdef USEVERTEXTEXTUREBLEND\n"
595 "       gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
596 "#endif\n"
597 "}\n"
598 "#endif\n"
599 "#else // !MODE_GENERIC\n"
600 "#ifdef MODE_BLOOMBLUR\n"
601 "#ifdef VERTEX_SHADER\n"
602 "void main(void)\n"
603 "{\n"
604 "       gl_FrontColor = gl_Color;\n"
605 "       gl_TexCoord[0] = gl_MultiTexCoord0;\n"
606 "       gl_Position = ftransform();\n"
607 "}\n"
608 "#endif\n"
609 "\n"
610 "#ifdef FRAGMENT_SHADER\n"
611 "uniform sampler2D Texture_First;\n"
612 "uniform vec4 BloomBlur_Parameters;\n"
613 "\n"
614 "void main(void)\n"
615 "{\n"
616 "       int i;\n"
617 "       vec2 tc = gl_TexCoord[0].xy;\n"
618 "       vec3 color = texture2D(Texture_First, tc).rgb;\n"
619 "       tc += BloomBlur_Parameters.xy;\n"
620 "       for (i = 1;i < SAMPLES;i++)\n"
621 "       {\n"
622 "               color += texture2D(Texture_First, tc).rgb;\n"
623 "               tc += BloomBlur_Parameters.xy;\n"
624 "       }\n"
625 "       gl_FragColor = vec4(color * BloomBlur_Parameters.z + vec3(BloomBlur_Parameters.w), 1);\n"
626 "}\n"
627 "#endif\n"
628 "#else // !MODE_BLOOMBLUR\n"
629 "#ifdef MODE_REFRACTION\n"
630 "varying vec2 TexCoord;\n"
631 "varying vec4 ModelViewProjectionPosition;\n"
632 "uniform mat4 TexMatrix;\n"
633 "#ifdef VERTEX_SHADER\n"
634 "\n"
635 "void main(void)\n"
636 "{\n"
637 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
638 "       gl_Position = ftransform();\n"
639 "       ModelViewProjectionPosition = gl_Position;\n"
640 "}\n"
641 "#endif\n"
642 "\n"
643 "#ifdef FRAGMENT_SHADER\n"
644 "uniform sampler2D Texture_Normal;\n"
645 "uniform sampler2D Texture_Refraction;\n"
646 "uniform sampler2D Texture_Reflection;\n"
647 "\n"
648 "uniform vec4 DistortScaleRefractReflect;\n"
649 "uniform vec4 ScreenScaleRefractReflect;\n"
650 "uniform vec4 ScreenCenterRefractReflect;\n"
651 "uniform vec4 RefractColor;\n"
652 "uniform vec4 ReflectColor;\n"
653 "uniform float ReflectFactor;\n"
654 "uniform float ReflectOffset;\n"
655 "\n"
656 "void main(void)\n"
657 "{\n"
658 "       vec2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
659 "       //vec2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
660 "       vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
661 "       vec2 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
662 "       // FIXME temporary hack to detect the case that the reflection\n"
663 "       // gets blackened at edges due to leaving the area that contains actual\n"
664 "       // content.\n"
665 "       // Remove this 'ack once we have a better way to stop this thing from\n"
666 "       // 'appening.\n"
667 "       float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
668 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
669 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
670 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
671 "       ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
672 "       gl_FragColor = texture2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
673 "}\n"
674 "#endif\n"
675 "#else // !MODE_REFRACTION\n"
676 "#ifdef MODE_WATER\n"
677 "varying vec2 TexCoord;\n"
678 "varying vec3 EyeVector;\n"
679 "varying vec4 ModelViewProjectionPosition;\n"
680 "#ifdef VERTEX_SHADER\n"
681 "uniform vec3 EyePosition;\n"
682 "uniform mat4 TexMatrix;\n"
683 "\n"
684 "void main(void)\n"
685 "{\n"
686 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
687 "       vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
688 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
689 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
690 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
691 "       gl_Position = ftransform();\n"
692 "       ModelViewProjectionPosition = gl_Position;\n"
693 "}\n"
694 "#endif\n"
695 "\n"
696 "#ifdef FRAGMENT_SHADER\n"
697 "uniform sampler2D Texture_Normal;\n"
698 "uniform sampler2D Texture_Refraction;\n"
699 "uniform sampler2D Texture_Reflection;\n"
700 "\n"
701 "uniform vec4 DistortScaleRefractReflect;\n"
702 "uniform vec4 ScreenScaleRefractReflect;\n"
703 "uniform vec4 ScreenCenterRefractReflect;\n"
704 "uniform vec4 RefractColor;\n"
705 "uniform vec4 ReflectColor;\n"
706 "uniform float ReflectFactor;\n"
707 "uniform float ReflectOffset;\n"
708 "\n"
709 "void main(void)\n"
710 "{\n"
711 "       vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
712 "       //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
713 "       vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
714 "       vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
715 "       // FIXME temporary hack to detect the case that the reflection\n"
716 "       // gets blackened at edges due to leaving the area that contains actual\n"
717 "       // content.\n"
718 "       // Remove this 'ack once we have a better way to stop this thing from\n"
719 "       // 'appening.\n"
720 "       float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, 0.01)).rgb) / 0.05);\n"
721 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, -0.01)).rgb) / 0.05);\n"
722 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
723 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
724 "       ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
725 "       f       = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, 0.01)).rgb) / 0.05);\n"
726 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, -0.01)).rgb) / 0.05);\n"
727 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
728 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
729 "       ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
730 "       float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
731 "       gl_FragColor = mix(texture2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, texture2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
732 "}\n"
733 "#endif\n"
734 "#else // !MODE_WATER\n"
735 "\n"
736 "#if defined(USESHADOWMAPRECT) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USEDEFERREDLIGHTMAP)\n"
737 "# extension GL_ARB_texture_rectangle : enable\n"
738 "#endif\n"
739 "\n"
740 "#ifdef USESHADOWMAP2D\n"
741 "# ifdef GL_EXT_gpu_shader4\n"
742 "#   extension GL_EXT_gpu_shader4 : enable\n"
743 "# endif\n"
744 "# ifdef GL_ARB_texture_gather\n"
745 "#   extension GL_ARB_texture_gather : enable\n"
746 "# else\n"
747 "#   ifdef GL_AMD_texture_texture4\n"
748 "#     extension GL_AMD_texture_texture4 : enable\n"
749 "#   endif\n"
750 "# endif\n"
751 "#endif\n"
752 "\n"
753 "#ifdef USESHADOWMAPCUBE\n"
754 "# extension GL_EXT_gpu_shader4 : enable\n"
755 "#endif\n"
756 "\n"
757 "#ifdef USESHADOWSAMPLER\n"
758 "# extension GL_ARB_shadow : enable\n"
759 "#endif\n"
760 "\n"
761 "// common definitions between vertex shader and fragment shader:\n"
762 "\n"
763 "//#ifdef __GLSL_CG_DATA_TYPES\n"
764 "//# define myhalf half\n"
765 "//# define myhalf2 half2\n"
766 "//# define myhalf3half3\n"
767 "//# define myhalf4 half4\n"
768 "//#else\n"
769 "# define myhalf float\n"
770 "# define myhalf2 vec2\n"
771 "# define myhalf3 vec3\n"
772 "# define myhalf4 vec4\n"
773 "//#endif\n"
774 "\n"
775 "#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
776 "# define USEFOG\n"
777 "#endif\n"
778 "\n"
779 "varying vec2 TexCoord;\n"
780 "#ifdef USEVERTEXTEXTUREBLEND\n"
781 "varying vec2 TexCoord2;\n"
782 "#endif\n"
783 "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
784 "#define USELIGHTMAP\n"
785 "varying vec2 TexCoordLightmap;\n"
786 "#endif\n"
787 "\n"
788 "#ifdef MODE_LIGHTSOURCE\n"
789 "varying vec3 CubeVector;\n"
790 "#endif\n"
791 "\n"
792 "#ifdef MODE_LIGHTSOURCE\n"
793 "varying vec3 LightVector;\n"
794 "#endif\n"
795 "#if defined(MODE_LIGHTDIRECTION)\n"
796 "varying vec3 LightVector;\n"
797 "#endif\n"
798 "\n"
799 "#if defined(USEOFFSETMAPPING) || defined(USESPECULAR)\n"
800 "//#if defined(USEOFFSETMAPPING) || defined(USESPECULAR) || defined(MODE_LIGHTDIRECTION) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
801 "#define USEEYEVECTOR\n"
802 "varying vec3 EyeVector;\n"
803 "#endif\n"
804 "#ifdef USEFOG\n"
805 "varying vec3 EyeVectorModelSpace;\n"
806 "varying float FogPlaneVertexDist;\n"
807 "#endif\n"
808 "\n"
809 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
810 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
811 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
812 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
813 "#endif\n"
814 "\n"
815 "#ifdef USEREFLECTION\n"
816 "varying vec4 ModelViewProjectionPosition;\n"
817 "#endif\n"
818 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
819 "uniform vec3 LightPosition;\n"
820 "varying vec4 ModelViewPosition;\n"
821 "#endif\n"
822 "\n"
823 "#ifdef MODE_LIGHTSOURCE\n"
824 "uniform vec3 LightPosition;\n"
825 "#endif\n"
826 "uniform vec3 EyePosition;\n"
827 "#ifdef MODE_LIGHTDIRECTION\n"
828 "uniform vec3 LightDir;\n"
829 "#endif\n"
830 "uniform vec4 FogPlane;\n"
831 "\n"
832 "\n"
833 "\n"
834 "\n"
835 "\n"
836 "// vertex shader specific:\n"
837 "#ifdef VERTEX_SHADER\n"
838 "\n"
839 "// 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"
840 "\n"
841 "#ifdef MODE_DEFERREDGEOMETRY\n"
842 "uniform mat4 TexMatrix;\n"
843 "#ifdef USEVERTEXTEXTUREBLEND\n"
844 "uniform mat4 BackgroundTexMatrix;\n"
845 "#endif\n"
846 "void main(void)\n"
847 "{\n"
848 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
849 "#ifdef USEVERTEXTEXTUREBLEND\n"
850 "       gl_FrontColor = gl_Color;\n"
851 "       TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
852 "#endif\n"
853 "\n"
854 "       // transform unnormalized eye direction into tangent space\n"
855 "#ifdef USEOFFSETMAPPING\n"
856 "       vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
857 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
858 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
859 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
860 "#endif\n"
861 "\n"
862 "       VectorS = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz).xyz;\n"
863 "       VectorT = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz).xyz;\n"
864 "       VectorR = normalize(gl_NormalMatrix * gl_MultiTexCoord3.xyz).xyz;\n"
865 "       gl_Position = ftransform();\n"
866 "}\n"
867 "#else // !MODE_DEFERREDGEOMETRY\n"
868 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
869 "void main(void)\n"
870 "{\n"
871 "       ModelViewPosition = gl_ModelViewMatrix * gl_Vertex;\n"
872 "       gl_Position = ftransform();\n"
873 "}\n"
874 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
875 "uniform mat4 TexMatrix;\n"
876 "#ifdef USEVERTEXTEXTUREBLEND\n"
877 "uniform mat4 BackgroundTexMatrix;\n"
878 "#endif\n"
879 "#ifdef MODE_LIGHTSOURCE\n"
880 "uniform mat4 ModelToLight;\n"
881 "#endif\n"
882 "void main(void)\n"
883 "{\n"
884 "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
885 "       gl_FrontColor = gl_Color;\n"
886 "#endif\n"
887 "       // copy the surface texcoord\n"
888 "       TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
889 "#ifdef USEVERTEXTEXTUREBLEND\n"
890 "       TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
891 "#endif\n"
892 "#ifdef USELIGHTMAP\n"
893 "       TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
894 "#endif\n"
895 "\n"
896 "#ifdef MODE_LIGHTSOURCE\n"
897 "       // transform vertex position into light attenuation/cubemap space\n"
898 "       // (-1 to +1 across the light box)\n"
899 "       CubeVector = vec3(ModelToLight * gl_Vertex);\n"
900 "\n"
901 "# ifdef USEDIFFUSE\n"
902 "       // transform unnormalized light direction into tangent space\n"
903 "       // (we use unnormalized to ensure that it interpolates correctly and then\n"
904 "       //  normalize it per pixel)\n"
905 "       vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
906 "       LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
907 "       LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
908 "       LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
909 "# endif\n"
910 "#endif\n"
911 "\n"
912 "#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
913 "       LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
914 "       LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
915 "       LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
916 "#endif\n"
917 "\n"
918 "       // transform unnormalized eye direction into tangent space\n"
919 "#ifdef USEEYEVECTOR\n"
920 "#ifndef USEFOG\n"
921 "       vec3 EyeVectorModelSpace;\n"
922 "#endif\n"
923 "       EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
924 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
925 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
926 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
927 "#endif\n"
928 "\n"
929 "#ifdef USEFOG\n"
930 "#ifndef USEEYEVECTOR\n"
931 "       EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
932 "#endif\n"
933 "       FogPlaneVertexDist = dot(FogPlane, gl_Vertex);\n"
934 "#endif\n"
935 "\n"
936 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
937 "       VectorS = gl_MultiTexCoord1.xyz;\n"
938 "       VectorT = gl_MultiTexCoord2.xyz;\n"
939 "       VectorR = gl_MultiTexCoord3.xyz;\n"
940 "#endif\n"
941 "\n"
942 "//#if defined(USEREFLECTION)\n"
943 "//     ModelViewProjectionPosition = gl_Vertex * gl_ModelViewProjectionMatrix;\n"
944 "//     //ModelViewProjectionPosition_svector = (gl_Vertex + vec4(gl_MultiTexCoord1.xyz, 0)) * gl_ModelViewProjectionMatrix - ModelViewProjectionPosition;\n"
945 "//     //ModelViewProjectionPosition_tvector = (gl_Vertex + vec4(gl_MultiTexCoord2.xyz, 0)) * gl_ModelViewProjectionMatrix - ModelViewProjectionPosition;\n"
946 "//#endif\n"
947 "\n"
948 "// transform vertex to camera space, using ftransform to match non-VS\n"
949 "       // rendering\n"
950 "       gl_Position = ftransform();\n"
951 "\n"
952 "#ifdef USEREFLECTION\n"
953 "       ModelViewProjectionPosition = gl_Position;\n"
954 "#endif\n"
955 "}\n"
956 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
957 "#endif // !MODE_DEFERREDGEOMETRY\n"
958 "\n"
959 "#endif // VERTEX_SHADER\n"
960 "\n"
961 "\n"
962 "\n"
963 "\n"
964 "// fragment shader specific:\n"
965 "#ifdef FRAGMENT_SHADER\n"
966 "\n"
967 "uniform sampler2D Texture_Normal;\n"
968 "uniform sampler2D Texture_Color;\n"
969 "//#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
970 "uniform sampler2D Texture_Gloss;\n"
971 "//#endif\n"
972 "#ifdef USEGLOW\n"
973 "uniform sampler2D Texture_Glow;\n"
974 "#endif\n"
975 "#ifdef USEVERTEXTEXTUREBLEND\n"
976 "uniform sampler2D Texture_SecondaryNormal;\n"
977 "uniform sampler2D Texture_SecondaryColor;\n"
978 "//#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
979 "uniform sampler2D Texture_SecondaryGloss;\n"
980 "//#endif\n"
981 "#ifdef USEGLOW\n"
982 "uniform sampler2D Texture_SecondaryGlow;\n"
983 "#endif\n"
984 "#endif\n"
985 "#ifdef USECOLORMAPPING\n"
986 "uniform sampler2D Texture_Pants;\n"
987 "uniform sampler2D Texture_Shirt;\n"
988 "#endif\n"
989 "#ifdef USEFOG\n"
990 "uniform sampler2D Texture_FogMask;\n"
991 "#endif\n"
992 "#ifdef USELIGHTMAP\n"
993 "uniform sampler2D Texture_Lightmap;\n"
994 "#endif\n"
995 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
996 "uniform sampler2D Texture_Deluxemap;\n"
997 "#endif\n"
998 "#ifdef USEREFLECTION\n"
999 "uniform sampler2D Texture_Reflection;\n"
1000 "#endif\n"
1001 "\n"
1002 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
1003 "uniform sampler2DRect Texture_ScreenDepth;\n"
1004 "uniform sampler2DRect Texture_ScreenNormalMap;\n"
1005 "#endif\n"
1006 "#ifdef USEDEFERREDLIGHTMAP\n"
1007 "uniform sampler2DRect Texture_ScreenDiffuse;\n"
1008 "uniform sampler2DRect Texture_ScreenSpecular;\n"
1009 "#endif\n"
1010 "\n"
1011 "uniform myhalf3 Color_Pants;\n"
1012 "uniform myhalf3 Color_Shirt;\n"
1013 "uniform myhalf3 FogColor;\n"
1014 "\n"
1015 "#ifdef USEFOG\n"
1016 "uniform float FogRangeRecip;\n"
1017 "uniform float FogPlaneViewDist;\n"
1018 "uniform float FogHeightFade;\n"
1019 "myhalf FogVertex(void)\n"
1020 "{\n"
1021 "       float fogfrac;\n"
1022 "#ifdef USEFOGOUTSIDE\n"
1023 "       fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
1024 "#else\n"
1025 "       fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
1026 "#endif\n"
1027 "       return myhalf(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
1028 "}\n"
1029 "#endif\n"
1030 "\n"
1031 "#ifdef USEOFFSETMAPPING\n"
1032 "uniform float OffsetMapping_Scale;\n"
1033 "vec2 OffsetMapping(vec2 TexCoord)\n"
1034 "{\n"
1035 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
1036 "       // 14 sample relief mapping: linear search and then binary search\n"
1037 "       // this basically steps forward a small amount repeatedly until it finds\n"
1038 "       // itself inside solid, then jitters forward and back using decreasing\n"
1039 "       // amounts to find the impact\n"
1040 "       //vec3 OffsetVector = vec3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1), -1);\n"
1041 "       //vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
1042 "       vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
1043 "       vec3 RT = vec3(TexCoord, 1);\n"
1044 "       OffsetVector *= 0.1;\n"
1045 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1046 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1047 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1048 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1049 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1050 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1051 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1052 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1053 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1054 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z)          - 0.5);\n"
1055 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.5    - 0.25);\n"
1056 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.25   - 0.125);\n"
1057 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.125  - 0.0625);\n"
1058 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
1059 "       return RT.xy;\n"
1060 "#else\n"
1061 "       // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
1062 "       // this basically moves forward the full distance, and then backs up based\n"
1063 "       // on height of samples\n"
1064 "       //vec2 OffsetVector = vec2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1));\n"
1065 "       //vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1));\n"
1066 "       vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1));\n"
1067 "       TexCoord += OffsetVector;\n"
1068 "       OffsetVector *= 0.333;\n"
1069 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1070 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1071 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1072 "       return TexCoord;\n"
1073 "#endif\n"
1074 "}\n"
1075 "#endif // USEOFFSETMAPPING\n"
1076 "\n"
1077 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
1078 "uniform sampler2D Texture_Attenuation;\n"
1079 "uniform samplerCube Texture_Cube;\n"
1080 "\n"
1081 "#ifdef USESHADOWMAPRECT\n"
1082 "# ifdef USESHADOWSAMPLER\n"
1083 "uniform sampler2DRectShadow Texture_ShadowMapRect;\n"
1084 "# else\n"
1085 "uniform sampler2DRect Texture_ShadowMapRect;\n"
1086 "# endif\n"
1087 "#endif\n"
1088 "\n"
1089 "#ifdef USESHADOWMAP2D\n"
1090 "# ifdef USESHADOWSAMPLER\n"
1091 "uniform sampler2DShadow Texture_ShadowMap2D;\n"
1092 "# else\n"
1093 "uniform sampler2D Texture_ShadowMap2D;\n"
1094 "# endif\n"
1095 "#endif\n"
1096 "\n"
1097 "#ifdef USESHADOWMAPVSDCT\n"
1098 "uniform samplerCube Texture_CubeProjection;\n"
1099 "#endif\n"
1100 "\n"
1101 "#ifdef USESHADOWMAPCUBE\n"
1102 "# ifdef USESHADOWSAMPLER\n"
1103 "uniform samplerCubeShadow Texture_ShadowMapCube;\n"
1104 "# else\n"
1105 "uniform samplerCube Texture_ShadowMapCube;\n"
1106 "# endif\n"
1107 "#endif\n"
1108 "\n"
1109 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
1110 "uniform vec2 ShadowMap_TextureScale;\n"
1111 "uniform vec4 ShadowMap_Parameters;\n"
1112 "#endif\n"
1113 "\n"
1114 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
1115 "vec3 GetShadowMapTC2D(vec3 dir)\n"
1116 "{\n"
1117 "       vec3 adir = abs(dir);\n"
1118 "# ifndef USESHADOWMAPVSDCT\n"
1119 "       vec2 tc;\n"
1120 "       vec2 offset;\n"
1121 "       float ma;\n"
1122 "       if (adir.x > adir.y)\n"
1123 "       {\n"
1124 "               if (adir.x > adir.z) // X\n"
1125 "               {\n"
1126 "                       ma = adir.x;\n"
1127 "                       tc = dir.zy;\n"
1128 "                       offset = vec2(mix(0.5, 1.5, dir.x < 0.0), 0.5);\n"
1129 "               }\n"
1130 "               else // Z\n"
1131 "               {\n"
1132 "                       ma = adir.z;\n"
1133 "                       tc = dir.xy;\n"
1134 "                       offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
1135 "               }\n"
1136 "       }\n"
1137 "       else\n"
1138 "       {\n"
1139 "               if (adir.y > adir.z) // Y\n"
1140 "               {\n"
1141 "                       ma = adir.y;\n"
1142 "                       tc = dir.xz;\n"
1143 "                       offset = vec2(mix(0.5, 1.5, dir.y < 0.0), 1.5);\n"
1144 "               }\n"
1145 "               else // Z\n"
1146 "               {\n"
1147 "                       ma = adir.z;\n"
1148 "                       tc = dir.xy;\n"
1149 "                       offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
1150 "               }\n"
1151 "       }\n"
1152 "\n"
1153 "       vec3 stc = vec3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
1154 "       stc.xy += offset * ShadowMap_Parameters.y;\n"
1155 "       stc.z += ShadowMap_Parameters.z;\n"
1156 "       return stc;\n"
1157 "# else\n"
1158 "       vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
1159 "       float ma = max(max(adir.x, adir.y), adir.z);\n"
1160 "       vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
1161 "       stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
1162 "       stc.z += ShadowMap_Parameters.z;\n"
1163 "       return stc;\n"
1164 "# endif\n"
1165 "}\n"
1166 "#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
1167 "\n"
1168 "#ifdef USESHADOWMAPCUBE\n"
1169 "vec4 GetShadowMapTCCube(vec3 dir)\n"
1170 "{\n"
1171 "    vec3 adir = abs(dir);\n"
1172 "    return vec4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
1173 "}\n"
1174 "#endif\n"
1175 "\n"
1176 "# ifdef USESHADOWMAPRECT\n"
1177 "float ShadowMapCompare(vec3 dir)\n"
1178 "{\n"
1179 "       vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
1180 "       float f;\n"
1181 "#  ifdef USESHADOWSAMPLER\n"
1182 "\n"
1183 "#    ifdef USESHADOWMAPPCF\n"
1184 "#      define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + vec3(x, y, 0.0)).r\n"
1185 "    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"
1186 "#    else\n"
1187 "    f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
1188 "#    endif\n"
1189 "\n"
1190 "#  else\n"
1191 "\n"
1192 "#    ifdef USESHADOWMAPPCF\n"
1193 "#      if USESHADOWMAPPCF > 1\n"
1194 "#        define texval(x, y) texture2DRect(Texture_ShadowMapRect, center + vec2(x, y)).r\n"
1195 "    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
1196 "    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"
1197 "    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"
1198 "    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"
1199 "    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"
1200 "    vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
1201 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1202 "#      else\n"
1203 "#        define texval(x, y) texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(x, y)).r\n"
1204 "    vec2 offset = fract(shadowmaptc.xy);\n"
1205 "    vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
1206 "    vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
1207 "    vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
1208 "    vec3 cols = row2 + mix(row1, row3, offset.y);\n"
1209 "    f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
1210 "#      endif\n"
1211 "#    else\n"
1212 "    f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
1213 "#    endif\n"
1214 "\n"
1215 "#  endif\n"
1216 "       return f;\n"
1217 "}\n"
1218 "# endif\n"
1219 "\n"
1220 "# ifdef USESHADOWMAP2D\n"
1221 "float ShadowMapCompare(vec3 dir)\n"
1222 "{\n"
1223 "    vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
1224 "    float f;\n"
1225 "\n"
1226 "#  ifdef USESHADOWSAMPLER\n"
1227 "#    ifdef USESHADOWMAPPCF\n"
1228 "#      define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r  \n"
1229 "    vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
1230 "    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"
1231 "#    else\n"
1232 "    f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
1233 "#    endif\n"
1234 "#  else\n"
1235 "#    ifdef USESHADOWMAPPCF\n"
1236 "#     if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
1237 "#      ifdef GL_ARB_texture_gather\n"
1238 "#        define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec(x, y))\n"
1239 "#      else\n"
1240 "#        define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x,y)*ShadowMap_TextureScale)\n"
1241 "#      endif\n"
1242 "    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
1243 "    center *= ShadowMap_TextureScale;\n"
1244 "    vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
1245 "    vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
1246 "    vec4 group3 = step(shadowmaptc.z, texval(-1.0,  1.0));\n"
1247 "    vec4 group4 = step(shadowmaptc.z, texval( 1.0,  1.0));\n"
1248 "    vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
1249 "                mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
1250 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1251 "#     else\n"
1252 "#      ifdef GL_EXT_gpu_shader4\n"
1253 "#        define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n"
1254 "#      else\n"
1255 "#        define texval(x, y) texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r  \n"
1256 "#      endif\n"
1257 "#      if USESHADOWMAPPCF > 1\n"
1258 "    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
1259 "    center *= ShadowMap_TextureScale;\n"
1260 "    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"
1261 "    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"
1262 "    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"
1263 "    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"
1264 "    vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
1265 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1266 "#      else\n"
1267 "    vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
1268 "    vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
1269 "    vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0,  0.0), texval( 0.0,  0.0), texval( 1.0,  0.0)));\n"
1270 "    vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0,  1.0), texval( 0.0,  1.0), texval( 1.0,  1.0)));\n"
1271 "    vec3 cols = row2 + mix(row1, row3, offset.y);\n"
1272 "    f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
1273 "#      endif\n"
1274 "#     endif\n"
1275 "#    else\n"
1276 "    f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
1277 "#    endif\n"
1278 "#  endif\n"
1279 "    return f;\n"
1280 "}\n"
1281 "# endif\n"
1282 "\n"
1283 "# ifdef USESHADOWMAPCUBE\n"
1284 "float ShadowMapCompare(vec3 dir)\n"
1285 "{\n"
1286 "    // apply depth texture cubemap as light filter\n"
1287 "    vec4 shadowmaptc = GetShadowMapTCCube(dir);\n"
1288 "    float f;\n"
1289 "#  ifdef USESHADOWSAMPLER\n"
1290 "    f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
1291 "#  else\n"
1292 "    f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
1293 "#  endif\n"
1294 "    return f;\n"
1295 "}\n"
1296 "# endif\n"
1297 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
1298 "\n"
1299 "#ifdef MODE_DEFERREDGEOMETRY\n"
1300 "void main(void)\n"
1301 "{\n"
1302 "#ifdef USEOFFSETMAPPING\n"
1303 "       // apply offsetmapping\n"
1304 "       vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1305 "#define TexCoord TexCoordOffset\n"
1306 "#endif\n"
1307 "\n"
1308 "#ifdef USEALPHAKILL\n"
1309 "       if (texture2D(Texture_Color, TexCoord).a < 0.5)\n"
1310 "               discard;\n"
1311 "#endif\n"
1312 "\n"
1313 "#ifdef USEVERTEXTEXTUREBLEND\n"
1314 "       float alpha = texture2D(Texture_Color, TexCoord).a;\n"
1315 "       float terrainblend = clamp(float(gl_Color.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
1316 "       //float terrainblend = min(float(gl_Color.a) * alpha * 2.0, float(1.0));\n"
1317 "       //float terrainblend = float(gl_Color.a) * alpha > 0.5;\n"
1318 "#endif\n"
1319 "\n"
1320 "#ifdef USEVERTEXTEXTUREBLEND\n"
1321 "       vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(texture2D(Texture_Normal, TexCoord)), terrainblend) - vec3(0.5, 0.5, 0.5);\n"
1322 "#else\n"
1323 "       vec3 surfacenormal = vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5, 0.5, 0.5);\n"
1324 "#endif\n"
1325 "\n"
1326 "       gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), 1);\n"
1327 "}\n"
1328 "#else // !MODE_DEFERREDGEOMETRY\n"
1329 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
1330 "uniform mat4 ViewToLight;\n"
1331 "// ScreenToDepth = vec2(Far / (Far - Near), Far * Near / (Near - Far));\n"
1332 "uniform vec2 ScreenToDepth;\n"
1333 "uniform myhalf3 DeferredColor_Ambient;\n"
1334 "uniform myhalf3 DeferredColor_Diffuse;\n"
1335 "#ifdef USESPECULAR\n"
1336 "uniform myhalf3 DeferredColor_Specular;\n"
1337 "uniform myhalf SpecularPower;\n"
1338 "#endif\n"
1339 "void main(void)\n"
1340 "{\n"
1341 "       // calculate viewspace pixel position\n"
1342 "       vec3 position;\n"
1343 "       position.z = ScreenToDepth.y / (texture2DRect(Texture_ScreenDepth, gl_FragCoord.xy).r + ScreenToDepth.x);\n"
1344 "       position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
1345 "       // decode viewspace pixel normal\n"
1346 "       myhalf4 normalmap = texture2DRect(Texture_ScreenNormalMap, gl_FragCoord.xy);\n"
1347 "       myhalf3 surfacenormal = normalize(normalmap.rgb - myhalf3(0.5,0.5,0.5));\n"
1348 "       // surfacenormal = pixel normal in viewspace\n"
1349 "       // LightVector = pixel to light in viewspace\n"
1350 "       // CubeVector = position in lightspace\n"
1351 "       // eyevector = pixel to view in viewspace\n"
1352 "       vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n"
1353 "       myhalf fade = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
1354 "#ifdef USEDIFFUSE\n"
1355 "       // calculate diffuse shading\n"
1356 "       myhalf3 lightnormal = myhalf3(normalize(LightPosition - position));\n"
1357 "       myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1358 "#endif\n"
1359 "#ifdef USESPECULAR\n"
1360 "       // calculate directional shading\n"
1361 "       vec3 eyevector = position * -1.0;\n"
1362 "#  ifdef USEEXACTSPECULARMATH\n"
1363 "       myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower);\n"
1364 "#  else\n"
1365 "       myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(eyevector)));\n"
1366 "       myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1367 "#  endif\n"
1368 "#endif\n"
1369 "\n"
1370 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
1371 "       fade *= ShadowMapCompare(CubeVector);\n"
1372 "#endif\n"
1373 "\n"
1374 "#ifdef USEDIFFUSE\n"
1375 "       gl_FragData[0] = vec4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
1376 "#else\n"
1377 "       gl_FragData[0] = vec4(DeferredColor_Ambient * fade, 1.0);\n"
1378 "#endif\n"
1379 "#ifdef USESPECULAR\n"
1380 "       gl_FragData[1] = vec4(DeferredColor_Specular * (specular * fade), 1.0);\n"
1381 "#else\n"
1382 "       gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0);\n"
1383 "#endif\n"
1384 "\n"
1385 "# ifdef USECUBEFILTER\n"
1386 "       vec3 cubecolor = textureCube(Texture_Cube, CubeVector).rgb;\n"
1387 "       gl_FragData[0] *= cubecolor;\n"
1388 "       gl_FragData[1] *= cubecolor;\n"
1389 "# endif\n"
1390 "}\n"
1391 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
1392 "#ifdef USEDEFERREDLIGHTMAP\n"
1393 "uniform myhalf3 DeferredMod_Diffuse;\n"
1394 "uniform myhalf3 DeferredMod_Specular;\n"
1395 "#endif\n"
1396 "uniform myhalf3 Color_Ambient;\n"
1397 "uniform myhalf3 Color_Diffuse;\n"
1398 "uniform myhalf3 Color_Specular;\n"
1399 "uniform myhalf SpecularPower;\n"
1400 "#ifdef USEGLOW\n"
1401 "uniform myhalf3 Color_Glow;\n"
1402 "#endif\n"
1403 "uniform myhalf Alpha;\n"
1404 "#ifdef USEREFLECTION\n"
1405 "uniform vec4 DistortScaleRefractReflect;\n"
1406 "uniform vec4 ScreenScaleRefractReflect;\n"
1407 "uniform vec4 ScreenCenterRefractReflect;\n"
1408 "uniform myhalf4 ReflectColor;\n"
1409 "#endif\n"
1410 "#ifdef MODE_LIGHTDIRECTION\n"
1411 "uniform myhalf3 LightColor;\n"
1412 "#endif\n"
1413 "#ifdef MODE_LIGHTSOURCE\n"
1414 "uniform myhalf3 LightColor;\n"
1415 "#endif\n"
1416 "void main(void)\n"
1417 "{\n"
1418 "#ifdef USEOFFSETMAPPING\n"
1419 "       // apply offsetmapping\n"
1420 "       vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1421 "#define TexCoord TexCoordOffset\n"
1422 "#endif\n"
1423 "\n"
1424 "       // combine the diffuse textures (base, pants, shirt)\n"
1425 "       myhalf4 color = myhalf4(texture2D(Texture_Color, TexCoord));\n"
1426 "#ifdef USEALPHAKILL\n"
1427 "       if (color.a < 0.5)\n"
1428 "               discard;\n"
1429 "#endif\n"
1430 "       color.a *= Alpha;\n"
1431 "#ifdef USECOLORMAPPING\n"
1432 "       color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
1433 "#endif\n"
1434 "#ifdef USEVERTEXTEXTUREBLEND\n"
1435 "       myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
1436 "       //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n"
1437 "       //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n"
1438 "       color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord2)), color.rgb, terrainblend);\n"
1439 "       color.a = 1.0;\n"
1440 "       //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
1441 "#endif\n"
1442 "\n"
1443 "       // get the surface normal\n"
1444 "#ifdef USEVERTEXTEXTUREBLEND\n"
1445 "       myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n"
1446 "#else\n"
1447 "       myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n"
1448 "#endif\n"
1449 "\n"
1450 "       // get the material colors\n"
1451 "       myhalf3 diffusetex = color.rgb;\n"
1452 "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
1453 "# ifdef USEVERTEXTEXTUREBLEND\n"
1454 "       myhalf3 glosstex = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
1455 "# else\n"
1456 "       myhalf3 glosstex = myhalf3(texture2D(Texture_Gloss, TexCoord));\n"
1457 "# endif\n"
1458 "#endif\n"
1459 "\n"
1460 "\n"
1461 "\n"
1462 "\n"
1463 "#ifdef MODE_LIGHTSOURCE\n"
1464 "       // light source\n"
1465 "       myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
1466 "       myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1467 "       color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
1468 "#ifdef USESPECULAR\n"
1469 "#ifdef USEEXACTSPECULARMATH\n"
1470 "       myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
1471 "#else\n"
1472 "       myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
1473 "       myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1474 "#endif\n"
1475 "       color.rgb += glosstex * (specular * Color_Specular);\n"
1476 "#endif\n"
1477 "       color.rgb *= LightColor;\n"
1478 "       color.rgb *= myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
1479 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
1480 "       color.rgb *= ShadowMapCompare(CubeVector);\n"
1481 "#endif\n"
1482 "# ifdef USECUBEFILTER\n"
1483 "       color.rgb *= myhalf3(textureCube(Texture_Cube, CubeVector));\n"
1484 "# endif\n"
1485 "#endif // MODE_LIGHTSOURCE\n"
1486 "\n"
1487 "\n"
1488 "\n"
1489 "\n"
1490 "#ifdef MODE_LIGHTDIRECTION\n"
1491 "#define SHADING\n"
1492 "       myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
1493 "#define lightcolor LightColor\n"
1494 "#endif // MODE_LIGHTDIRECTION\n"
1495 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1496 "#define SHADING\n"
1497 "       // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
1498 "       myhalf3 lightnormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1499 "       myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1500 "       // convert modelspace light vector to tangentspace\n"
1501 "       myhalf3 lightnormal;\n"
1502 "       lightnormal.x = dot(lightnormal_modelspace, myhalf3(VectorS));\n"
1503 "       lightnormal.y = dot(lightnormal_modelspace, myhalf3(VectorT));\n"
1504 "       lightnormal.z = dot(lightnormal_modelspace, myhalf3(VectorR));\n"
1505 "       // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
1506 "       // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
1507 "       // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
1508 "       // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
1509 "       // to map the luxels to coordinates on the draw surfaces), which also causes\n"
1510 "       // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
1511 "       // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
1512 "       // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
1513 "       // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
1514 "       lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
1515 "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1516 "#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
1517 "#define SHADING\n"
1518 "       // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
1519 "       myhalf3 lightnormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1520 "       myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1521 "#endif\n"
1522 "\n"
1523 "\n"
1524 "\n"
1525 "\n"
1526 "#ifdef MODE_LIGHTMAP\n"
1527 "       color.rgb = diffusetex * (Color_Ambient + myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
1528 "#endif // MODE_LIGHTMAP\n"
1529 "#ifdef MODE_VERTEXCOLOR\n"
1530 "       color.rgb = diffusetex * (Color_Ambient + myhalf3(gl_Color.rgb) * Color_Diffuse);\n"
1531 "#endif // MODE_VERTEXCOLOR\n"
1532 "#ifdef MODE_FLATCOLOR\n"
1533 "       color.rgb = diffusetex * Color_Ambient;\n"
1534 "#endif // MODE_FLATCOLOR\n"
1535 "\n"
1536 "\n"
1537 "\n"
1538 "\n"
1539 "#ifdef SHADING\n"
1540 "# ifdef USEDIFFUSE\n"
1541 "       myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1542 "#  ifdef USESPECULAR\n"
1543 "#   ifdef USEEXACTSPECULARMATH\n"
1544 "       myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
1545 "#   else\n"
1546 "       myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
1547 "       myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1548 "#   endif\n"
1549 "       color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex * Color_Specular * specular) * lightcolor;\n"
1550 "#  else\n"
1551 "       color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
1552 "#  endif\n"
1553 "# else\n"
1554 "       color.rgb = diffusetex * Color_Ambient;\n"
1555 "# endif\n"
1556 "#endif\n"
1557 "\n"
1558 "#ifdef USEDEFERREDLIGHTMAP\n"
1559 "       color.rgb += diffusetex * myhalf3(texture2DRect(Texture_ScreenDiffuse, gl_FragCoord.xy)) * DeferredMod_Diffuse;\n"
1560 "       color.rgb += glosstex * myhalf3(texture2DRect(Texture_ScreenSpecular, gl_FragCoord.xy)) * DeferredMod_Specular;\n"
1561 "#endif\n"
1562 "\n"
1563 "#ifdef USEGLOW\n"
1564 "#ifdef USEVERTEXTEXTUREBLEND\n"
1565 "       color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
1566 "#else\n"
1567 "       color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
1568 "#endif\n"
1569 "#endif\n"
1570 "\n"
1571 "#ifdef USEFOG\n"
1572 "       color.rgb = mix(FogColor, color.rgb, FogVertex());\n"
1573 "#endif\n"
1574 "\n"
1575 "       // 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"
1576 "#ifdef USEREFLECTION\n"
1577 "       vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
1578 "       //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
1579 "       vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
1580 "       vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
1581 "       // FIXME temporary hack to detect the case that the reflection\n"
1582 "       // gets blackened at edges due to leaving the area that contains actual\n"
1583 "       // content.\n"
1584 "       // Remove this 'ack once we have a better way to stop this thing from\n"
1585 "       // 'appening.\n"
1586 "       float f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
1587 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
1588 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
1589 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
1590 "       ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
1591 "       color.rgb = mix(color.rgb, myhalf3(texture2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
1592 "#endif\n"
1593 "\n"
1594 "       gl_FragColor = vec4(color);\n"
1595 "}\n"
1596 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
1597 "#endif // !MODE_DEFERREDGEOMETRY\n"
1598 "\n"
1599 "#endif // FRAGMENT_SHADER\n"
1600 "\n"
1601 "#endif // !MODE_WATER\n"
1602 "#endif // !MODE_REFRACTION\n"
1603 "#endif // !MODE_BLOOMBLUR\n"
1604 "#endif // !MODE_GENERIC\n"
1605 "#endif // !MODE_POSTPROCESS\n"
1606 "#endif // !MODE_SHOWDEPTH\n"
1607 "#endif // !MODE_DEPTH_OR_SHADOW\n"
1608 ;
1609
1610 typedef struct shaderpermutationinfo_s
1611 {
1612         const char *pretext;
1613         const char *name;
1614 }
1615 shaderpermutationinfo_t;
1616
1617 typedef struct shadermodeinfo_s
1618 {
1619         const char *vertexfilename;
1620         const char *geometryfilename;
1621         const char *fragmentfilename;
1622         const char *pretext;
1623         const char *name;
1624 }
1625 shadermodeinfo_t;
1626
1627 typedef enum shaderpermutation_e
1628 {
1629         SHADERPERMUTATION_DIFFUSE = 1<<0, ///< (lightsource) whether to use directional shading
1630         SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, ///< indicates this is a two-layer material blend based on vertex alpha (q3bsp)
1631         SHADERPERMUTATION_VIEWTINT = 1<<2, ///< view tint (postprocessing only)
1632         SHADERPERMUTATION_COLORMAPPING = 1<<3, ///< indicates this is a colormapped skin
1633         SHADERPERMUTATION_SATURATION = 1<<4, ///< saturation (postprocessing only)
1634         SHADERPERMUTATION_FOGINSIDE = 1<<5, ///< tint the color by fog color or black if using additive blend mode
1635         SHADERPERMUTATION_FOGOUTSIDE = 1<<6, ///< tint the color by fog color or black if using additive blend mode
1636         SHADERPERMUTATION_GAMMARAMPS = 1<<7, ///< gamma (postprocessing only)
1637         SHADERPERMUTATION_CUBEFILTER = 1<<8, ///< (lightsource) use cubemap light filter
1638         SHADERPERMUTATION_GLOW = 1<<9, ///< (lightmap) blend in an additive glow texture
1639         SHADERPERMUTATION_BLOOM = 1<<10, ///< bloom (postprocessing only)
1640         SHADERPERMUTATION_SPECULAR = 1<<11, ///< (lightsource or deluxemapping) render specular effects
1641         SHADERPERMUTATION_POSTPROCESSING = 1<<12, ///< user defined postprocessing (postprocessing only)
1642         SHADERPERMUTATION_EXACTSPECULARMATH = 1<<13, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
1643         SHADERPERMUTATION_REFLECTION = 1<<14, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
1644         SHADERPERMUTATION_OFFSETMAPPING = 1<<15, ///< adjust texcoords to roughly simulate a displacement mapped surface
1645         SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<16, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
1646         SHADERPERMUTATION_SHADOWMAPRECT = 1<<17, ///< (lightsource) use shadowmap rectangle texture as light filter
1647         SHADERPERMUTATION_SHADOWMAPCUBE = 1<<18, ///< (lightsource) use shadowmap cubemap texture as light filter
1648         SHADERPERMUTATION_SHADOWMAP2D = 1<<19, ///< (lightsource) use shadowmap rectangle texture as light filter
1649         SHADERPERMUTATION_SHADOWMAPPCF = 1<<20, ///< (lightsource) use percentage closer filtering on shadowmap test results
1650         SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<21, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
1651         SHADERPERMUTATION_SHADOWSAMPLER = 1<<22, ///< (lightsource) use hardware shadowmap test
1652         SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<23, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
1653         SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<24, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
1654         SHADERPERMUTATION_ALPHAKILL = 1<<25, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
1655         SHADERPERMUTATION_LIMIT = 1<<26, ///< size of permutations array
1656         SHADERPERMUTATION_COUNT = 27 ///< size of shaderpermutationinfo array
1657 }
1658 shaderpermutation_t;
1659
1660 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
1661 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
1662 {
1663         {"#define USEDIFFUSE\n", " diffuse"},
1664         {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
1665         {"#define USEVIEWTINT\n", " viewtint"},
1666         {"#define USECOLORMAPPING\n", " colormapping"},
1667         {"#define USESATURATION\n", " saturation"},
1668         {"#define USEFOGINSIDE\n", " foginside"},
1669         {"#define USEFOGOUTSIDE\n", " fogoutside"},
1670         {"#define USEGAMMARAMPS\n", " gammaramps"},
1671         {"#define USECUBEFILTER\n", " cubefilter"},
1672         {"#define USEGLOW\n", " glow"},
1673         {"#define USEBLOOM\n", " bloom"},
1674         {"#define USESPECULAR\n", " specular"},
1675         {"#define USEPOSTPROCESSING\n", " postprocessing"},
1676         {"#define USEEXACTSPECULARMATH\n", " exactspecularmath"},
1677         {"#define USEREFLECTION\n", " reflection"},
1678         {"#define USEOFFSETMAPPING\n", " offsetmapping"},
1679         {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
1680         {"#define USESHADOWMAPRECT\n", " shadowmaprect"},
1681         {"#define USESHADOWMAPCUBE\n", " shadowmapcube"},
1682         {"#define USESHADOWMAP2D\n", " shadowmap2d"},
1683         {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"},
1684         {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"},
1685         {"#define USESHADOWSAMPLER\n", " shadowsampler"},
1686         {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"},
1687         {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
1688         {"#define USEALPHAKILL\n", " alphakill"},
1689 };
1690
1691 /// this enum is multiplied by SHADERPERMUTATION_MODEBASE
1692 typedef enum shadermode_e
1693 {
1694         SHADERMODE_GENERIC, ///< (particles/HUD/etc) vertex color, optionally multiplied by one texture
1695         SHADERMODE_POSTPROCESS, ///< postprocessing shader (r_glsl_postprocess)
1696         SHADERMODE_DEPTH_OR_SHADOW, ///< (depthfirst/shadows) vertex shader only
1697         SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp)
1698         SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp)
1699         SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp)
1700         SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap)
1701         SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap)
1702         SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp)
1703         SHADERMODE_LIGHTSOURCE, ///< (lightsource) use directional pixel shading from light source (rtlight)
1704         SHADERMODE_REFRACTION, ///< refract background (the material is rendered normally after this pass)
1705         SHADERMODE_WATER, ///< refract background and reflection (the material is rendered normally after this pass)
1706         SHADERMODE_SHOWDEPTH, ///< (debugging) renders depth as color
1707         SHADERMODE_DEFERREDGEOMETRY, ///< (deferred) render material properties to screenspace geometry buffers
1708         SHADERMODE_DEFERREDLIGHTSOURCE, ///< (deferred) use directional pixel shading from light source (rtlight) on screenspace geometry buffers
1709         SHADERMODE_COUNT
1710 }
1711 shadermode_t;
1712
1713 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
1714 shadermodeinfo_t shadermodeinfo[SHADERMODE_COUNT] =
1715 {
1716         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
1717         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
1718         {"glsl/default.glsl", NULL, NULL               , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
1719         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
1720         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
1721         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
1722         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
1723         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
1724         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
1725         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
1726         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
1727         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_WATER\n", " water"},
1728         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
1729         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
1730         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
1731 };
1732
1733 struct r_glsl_permutation_s;
1734 typedef struct r_glsl_permutation_s
1735 {
1736         /// hash lookup data
1737         struct r_glsl_permutation_s *hashnext;
1738         unsigned int mode;
1739         unsigned int permutation;
1740
1741         /// indicates if we have tried compiling this permutation already
1742         qboolean compiled;
1743         /// 0 if compilation failed
1744         int program;
1745         /// locations of detected uniforms in program object, or -1 if not found
1746         int loc_Texture_First;
1747         int loc_Texture_Second;
1748         int loc_Texture_GammaRamps;
1749         int loc_Texture_Normal;
1750         int loc_Texture_Color;
1751         int loc_Texture_Gloss;
1752         int loc_Texture_Glow;
1753         int loc_Texture_SecondaryNormal;
1754         int loc_Texture_SecondaryColor;
1755         int loc_Texture_SecondaryGloss;
1756         int loc_Texture_SecondaryGlow;
1757         int loc_Texture_Pants;
1758         int loc_Texture_Shirt;
1759         int loc_Texture_FogMask;
1760         int loc_Texture_Lightmap;
1761         int loc_Texture_Deluxemap;
1762         int loc_Texture_Attenuation;
1763         int loc_Texture_Cube;
1764         int loc_Texture_Refraction;
1765         int loc_Texture_Reflection;
1766         int loc_Texture_ShadowMapRect;
1767         int loc_Texture_ShadowMapCube;
1768         int loc_Texture_ShadowMap2D;
1769         int loc_Texture_CubeProjection;
1770         int loc_Texture_ScreenDepth;
1771         int loc_Texture_ScreenNormalMap;
1772         int loc_Texture_ScreenDiffuse;
1773         int loc_Texture_ScreenSpecular;
1774         int loc_Alpha;
1775         int loc_BloomBlur_Parameters;
1776         int loc_ClientTime;
1777         int loc_Color_Ambient;
1778         int loc_Color_Diffuse;
1779         int loc_Color_Specular;
1780         int loc_Color_Glow;
1781         int loc_Color_Pants;
1782         int loc_Color_Shirt;
1783         int loc_DeferredColor_Ambient;
1784         int loc_DeferredColor_Diffuse;
1785         int loc_DeferredColor_Specular;
1786         int loc_DeferredMod_Diffuse;
1787         int loc_DeferredMod_Specular;
1788         int loc_DistortScaleRefractReflect;
1789         int loc_EyePosition;
1790         int loc_FogColor;
1791         int loc_FogHeightFade;
1792         int loc_FogPlane;
1793         int loc_FogPlaneViewDist;
1794         int loc_FogRangeRecip;
1795         int loc_LightColor;
1796         int loc_LightDir;
1797         int loc_LightPosition;
1798         int loc_OffsetMapping_Scale;
1799         int loc_PixelSize;
1800         int loc_ReflectColor;
1801         int loc_ReflectFactor;
1802         int loc_ReflectOffset;
1803         int loc_RefractColor;
1804         int loc_Saturation;
1805         int loc_ScreenCenterRefractReflect;
1806         int loc_ScreenScaleRefractReflect;
1807         int loc_ScreenToDepth;
1808         int loc_ShadowMap_Parameters;
1809         int loc_ShadowMap_TextureScale;
1810         int loc_SpecularPower;
1811         int loc_UserVec1;
1812         int loc_UserVec2;
1813         int loc_UserVec3;
1814         int loc_UserVec4;
1815         int loc_ViewTintColor;
1816         int loc_ViewToLight;
1817         int loc_ModelToLight;
1818         int loc_TexMatrix;
1819         int loc_BackgroundTexMatrix;
1820 }
1821 r_glsl_permutation_t;
1822
1823 #define SHADERPERMUTATION_HASHSIZE 256
1824
1825 /// information about each possible shader permutation
1826 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
1827 /// currently selected permutation
1828 r_glsl_permutation_t *r_glsl_permutation;
1829 /// storage for permutations linked in the hash table
1830 memexpandablearray_t r_glsl_permutationarray;
1831
1832 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation)
1833 {
1834         //unsigned int hashdepth = 0;
1835         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
1836         r_glsl_permutation_t *p;
1837         for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1838         {
1839                 if (p->mode == mode && p->permutation == permutation)
1840                 {
1841                         //if (hashdepth > 10)
1842                         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1843                         return p;
1844                 }
1845                 //hashdepth++;
1846         }
1847         p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
1848         p->mode = mode;
1849         p->permutation = permutation;
1850         p->hashnext = r_glsl_permutationhash[mode][hashindex];
1851         r_glsl_permutationhash[mode][hashindex] = p;
1852         //if (hashdepth > 10)
1853         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1854         return p;
1855 }
1856
1857 static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice)
1858 {
1859         char *shaderstring;
1860         if (!filename || !filename[0])
1861                 return NULL;
1862         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1863         if (shaderstring)
1864         {
1865                 if (printfromdisknotice)
1866                         Con_DPrintf("from disk %s... ", filename);
1867                 return shaderstring;
1868         }
1869         else if (!strcmp(filename, "glsl/default.glsl"))
1870         {
1871                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(builtinshaderstring) + 1);
1872                 memcpy(shaderstring, builtinshaderstring, strlen(builtinshaderstring) + 1);
1873         }
1874         return shaderstring;
1875 }
1876
1877 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1878 {
1879         int i;
1880         shadermodeinfo_t *modeinfo = shadermodeinfo + mode;
1881         int vertstrings_count = 0;
1882         int geomstrings_count = 0;
1883         int fragstrings_count = 0;
1884         char *vertexstring, *geometrystring, *fragmentstring;
1885         const char *vertstrings_list[32+3];
1886         const char *geomstrings_list[32+3];
1887         const char *fragstrings_list[32+3];
1888         char permutationname[256];
1889
1890         if (p->compiled)
1891                 return;
1892         p->compiled = true;
1893         p->program = 0;
1894
1895         permutationname[0] = 0;
1896         vertexstring   = R_GLSL_GetText(modeinfo->vertexfilename, true);
1897         geometrystring = R_GLSL_GetText(modeinfo->geometryfilename, false);
1898         fragmentstring = R_GLSL_GetText(modeinfo->fragmentfilename, false);
1899
1900         strlcat(permutationname, shadermodeinfo[mode].vertexfilename, sizeof(permutationname));
1901
1902         // the first pretext is which type of shader to compile as
1903         // (later these will all be bound together as a program object)
1904         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1905         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1906         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1907
1908         // the second pretext is the mode (for example a light source)
1909         vertstrings_list[vertstrings_count++] = shadermodeinfo[mode].pretext;
1910         geomstrings_list[geomstrings_count++] = shadermodeinfo[mode].pretext;
1911         fragstrings_list[fragstrings_count++] = shadermodeinfo[mode].pretext;
1912         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1913
1914         // now add all the permutation pretexts
1915         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1916         {
1917                 if (permutation & (1<<i))
1918                 {
1919                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1920                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1921                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1922                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1923                 }
1924                 else
1925                 {
1926                         // keep line numbers correct
1927                         vertstrings_list[vertstrings_count++] = "\n";
1928                         geomstrings_list[geomstrings_count++] = "\n";
1929                         fragstrings_list[fragstrings_count++] = "\n";
1930                 }
1931         }
1932
1933         // now append the shader text itself
1934         vertstrings_list[vertstrings_count++] = vertexstring;
1935         geomstrings_list[geomstrings_count++] = geometrystring;
1936         fragstrings_list[fragstrings_count++] = fragmentstring;
1937
1938         // if any sources were NULL, clear the respective list
1939         if (!vertexstring)
1940                 vertstrings_count = 0;
1941         if (!geometrystring)
1942                 geomstrings_count = 0;
1943         if (!fragmentstring)
1944                 fragstrings_count = 0;
1945
1946         // compile the shader program
1947         if (vertstrings_count + geomstrings_count + fragstrings_count)
1948                 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1949         if (p->program)
1950         {
1951                 CHECKGLERROR
1952                 qglUseProgramObjectARB(p->program);CHECKGLERROR
1953                 // look up all the uniform variable names we care about, so we don't
1954                 // have to look them up every time we set them
1955
1956                 p->loc_Texture_First              = qglGetUniformLocationARB(p->program, "Texture_First");
1957                 p->loc_Texture_Second             = qglGetUniformLocationARB(p->program, "Texture_Second");
1958                 p->loc_Texture_GammaRamps         = qglGetUniformLocationARB(p->program, "Texture_GammaRamps");
1959                 p->loc_Texture_Normal             = qglGetUniformLocationARB(p->program, "Texture_Normal");
1960                 p->loc_Texture_Color              = qglGetUniformLocationARB(p->program, "Texture_Color");
1961                 p->loc_Texture_Gloss              = qglGetUniformLocationARB(p->program, "Texture_Gloss");
1962                 p->loc_Texture_Glow               = qglGetUniformLocationARB(p->program, "Texture_Glow");
1963                 p->loc_Texture_SecondaryNormal    = qglGetUniformLocationARB(p->program, "Texture_SecondaryNormal");
1964                 p->loc_Texture_SecondaryColor     = qglGetUniformLocationARB(p->program, "Texture_SecondaryColor");
1965                 p->loc_Texture_SecondaryGloss     = qglGetUniformLocationARB(p->program, "Texture_SecondaryGloss");
1966                 p->loc_Texture_SecondaryGlow      = qglGetUniformLocationARB(p->program, "Texture_SecondaryGlow");
1967                 p->loc_Texture_Pants              = qglGetUniformLocationARB(p->program, "Texture_Pants");
1968                 p->loc_Texture_Shirt              = qglGetUniformLocationARB(p->program, "Texture_Shirt");
1969                 p->loc_Texture_FogMask            = qglGetUniformLocationARB(p->program, "Texture_FogMask");
1970                 p->loc_Texture_Lightmap           = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
1971                 p->loc_Texture_Deluxemap          = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
1972                 p->loc_Texture_Attenuation        = qglGetUniformLocationARB(p->program, "Texture_Attenuation");
1973                 p->loc_Texture_Cube               = qglGetUniformLocationARB(p->program, "Texture_Cube");
1974                 p->loc_Texture_Refraction         = qglGetUniformLocationARB(p->program, "Texture_Refraction");
1975                 p->loc_Texture_Reflection         = qglGetUniformLocationARB(p->program, "Texture_Reflection");
1976                 p->loc_Texture_ShadowMapRect      = qglGetUniformLocationARB(p->program, "Texture_ShadowMapRect");
1977                 p->loc_Texture_ShadowMapCube      = qglGetUniformLocationARB(p->program, "Texture_ShadowMapCube");
1978                 p->loc_Texture_ShadowMap2D        = qglGetUniformLocationARB(p->program, "Texture_ShadowMap2D");
1979                 p->loc_Texture_CubeProjection     = qglGetUniformLocationARB(p->program, "Texture_CubeProjection");
1980                 p->loc_Texture_ScreenDepth        = qglGetUniformLocationARB(p->program, "Texture_ScreenDepth");
1981                 p->loc_Texture_ScreenNormalMap    = qglGetUniformLocationARB(p->program, "Texture_ScreenNormalMap");
1982                 p->loc_Texture_ScreenDiffuse      = qglGetUniformLocationARB(p->program, "Texture_ScreenDiffuse");
1983                 p->loc_Texture_ScreenSpecular     = qglGetUniformLocationARB(p->program, "Texture_ScreenSpecular");
1984                 p->loc_Alpha                      = qglGetUniformLocationARB(p->program, "Alpha");
1985                 p->loc_BloomBlur_Parameters       = qglGetUniformLocationARB(p->program, "BloomBlur_Parameters");
1986                 p->loc_ClientTime                 = qglGetUniformLocationARB(p->program, "ClientTime");
1987                 p->loc_Color_Ambient              = qglGetUniformLocationARB(p->program, "Color_Ambient");
1988                 p->loc_Color_Diffuse              = qglGetUniformLocationARB(p->program, "Color_Diffuse");
1989                 p->loc_Color_Specular             = qglGetUniformLocationARB(p->program, "Color_Specular");
1990                 p->loc_Color_Glow                 = qglGetUniformLocationARB(p->program, "Color_Glow");
1991                 p->loc_Color_Pants                = qglGetUniformLocationARB(p->program, "Color_Pants");
1992                 p->loc_Color_Shirt                = qglGetUniformLocationARB(p->program, "Color_Shirt");
1993                 p->loc_DeferredColor_Ambient      = qglGetUniformLocationARB(p->program, "DeferredColor_Ambient");
1994                 p->loc_DeferredColor_Diffuse      = qglGetUniformLocationARB(p->program, "DeferredColor_Diffuse");
1995                 p->loc_DeferredColor_Specular     = qglGetUniformLocationARB(p->program, "DeferredColor_Specular");
1996                 p->loc_DeferredMod_Diffuse        = qglGetUniformLocationARB(p->program, "DeferredMod_Diffuse");
1997                 p->loc_DeferredMod_Specular       = qglGetUniformLocationARB(p->program, "DeferredMod_Specular");
1998                 p->loc_DistortScaleRefractReflect = qglGetUniformLocationARB(p->program, "DistortScaleRefractReflect");
1999                 p->loc_EyePosition                = qglGetUniformLocationARB(p->program, "EyePosition");
2000                 p->loc_FogColor                   = qglGetUniformLocationARB(p->program, "FogColor");
2001                 p->loc_FogHeightFade              = qglGetUniformLocationARB(p->program, "FogHeightFade");
2002                 p->loc_FogPlane                   = qglGetUniformLocationARB(p->program, "FogPlane");
2003                 p->loc_FogPlaneViewDist           = qglGetUniformLocationARB(p->program, "FogPlaneViewDist");
2004                 p->loc_FogRangeRecip              = qglGetUniformLocationARB(p->program, "FogRangeRecip");
2005                 p->loc_LightColor                 = qglGetUniformLocationARB(p->program, "LightColor");
2006                 p->loc_LightDir                   = qglGetUniformLocationARB(p->program, "LightDir");
2007                 p->loc_LightPosition              = qglGetUniformLocationARB(p->program, "LightPosition");
2008                 p->loc_OffsetMapping_Scale        = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
2009                 p->loc_PixelSize                  = qglGetUniformLocationARB(p->program, "PixelSize");
2010                 p->loc_ReflectColor               = qglGetUniformLocationARB(p->program, "ReflectColor");
2011                 p->loc_ReflectFactor              = qglGetUniformLocationARB(p->program, "ReflectFactor");
2012                 p->loc_ReflectOffset              = qglGetUniformLocationARB(p->program, "ReflectOffset");
2013                 p->loc_RefractColor               = qglGetUniformLocationARB(p->program, "RefractColor");
2014                 p->loc_Saturation                 = qglGetUniformLocationARB(p->program, "Saturation");
2015                 p->loc_ScreenCenterRefractReflect = qglGetUniformLocationARB(p->program, "ScreenCenterRefractReflect");
2016                 p->loc_ScreenScaleRefractReflect  = qglGetUniformLocationARB(p->program, "ScreenScaleRefractReflect");
2017                 p->loc_ScreenToDepth              = qglGetUniformLocationARB(p->program, "ScreenToDepth");
2018                 p->loc_ShadowMap_Parameters       = qglGetUniformLocationARB(p->program, "ShadowMap_Parameters");
2019                 p->loc_ShadowMap_TextureScale     = qglGetUniformLocationARB(p->program, "ShadowMap_TextureScale");
2020                 p->loc_SpecularPower              = qglGetUniformLocationARB(p->program, "SpecularPower");
2021                 p->loc_UserVec1                   = qglGetUniformLocationARB(p->program, "UserVec1");
2022                 p->loc_UserVec2                   = qglGetUniformLocationARB(p->program, "UserVec2");
2023                 p->loc_UserVec3                   = qglGetUniformLocationARB(p->program, "UserVec3");
2024                 p->loc_UserVec4                   = qglGetUniformLocationARB(p->program, "UserVec4");
2025                 p->loc_ViewTintColor              = qglGetUniformLocationARB(p->program, "ViewTintColor");
2026                 p->loc_ViewToLight                = qglGetUniformLocationARB(p->program, "ViewToLight");
2027                 p->loc_ModelToLight               = qglGetUniformLocationARB(p->program, "ModelToLight");
2028                 p->loc_TexMatrix                  = qglGetUniformLocationARB(p->program, "TexMatrix");
2029                 p->loc_BackgroundTexMatrix        = qglGetUniformLocationARB(p->program, "BackgroundTexMatrix");
2030                 // initialize the samplers to refer to the texture units we use
2031                 if (p->loc_Texture_First           >= 0) qglUniform1iARB(p->loc_Texture_First          , GL20TU_FIRST);
2032                 if (p->loc_Texture_Second          >= 0) qglUniform1iARB(p->loc_Texture_Second         , GL20TU_SECOND);
2033                 if (p->loc_Texture_GammaRamps      >= 0) qglUniform1iARB(p->loc_Texture_GammaRamps     , GL20TU_GAMMARAMPS);
2034                 if (p->loc_Texture_Normal          >= 0) qglUniform1iARB(p->loc_Texture_Normal         , GL20TU_NORMAL);
2035                 if (p->loc_Texture_Color           >= 0) qglUniform1iARB(p->loc_Texture_Color          , GL20TU_COLOR);
2036                 if (p->loc_Texture_Gloss           >= 0) qglUniform1iARB(p->loc_Texture_Gloss          , GL20TU_GLOSS);
2037                 if (p->loc_Texture_Glow            >= 0) qglUniform1iARB(p->loc_Texture_Glow           , GL20TU_GLOW);
2038                 if (p->loc_Texture_SecondaryNormal >= 0) qglUniform1iARB(p->loc_Texture_SecondaryNormal, GL20TU_SECONDARY_NORMAL);
2039                 if (p->loc_Texture_SecondaryColor  >= 0) qglUniform1iARB(p->loc_Texture_SecondaryColor , GL20TU_SECONDARY_COLOR);
2040                 if (p->loc_Texture_SecondaryGloss  >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGloss , GL20TU_SECONDARY_GLOSS);
2041                 if (p->loc_Texture_SecondaryGlow   >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGlow  , GL20TU_SECONDARY_GLOW);
2042                 if (p->loc_Texture_Pants           >= 0) qglUniform1iARB(p->loc_Texture_Pants          , GL20TU_PANTS);
2043                 if (p->loc_Texture_Shirt           >= 0) qglUniform1iARB(p->loc_Texture_Shirt          , GL20TU_SHIRT);
2044                 if (p->loc_Texture_FogMask         >= 0) qglUniform1iARB(p->loc_Texture_FogMask        , GL20TU_FOGMASK);
2045                 if (p->loc_Texture_Lightmap        >= 0) qglUniform1iARB(p->loc_Texture_Lightmap       , GL20TU_LIGHTMAP);
2046                 if (p->loc_Texture_Deluxemap       >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap      , GL20TU_DELUXEMAP);
2047                 if (p->loc_Texture_Attenuation     >= 0) qglUniform1iARB(p->loc_Texture_Attenuation    , GL20TU_ATTENUATION);
2048                 if (p->loc_Texture_Cube            >= 0) qglUniform1iARB(p->loc_Texture_Cube           , GL20TU_CUBE);
2049                 if (p->loc_Texture_Refraction      >= 0) qglUniform1iARB(p->loc_Texture_Refraction     , GL20TU_REFRACTION);
2050                 if (p->loc_Texture_Reflection      >= 0) qglUniform1iARB(p->loc_Texture_Reflection     , GL20TU_REFLECTION);
2051                 if (p->loc_Texture_ShadowMapRect   >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapRect  , GL20TU_SHADOWMAPRECT);
2052                 if (p->loc_Texture_ShadowMapCube   >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapCube  , GL20TU_SHADOWMAPCUBE);
2053                 if (p->loc_Texture_ShadowMap2D     >= 0) qglUniform1iARB(p->loc_Texture_ShadowMap2D    , GL20TU_SHADOWMAP2D);
2054                 if (p->loc_Texture_CubeProjection  >= 0) qglUniform1iARB(p->loc_Texture_CubeProjection , GL20TU_CUBEPROJECTION);
2055                 if (p->loc_Texture_ScreenDepth     >= 0) qglUniform1iARB(p->loc_Texture_ScreenDepth    , GL20TU_SCREENDEPTH);
2056                 if (p->loc_Texture_ScreenNormalMap >= 0) qglUniform1iARB(p->loc_Texture_ScreenNormalMap, GL20TU_SCREENNORMALMAP);
2057                 if (p->loc_Texture_ScreenDiffuse   >= 0) qglUniform1iARB(p->loc_Texture_ScreenDiffuse  , GL20TU_SCREENDIFFUSE);
2058                 if (p->loc_Texture_ScreenSpecular  >= 0) qglUniform1iARB(p->loc_Texture_ScreenSpecular , GL20TU_SCREENSPECULAR);
2059                 CHECKGLERROR
2060                 if (developer.integer)
2061                         Con_Printf("^5GLSL shader %s compiled.\n", permutationname);
2062         }
2063         else
2064                 Con_Printf("^1GLSL shader %s failed!  some features may not work properly.\n", permutationname);
2065
2066         // free the strings
2067         if (vertexstring)
2068                 Mem_Free(vertexstring);
2069         if (geometrystring)
2070                 Mem_Free(geometrystring);
2071         if (fragmentstring)
2072                 Mem_Free(fragmentstring);
2073 }
2074
2075 void R_GLSL_Restart_f(void)
2076 {
2077         unsigned int i, limit;
2078         r_glsl_permutation_t *p;
2079         limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
2080         for (i = 0;i < limit;i++)
2081         {
2082                 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
2083                 {
2084                         GL_Backend_FreeProgram(p->program);
2085                         Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
2086                 }
2087         }
2088         memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
2089 }
2090
2091 void R_GLSL_DumpShader_f(void)
2092 {
2093         int i;
2094
2095         qfile_t *file = FS_OpenRealFile("glsl/default.glsl", "w", false);
2096         if(!file)
2097         {
2098                 Con_Printf("failed to write to glsl/default.glsl\n");
2099                 return;
2100         }
2101
2102         FS_Print(file, "/* The engine may define the following macros:\n");
2103         FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
2104         for (i = 0;i < SHADERMODE_COUNT;i++)
2105                 FS_Print(file, shadermodeinfo[i].pretext);
2106         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2107                 FS_Print(file, shaderpermutationinfo[i].pretext);
2108         FS_Print(file, "*/\n");
2109         FS_Print(file, builtinshaderstring);
2110         FS_Close(file);
2111
2112         Con_Printf("glsl/default.glsl written\n");
2113 }
2114
2115 void R_SetupShader_SetPermutation(unsigned int mode, unsigned int permutation)
2116 {
2117         r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
2118         if (r_glsl_permutation != perm)
2119         {
2120                 r_glsl_permutation = perm;
2121                 if (!r_glsl_permutation->program)
2122                 {
2123                         if (!r_glsl_permutation->compiled)
2124                                 R_GLSL_CompilePermutation(perm, mode, permutation);
2125                         if (!r_glsl_permutation->program)
2126                         {
2127                                 // remove features until we find a valid permutation
2128                                 int i;
2129                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2130                                 {
2131                                         // reduce i more quickly whenever it would not remove any bits
2132                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
2133                                         if (!(permutation & j))
2134                                                 continue;
2135                                         permutation -= j;
2136                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
2137                                         if (!r_glsl_permutation->compiled)
2138                                                 R_GLSL_CompilePermutation(perm, mode, permutation);
2139                                         if (r_glsl_permutation->program)
2140                                                 break;
2141                                 }
2142                                 if (i >= SHADERPERMUTATION_COUNT)
2143                                 {
2144                                         //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
2145                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
2146                                         qglUseProgramObjectARB(0);CHECKGLERROR
2147                                         return; // no bit left to clear, entire mode is broken
2148                                 }
2149                         }
2150                 }
2151                 CHECKGLERROR
2152                 qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
2153         }
2154 }
2155
2156 void R_SetupGenericShader(qboolean usetexture)
2157 {
2158         switch(vid.renderpath)
2159         {
2160         case RENDERPATH_GL20:
2161                 R_SetupShader_SetPermutation(SHADERMODE_GENERIC, usetexture ? SHADERPERMUTATION_DIFFUSE : 0);
2162                 break;
2163         case RENDERPATH_GL13:
2164         case RENDERPATH_GL11:
2165                 break;
2166         }
2167 }
2168
2169 void R_SetupGenericTwoTextureShader(int texturemode)
2170 {
2171         switch (vid.renderpath)
2172         {
2173         case RENDERPATH_GL20:
2174                 R_SetupShader_SetPermutation(SHADERMODE_GENERIC, SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
2175                 break;
2176         case RENDERPATH_GL13:
2177         case RENDERPATH_GL11:
2178                 R_Mesh_TexCombine(1, GL_DECAL, GL_DECAL, 1, 1);
2179                 break;
2180         }
2181 }
2182
2183 void R_SetupDepthOrShadowShader(void)
2184 {
2185         switch (vid.renderpath)
2186         {
2187         case RENDERPATH_GL20:
2188                 R_SetupShader_SetPermutation(SHADERMODE_DEPTH_OR_SHADOW, 0);
2189                 break;
2190         case RENDERPATH_GL13:
2191                 break;
2192         case RENDERPATH_GL11:
2193                 break;
2194         }
2195 }
2196
2197 void R_SetupShowDepthShader(void)
2198 {
2199         switch (vid.renderpath)
2200         {
2201         case RENDERPATH_GL20:
2202                 R_SetupShader_SetPermutation(SHADERMODE_SHOWDEPTH, 0);
2203                 break;
2204         case RENDERPATH_GL13:
2205                 break;
2206         case RENDERPATH_GL11:
2207                 break;
2208         }
2209 }
2210
2211 extern qboolean r_shadow_usingdeferredprepass;
2212 extern cvar_t r_shadow_deferred_8bitrange;
2213 extern rtexture_t *r_shadow_attenuationgradienttexture;
2214 extern rtexture_t *r_shadow_attenuation2dtexture;
2215 extern rtexture_t *r_shadow_attenuation3dtexture;
2216 extern qboolean r_shadow_usingshadowmaprect;
2217 extern qboolean r_shadow_usingshadowmapcube;
2218 extern qboolean r_shadow_usingshadowmap2d;
2219 extern float r_shadow_shadowmap_texturescale[2];
2220 extern float r_shadow_shadowmap_parameters[4];
2221 extern qboolean r_shadow_shadowmapvsdct;
2222 extern qboolean r_shadow_shadowmapsampler;
2223 extern int r_shadow_shadowmappcf;
2224 void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass)
2225 {
2226         // select a permutation of the lighting shader appropriate to this
2227         // combination of texture, entity, light source, and fogging, only use the
2228         // minimum features necessary to avoid wasting rendering time in the
2229         // fragment shader on features that are not being used
2230         unsigned int permutation = 0;
2231         unsigned int mode = 0;
2232         float m16f[16];
2233         // TODO: implement geometry-shader based shadow volumes someday
2234         if (r_glsl_offsetmapping.integer)
2235         {
2236                 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
2237                 if (r_glsl_offsetmapping_reliefmapping.integer)
2238                         permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
2239         }
2240         if (rsurfacepass == RSURFPASS_BACKGROUND)
2241         {
2242                 // distorted background
2243                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2244                         mode = SHADERMODE_WATER;
2245                 else
2246                         mode = SHADERMODE_REFRACTION;
2247         }
2248         else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2249         {
2250                 // normalmap (deferred prepass), may use alpha test on diffuse
2251                 mode = SHADERMODE_DEFERREDGEOMETRY;
2252                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2253                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2254                 if (r_glsl_offsetmapping.integer)
2255                 {
2256                         permutation |= SHADERPERMUTATION_OFFSETMAPPING;
2257                         if (r_glsl_offsetmapping_reliefmapping.integer)
2258                                 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
2259                 }
2260         }
2261         else if (rsurfacepass == RSURFPASS_RTLIGHT)
2262         {
2263                 // light source
2264                 mode = SHADERMODE_LIGHTSOURCE;
2265                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2266                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2267                 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2268                         permutation |= SHADERPERMUTATION_CUBEFILTER;
2269                 if (diffusescale > 0)
2270                         permutation |= SHADERPERMUTATION_DIFFUSE;
2271                 if (specularscale > 0)
2272                         permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2273                 if (r_refdef.fogenabled)
2274                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2275                 if (rsurface.texture->colormapping)
2276                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2277                 if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
2278                 {
2279                         if (r_shadow_usingshadowmaprect)
2280                                 permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
2281                         if (r_shadow_usingshadowmap2d)
2282                                 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2283                         if (r_shadow_usingshadowmapcube)
2284                                 permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
2285                         else if(r_shadow_shadowmapvsdct)
2286                                 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2287
2288                         if (r_shadow_shadowmapsampler)
2289                                 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2290                         if (r_shadow_shadowmappcf > 1)
2291                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2292                         else if (r_shadow_shadowmappcf)
2293                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2294                 }
2295         }
2296         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2297         {
2298                 // unshaded geometry (fullbright or ambient model lighting)
2299                 mode = SHADERMODE_FLATCOLOR;
2300                 ambientscale = diffusescale = specularscale = 0;
2301                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2302                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2303                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2304                         permutation |= SHADERPERMUTATION_GLOW;
2305                 if (r_refdef.fogenabled)
2306                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2307                 if (rsurface.texture->colormapping)
2308                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2309                 if (r_glsl_offsetmapping.integer)
2310                 {
2311                         permutation |= SHADERPERMUTATION_OFFSETMAPPING;
2312                         if (r_glsl_offsetmapping_reliefmapping.integer)
2313                                 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
2314                 }
2315                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2316                         permutation |= SHADERPERMUTATION_REFLECTION;
2317         }
2318         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2319         {
2320                 // directional model lighting
2321                 mode = SHADERMODE_LIGHTDIRECTION;
2322                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2323                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2324                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2325                         permutation |= SHADERPERMUTATION_GLOW;
2326                 permutation |= SHADERPERMUTATION_DIFFUSE;
2327                 if (specularscale > 0)
2328                         permutation |= SHADERPERMUTATION_SPECULAR;
2329                 if (r_refdef.fogenabled)
2330                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2331                 if (rsurface.texture->colormapping)
2332                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2333                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2334                         permutation |= SHADERPERMUTATION_REFLECTION;
2335                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2336                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2337         }
2338         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2339         {
2340                 // ambient model lighting
2341                 mode = SHADERMODE_LIGHTDIRECTION;
2342                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2343                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2344                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2345                         permutation |= SHADERPERMUTATION_GLOW;
2346                 if (r_refdef.fogenabled)
2347                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2348                 if (rsurface.texture->colormapping)
2349                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2350                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2351                         permutation |= SHADERPERMUTATION_REFLECTION;
2352                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2353                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2354         }
2355         else
2356         {
2357                 // lightmapped wall
2358                 if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2359                 {
2360                         // deluxemapping (light direction texture)
2361                         if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2362                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2363                         else
2364                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2365                         permutation |= SHADERPERMUTATION_DIFFUSE;
2366                         if (specularscale > 0)
2367                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2368                 }
2369                 else if (r_glsl_deluxemapping.integer >= 2)
2370                 {
2371                         // fake deluxemapping (uniform light direction in tangentspace)
2372                         mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2373                         permutation |= SHADERPERMUTATION_DIFFUSE;
2374                         if (specularscale > 0)
2375                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2376                 }
2377                 else if (rsurface.uselightmaptexture)
2378                 {
2379                         // ordinary lightmapping (q1bsp, q3bsp)
2380                         mode = SHADERMODE_LIGHTMAP;
2381                 }
2382                 else
2383                 {
2384                         // ordinary vertex coloring (q3bsp)
2385                         mode = SHADERMODE_VERTEXCOLOR;
2386                 }
2387                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2388                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2389                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2390                         permutation |= SHADERPERMUTATION_GLOW;
2391                 if (r_refdef.fogenabled)
2392                         permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
2393                 if (rsurface.texture->colormapping)
2394                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2395                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2396                         permutation |= SHADERPERMUTATION_REFLECTION;
2397                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2398                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2399         }
2400         if(permutation & SHADERPERMUTATION_SPECULAR)
2401                 if(r_shadow_glossexact.integer)
2402                         permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
2403         if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) && r_shadow_usingdeferredprepass)
2404                 permutation |= SHADERPERMUTATION_ALPHAKILL;
2405         R_SetupShader_SetPermutation(mode, permutation);
2406         if (mode == SHADERMODE_LIGHTSOURCE)
2407         {
2408                 if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2409                 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2410                 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2411                 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);
2412                 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);
2413                 if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, specularscale, specularscale, specularscale);
2414
2415                 // additive passes are only darkened by fog, not tinted
2416                 if (r_glsl_permutation->loc_FogColor >= 0)
2417                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2418                 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]);
2419                 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]);
2420                 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
2421         }
2422         else
2423         {
2424                 if (mode == SHADERMODE_FLATCOLOR)
2425                 {
2426                         if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);
2427                 }
2428                 else if (mode == SHADERMODE_LIGHTDIRECTION)
2429                 {
2430                         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]);
2431                         if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity, r_refdef.lightmapintensity, r_refdef.lightmapintensity);
2432                         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);
2433                         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);
2434                         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);
2435                         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]);
2436                         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]);
2437                 }
2438                 else
2439                 {
2440                         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]);
2441                         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]);
2442                         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);
2443                         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);
2444                         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);
2445                 }
2446                 // additive passes are only darkened by fog, not tinted
2447                 if (r_glsl_permutation->loc_FogColor >= 0)
2448                 {
2449                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
2450                                 qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2451                         else
2452                                 qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2453                 }
2454                 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);
2455                 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]);
2456                 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]);
2457                 if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
2458                 if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
2459                 if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2460                 if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2461                 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
2462         }
2463         if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
2464         if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
2465         if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2466         if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1fARB(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3]);
2467         if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2468         if (r_glsl_permutation->loc_Color_Pants >= 0)
2469         {
2470                 if (rsurface.texture->currentskinframe->pants)
2471                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2472                 else
2473                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
2474         }
2475         if (r_glsl_permutation->loc_Color_Shirt >= 0)
2476         {
2477                 if (rsurface.texture->currentskinframe->shirt)
2478                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2479                 else
2480                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
2481         }
2482         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]);
2483         if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
2484         if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
2485         if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
2486         if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
2487         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]);
2488         CHECKGLERROR
2489 }
2490
2491 void R_SetupDeferredLightShader(const rtlight_t *rtlight)
2492 {
2493         // select a permutation of the lighting shader appropriate to this
2494         // combination of texture, entity, light source, and fogging, only use the
2495         // minimum features necessary to avoid wasting rendering time in the
2496         // fragment shader on features that are not being used
2497         unsigned int permutation = 0;
2498         unsigned int mode = 0;
2499         const float *lightcolorbase = rtlight->currentcolor;
2500         float ambientscale = rtlight->ambientscale;
2501         float diffusescale = rtlight->diffusescale;
2502         float specularscale = rtlight->specularscale;
2503         // this is the location of the light in view space
2504         vec3_t viewlightorigin;
2505         // this transforms from view space (camera) to light space (cubemap)
2506         matrix4x4_t viewtolight;
2507         matrix4x4_t lighttoview;
2508         float viewtolight16f[16];
2509         float range = 1.0f / r_shadow_deferred_8bitrange.value;
2510         // light source
2511         mode = SHADERMODE_DEFERREDLIGHTSOURCE;
2512         if (rtlight->currentcubemap != r_texture_whitecube)
2513                 permutation |= SHADERPERMUTATION_CUBEFILTER;
2514         if (diffusescale > 0)
2515                 permutation |= SHADERPERMUTATION_DIFFUSE;
2516         if (specularscale > 0)
2517         {
2518                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2519                 if (r_shadow_glossexact.integer)
2520                         permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
2521         }
2522         if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
2523         {
2524                 if (r_shadow_usingshadowmaprect)
2525                         permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
2526                 if (r_shadow_usingshadowmap2d)
2527                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2528                 if (r_shadow_usingshadowmapcube)
2529                         permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
2530                 else if(r_shadow_shadowmapvsdct)
2531                         permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2532
2533                 if (r_shadow_shadowmapsampler)
2534                         permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2535                 if (r_shadow_shadowmappcf > 1)
2536                         permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2537                 else if (r_shadow_shadowmappcf)
2538                         permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2539         }
2540         R_SetupShader_SetPermutation(mode, permutation);
2541         Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
2542         Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
2543         Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
2544         Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
2545         if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
2546         if (r_glsl_permutation->loc_ViewToLight >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ViewToLight, 1, false, viewtolight16f);
2547         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);
2548         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);
2549         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);
2550         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]);
2551         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]);
2552         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));
2553         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]);
2554 }
2555
2556 #define SKINFRAME_HASH 1024
2557
2558 typedef struct
2559 {
2560         int loadsequence; // incremented each level change
2561         memexpandablearray_t array;
2562         skinframe_t *hash[SKINFRAME_HASH];
2563 }
2564 r_skinframe_t;
2565 r_skinframe_t r_skinframe;
2566
2567 void R_SkinFrame_PrepareForPurge(void)
2568 {
2569         r_skinframe.loadsequence++;
2570         // wrap it without hitting zero
2571         if (r_skinframe.loadsequence >= 200)
2572                 r_skinframe.loadsequence = 1;
2573 }
2574
2575 void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
2576 {
2577         if (!skinframe)
2578                 return;
2579         // mark the skinframe as used for the purging code
2580         skinframe->loadsequence = r_skinframe.loadsequence;
2581 }
2582
2583 void R_SkinFrame_Purge(void)
2584 {
2585         int i;
2586         skinframe_t *s;
2587         for (i = 0;i < SKINFRAME_HASH;i++)
2588         {
2589                 for (s = r_skinframe.hash[i];s;s = s->next)
2590                 {
2591                         if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
2592                         {
2593                                 if (s->merged == s->base)
2594                                         s->merged = NULL;
2595                                 // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
2596                                 R_PurgeTexture(s->stain );s->stain  = NULL;
2597                                 R_PurgeTexture(s->merged);s->merged = NULL;
2598                                 R_PurgeTexture(s->base  );s->base   = NULL;
2599                                 R_PurgeTexture(s->pants );s->pants  = NULL;
2600                                 R_PurgeTexture(s->shirt );s->shirt  = NULL;
2601                                 R_PurgeTexture(s->nmap  );s->nmap   = NULL;
2602                                 R_PurgeTexture(s->gloss );s->gloss  = NULL;
2603                                 R_PurgeTexture(s->glow  );s->glow   = NULL;
2604                                 R_PurgeTexture(s->fog   );s->fog    = NULL;
2605                                 s->loadsequence = 0;
2606                         }
2607                 }
2608         }
2609 }
2610
2611 skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
2612         skinframe_t *item;
2613         char basename[MAX_QPATH];
2614
2615         Image_StripImageExtension(name, basename, sizeof(basename));
2616
2617         if( last == NULL ) {
2618                 int hashindex;
2619                 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
2620                 item = r_skinframe.hash[hashindex];
2621         } else {
2622                 item = last->next;
2623         }
2624
2625         // linearly search through the hash bucket
2626         for( ; item ; item = item->next ) {
2627                 if( !strcmp( item->basename, basename ) ) {
2628                         return item;
2629                 }
2630         }
2631         return NULL;
2632 }
2633
2634 skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
2635 {
2636         skinframe_t *item;
2637         int hashindex;
2638         char basename[MAX_QPATH];
2639
2640         Image_StripImageExtension(name, basename, sizeof(basename));
2641
2642         hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
2643         for (item = r_skinframe.hash[hashindex];item;item = item->next)
2644                 if (!strcmp(item->basename, basename) && item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)
2645                         break;
2646
2647         if (!item) {
2648                 rtexture_t *dyntexture;
2649                 // check whether its a dynamic texture
2650                 dyntexture = CL_GetDynTexture( basename );
2651                 if (!add && !dyntexture)
2652                         return NULL;
2653                 item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
2654                 memset(item, 0, sizeof(*item));
2655                 strlcpy(item->basename, basename, sizeof(item->basename));
2656                 item->base = dyntexture; // either NULL or dyntexture handle
2657                 item->textureflags = textureflags;
2658                 item->comparewidth = comparewidth;
2659                 item->compareheight = compareheight;
2660                 item->comparecrc = comparecrc;
2661                 item->next = r_skinframe.hash[hashindex];
2662                 r_skinframe.hash[hashindex] = item;
2663         }
2664         else if( item->base == NULL )
2665         {
2666                 rtexture_t *dyntexture;
2667                 // check whether its a dynamic texture
2668                 // 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]
2669                 dyntexture = CL_GetDynTexture( basename );
2670                 item->base = dyntexture; // either NULL or dyntexture handle
2671         }
2672
2673         R_SkinFrame_MarkUsed(item);
2674         return item;
2675 }
2676
2677 #define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \
2678         { \
2679                 unsigned long long avgcolor[5], wsum; \
2680                 int pix, comp, w; \
2681                 avgcolor[0] = 0; \
2682                 avgcolor[1] = 0; \
2683                 avgcolor[2] = 0; \
2684                 avgcolor[3] = 0; \
2685                 avgcolor[4] = 0; \
2686                 wsum = 0; \
2687                 for(pix = 0; pix < cnt; ++pix) \
2688                 { \
2689                         w = 0; \
2690                         for(comp = 0; comp < 3; ++comp) \
2691                                 w += getpixel; \
2692                         if(w) /* ignore perfectly black pixels because that is better for model skins */ \
2693                         { \
2694                                 ++wsum; \
2695                                 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
2696                                 w = getpixel; \
2697                                 for(comp = 0; comp < 3; ++comp) \
2698                                         avgcolor[comp] += getpixel * w; \
2699                                 avgcolor[3] += w; \
2700                         } \
2701                         /* comp = 3; -- not needed, comp is always 3 when we get here */ \
2702                         avgcolor[4] += getpixel; \
2703                 } \
2704                 if(avgcolor[3] == 0) /* no pixels seen? even worse */ \
2705                         avgcolor[3] = 1; \
2706                 skinframe->avgcolor[0] = avgcolor[2] / (255.0 * avgcolor[3]); \
2707                 skinframe->avgcolor[1] = avgcolor[1] / (255.0 * avgcolor[3]); \
2708                 skinframe->avgcolor[2] = avgcolor[0] / (255.0 * avgcolor[3]); \
2709                 skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \
2710         }
2711
2712 skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain)
2713 {
2714         int j;
2715         unsigned char *pixels;
2716         unsigned char *bumppixels;
2717         unsigned char *basepixels = NULL;
2718         int basepixels_width;
2719         int basepixels_height;
2720         skinframe_t *skinframe;
2721
2722         if (cls.state == ca_dedicated)
2723                 return NULL;
2724
2725         // return an existing skinframe if already loaded
2726         // if loading of the first image fails, don't make a new skinframe as it
2727         // would cause all future lookups of this to be missing
2728         skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
2729         if (skinframe && skinframe->base)
2730                 return skinframe;
2731
2732         basepixels = loadimagepixelsbgra(name, complain, true);
2733         if (basepixels == NULL)
2734                 return NULL;
2735
2736         if (developer_loading.integer)
2737                 Con_Printf("loading skin \"%s\"\n", name);
2738
2739         // we've got some pixels to store, so really allocate this new texture now
2740         if (!skinframe)
2741                 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, true);
2742         skinframe->stain = NULL;
2743         skinframe->merged = NULL;
2744         skinframe->base = r_texture_notexture;
2745         skinframe->pants = NULL;
2746         skinframe->shirt = NULL;
2747         skinframe->nmap = r_texture_blanknormalmap;
2748         skinframe->gloss = NULL;
2749         skinframe->glow = NULL;
2750         skinframe->fog = NULL;
2751         skinframe->hasalpha = false;
2752
2753         basepixels_width = image_width;
2754         basepixels_height = image_height;
2755         skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2756
2757         if (textureflags & TEXF_ALPHA)
2758         {
2759                 for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
2760                 {
2761                         if (basepixels[j] < 255)
2762                         {
2763                                 skinframe->hasalpha = true;
2764                                 break;
2765                         }
2766                 }
2767                 if (r_loadfog && skinframe->hasalpha)
2768                 {
2769                         // has transparent pixels
2770                         pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
2771                         for (j = 0;j < image_width * image_height * 4;j += 4)
2772                         {
2773                                 pixels[j+0] = 255;
2774                                 pixels[j+1] = 255;
2775                                 pixels[j+2] = 255;
2776                                 pixels[j+3] = basepixels[j+3];
2777                         }
2778                         skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2779                         Mem_Free(pixels);
2780                 }
2781         }
2782
2783         R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
2784         //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2785
2786         // _norm is the name used by tenebrae and has been adopted as standard
2787         if (r_loadnormalmap)
2788         {
2789                 if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false)) != NULL)
2790                 {
2791                         skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2792                         Mem_Free(pixels);
2793                         pixels = NULL;
2794                 }
2795                 else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false)) != NULL)
2796                 {
2797                         pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
2798                         Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value);
2799                         skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2800                         Mem_Free(pixels);
2801                         Mem_Free(bumppixels);
2802                 }
2803                 else if (r_shadow_bumpscale_basetexture.value > 0)
2804                 {
2805                         pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4);
2806                         Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value);
2807                         skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2808                         Mem_Free(pixels);
2809                 }
2810         }
2811         // _luma is supported for tenebrae compatibility
2812         // (I think it's a very stupid name, but oh well)
2813         // _glow is the preferred name
2814         if ((pixels = loadimagepixelsbgra(va("%s_glow",  skinframe->basename), false, false)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false))) {skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2815         if (r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false))) {skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2816         if ((pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false))) {skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2817         if ((pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false))) {skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2818
2819         if (basepixels)
2820                 Mem_Free(basepixels);
2821
2822         return skinframe;
2823 }
2824
2825 // this is only used by .spr32 sprites, HL .spr files, HL .bsp files
2826 skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height)
2827 {
2828         int i;
2829         unsigned char *temp1, *temp2;
2830         skinframe_t *skinframe;
2831
2832         if (cls.state == ca_dedicated)
2833                 return NULL;
2834
2835         // if already loaded just return it, otherwise make a new skinframe
2836         skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height*4) : 0, true);
2837         if (skinframe && skinframe->base)
2838                 return skinframe;
2839
2840         skinframe->stain = NULL;
2841         skinframe->merged = NULL;
2842         skinframe->base = r_texture_notexture;
2843         skinframe->pants = NULL;
2844         skinframe->shirt = NULL;
2845         skinframe->nmap = r_texture_blanknormalmap;
2846         skinframe->gloss = NULL;
2847         skinframe->glow = NULL;
2848         skinframe->fog = NULL;
2849         skinframe->hasalpha = false;
2850
2851         // if no data was provided, then clearly the caller wanted to get a blank skinframe
2852         if (!skindata)
2853                 return NULL;
2854
2855         if (developer_loading.integer)
2856                 Con_Printf("loading 32bit skin \"%s\"\n", name);
2857
2858         if (r_loadnormalmap && r_shadow_bumpscale_basetexture.value > 0)
2859         {
2860                 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
2861                 temp2 = temp1 + width * height * 4;
2862                 Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
2863                 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL);
2864                 Mem_Free(temp1);
2865         }
2866         skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, skinframe->textureflags, NULL);
2867         if (textureflags & TEXF_ALPHA)
2868         {
2869                 for (i = 3;i < width * height * 4;i += 4)
2870                 {
2871                         if (skindata[i] < 255)
2872                         {
2873                                 skinframe->hasalpha = true;
2874                                 break;
2875                         }
2876                 }
2877                 if (r_loadfog && skinframe->hasalpha)
2878                 {
2879                         unsigned char *fogpixels = (unsigned char *)Mem_Alloc(tempmempool, width * height * 4);
2880                         memcpy(fogpixels, skindata, width * height * 4);
2881                         for (i = 0;i < width * height * 4;i += 4)
2882                                 fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
2883                         skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, skinframe->textureflags, NULL);
2884                         Mem_Free(fogpixels);
2885                 }
2886         }
2887
2888         R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, skindata[4 * pix + comp]);
2889         //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2890
2891         return skinframe;
2892 }
2893
2894 skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height)
2895 {
2896         int i;
2897         int featuresmask;
2898         skinframe_t *skinframe;
2899
2900         if (cls.state == ca_dedicated)
2901                 return NULL;
2902
2903         // if already loaded just return it, otherwise make a new skinframe
2904         skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
2905         if (skinframe && skinframe->base)
2906                 return skinframe;
2907
2908         skinframe->stain = NULL;
2909         skinframe->merged = NULL;
2910         skinframe->base = r_texture_notexture;
2911         skinframe->pants = NULL;
2912         skinframe->shirt = NULL;
2913         skinframe->nmap = r_texture_blanknormalmap;
2914         skinframe->gloss = NULL;
2915         skinframe->glow = NULL;
2916         skinframe->fog = NULL;
2917         skinframe->hasalpha = false;
2918
2919         // if no data was provided, then clearly the caller wanted to get a blank skinframe
2920         if (!skindata)
2921                 return NULL;
2922
2923         if (developer_loading.integer)
2924                 Con_Printf("loading quake skin \"%s\"\n", name);
2925
2926         // we actually don't upload anything until the first use, because mdl skins frequently go unused, and are almost never used in both modes (colormapped and non-colormapped)
2927         skinframe->qpixels = Mem_Alloc(r_main_mempool, width*height);
2928         memcpy(skinframe->qpixels, skindata, width*height);
2929         skinframe->qwidth = width;
2930         skinframe->qheight = height;
2931
2932         featuresmask = 0;
2933         for (i = 0;i < width * height;i++)
2934                 featuresmask |= palette_featureflags[skindata[i]];
2935
2936         skinframe->hasalpha = false;
2937         skinframe->qhascolormapping = loadpantsandshirt && (featuresmask & (PALETTEFEATURE_PANTS | PALETTEFEATURE_SHIRT));
2938         skinframe->qgeneratenmap = r_shadow_bumpscale_basetexture.value > 0;
2939         skinframe->qgeneratemerged = true;
2940         skinframe->qgeneratebase = skinframe->qhascolormapping;
2941         skinframe->qgenerateglow = loadglowtexture && (featuresmask & PALETTEFEATURE_GLOW);
2942
2943         R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette_bgra_complete)[skindata[pix]*4 + comp]);
2944         //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2945
2946         return skinframe;
2947 }
2948
2949 static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboolean colormapped)
2950 {
2951         int width;
2952         int height;
2953         unsigned char *skindata;
2954
2955         if (!skinframe->qpixels)
2956                 return;
2957
2958         if (!skinframe->qhascolormapping)
2959                 colormapped = false;
2960
2961         if (colormapped)
2962         {
2963                 if (!skinframe->qgeneratebase)
2964                         return;
2965         }
2966         else
2967         {
2968                 if (!skinframe->qgeneratemerged)
2969                         return;
2970         }
2971
2972         width = skinframe->qwidth;
2973         height = skinframe->qheight;
2974         skindata = skinframe->qpixels;
2975
2976         if (skinframe->qgeneratenmap)
2977         {
2978                 unsigned char *temp1, *temp2;
2979                 skinframe->qgeneratenmap = false;
2980                 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
2981                 temp2 = temp1 + width * height * 4;
2982                 // use either a custom palette or the quake palette
2983                 Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
2984                 Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
2985                 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL);
2986                 Mem_Free(temp1);
2987         }
2988
2989         if (skinframe->qgenerateglow)
2990         {
2991                 skinframe->qgenerateglow = false;
2992                 skinframe->glow = R_LoadTexture2D(r_main_texturepool, va("%s_glow", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette_bgra_onlyfullbrights); // glow
2993         }
2994
2995         if (colormapped)
2996         {
2997                 skinframe->qgeneratebase = false;
2998                 skinframe->base  = R_LoadTexture2D(r_main_texturepool, va("%s_nospecial", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, skinframe->glow ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap);
2999                 skinframe->pants = R_LoadTexture2D(r_main_texturepool, va("%s_pants", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette_bgra_pantsaswhite);
3000                 skinframe->shirt = R_LoadTexture2D(r_main_texturepool, va("%s_shirt", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette_bgra_shirtaswhite);
3001         }
3002         else
3003         {
3004                 skinframe->qgeneratemerged = false;
3005                 skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete);
3006         }
3007
3008         if (!skinframe->qgeneratemerged && !skinframe->qgeneratebase)
3009         {
3010                 Mem_Free(skinframe->qpixels);
3011                 skinframe->qpixels = NULL;
3012         }
3013 }
3014
3015 skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, const unsigned char *skindata, int width, int height, const unsigned int *palette, const unsigned int *alphapalette)
3016 {
3017         int i;
3018         skinframe_t *skinframe;
3019
3020         if (cls.state == ca_dedicated)
3021                 return NULL;
3022
3023         // if already loaded just return it, otherwise make a new skinframe
3024         skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
3025         if (skinframe && skinframe->base)
3026                 return skinframe;
3027
3028         skinframe->stain = NULL;
3029         skinframe->merged = NULL;
3030         skinframe->base = r_texture_notexture;
3031         skinframe->pants = NULL;
3032         skinframe->shirt = NULL;
3033         skinframe->nmap = r_texture_blanknormalmap;
3034         skinframe->gloss = NULL;
3035         skinframe->glow = NULL;
3036         skinframe->fog = NULL;
3037         skinframe->hasalpha = false;
3038
3039         // if no data was provided, then clearly the caller wanted to get a blank skinframe
3040         if (!skindata)
3041                 return NULL;
3042
3043         if (developer_loading.integer)
3044                 Con_Printf("loading embedded 8bit image \"%s\"\n", name);
3045
3046         skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette);
3047         if (textureflags & TEXF_ALPHA)
3048         {
3049                 for (i = 0;i < width * height;i++)
3050                 {
3051                         if (((unsigned char *)palette)[skindata[i]*4+3] < 255)
3052                         {
3053                                 skinframe->hasalpha = true;
3054                                 break;
3055                         }
3056                 }
3057                 if (r_loadfog && skinframe->hasalpha)
3058                         skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, alphapalette);
3059         }
3060
3061         R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
3062         //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
3063
3064         return skinframe;
3065 }
3066
3067 skinframe_t *R_SkinFrame_LoadMissing(void)
3068 {
3069         skinframe_t *skinframe;
3070
3071         if (cls.state == ca_dedicated)
3072                 return NULL;
3073
3074         skinframe = R_SkinFrame_Find("missing", TEXF_PRECACHE | TEXF_FORCENEAREST, 0, 0, 0, true);
3075         skinframe->stain = NULL;
3076         skinframe->merged = NULL;
3077         skinframe->base = r_texture_notexture;
3078         skinframe->pants = NULL;
3079         skinframe->shirt = NULL;
3080         skinframe->nmap = r_texture_blanknormalmap;
3081         skinframe->gloss = NULL;
3082         skinframe->glow = NULL;
3083         skinframe->fog = NULL;
3084         skinframe->hasalpha = false;
3085
3086         skinframe->avgcolor[0] = rand() / RAND_MAX;
3087         skinframe->avgcolor[1] = rand() / RAND_MAX;
3088         skinframe->avgcolor[2] = rand() / RAND_MAX;
3089         skinframe->avgcolor[3] = 1;
3090
3091         return skinframe;
3092 }
3093
3094 void R_Main_FreeViewCache(void)
3095 {
3096         if (r_refdef.viewcache.entityvisible)
3097                 Mem_Free(r_refdef.viewcache.entityvisible);
3098         if (r_refdef.viewcache.world_pvsbits)
3099                 Mem_Free(r_refdef.viewcache.world_pvsbits);
3100         if (r_refdef.viewcache.world_leafvisible)
3101                 Mem_Free(r_refdef.viewcache.world_leafvisible);
3102         if (r_refdef.viewcache.world_surfacevisible)
3103                 Mem_Free(r_refdef.viewcache.world_surfacevisible);
3104         memset(&r_refdef.viewcache, 0, sizeof(r_refdef.viewcache));
3105 }
3106
3107 void R_Main_ResizeViewCache(void)
3108 {
3109         int numentities = r_refdef.scene.numentities;
3110         int numclusters = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusters : 1;
3111         int numclusterbytes = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusterbytes : 1;
3112         int numleafs = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_leafs : 1;
3113         int numsurfaces = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->num_surfaces : 1;
3114         if (r_refdef.viewcache.maxentities < numentities)
3115         {
3116                 r_refdef.viewcache.maxentities = numentities;
3117                 if (r_refdef.viewcache.entityvisible)
3118                         Mem_Free(r_refdef.viewcache.entityvisible);
3119                 r_refdef.viewcache.entityvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
3120         }
3121         if (r_refdef.viewcache.world_numclusters != numclusters)
3122         {
3123                 r_refdef.viewcache.world_numclusters = numclusters;
3124                 r_refdef.viewcache.world_numclusterbytes = numclusterbytes;
3125                 if (r_refdef.viewcache.world_pvsbits)
3126                         Mem_Free(r_refdef.viewcache.world_pvsbits);
3127                 r_refdef.viewcache.world_pvsbits = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
3128         }
3129         if (r_refdef.viewcache.world_numleafs != numleafs)
3130         {
3131                 r_refdef.viewcache.world_numleafs = numleafs;
3132                 if (r_refdef.viewcache.world_leafvisible)
3133                         Mem_Free(r_refdef.viewcache.world_leafvisible);
3134                 r_refdef.viewcache.world_leafvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
3135         }
3136         if (r_refdef.viewcache.world_numsurfaces != numsurfaces)
3137         {
3138                 r_refdef.viewcache.world_numsurfaces = numsurfaces;
3139                 if (r_refdef.viewcache.world_surfacevisible)
3140                         Mem_Free(r_refdef.viewcache.world_surfacevisible);
3141                 r_refdef.viewcache.world_surfacevisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
3142         }
3143 }
3144
3145 extern rtexture_t *loadingscreentexture;
3146 void gl_main_start(void)
3147 {
3148         loadingscreentexture = NULL;
3149         r_texture_blanknormalmap = NULL;
3150         r_texture_white = NULL;
3151         r_texture_grey128 = NULL;
3152         r_texture_black = NULL;
3153         r_texture_whitecube = NULL;
3154         r_texture_normalizationcube = NULL;
3155         r_texture_fogattenuation = NULL;
3156         r_texture_gammaramps = NULL;
3157
3158         switch(vid.renderpath)
3159         {
3160         case RENDERPATH_GL20:
3161                 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
3162                 Cvar_SetValueQuick(&gl_combine, 1);
3163                 Cvar_SetValueQuick(&r_glsl, 1);
3164                 r_loadnormalmap = true;
3165                 r_loadgloss = true;
3166                 r_loadfog = false;
3167                 break;
3168         case RENDERPATH_GL13:
3169                 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
3170                 Cvar_SetValueQuick(&gl_combine, 1);
3171                 Cvar_SetValueQuick(&r_glsl, 0);
3172                 r_loadnormalmap = false;
3173                 r_loadgloss = false;
3174                 r_loadfog = true;
3175                 break;
3176         case RENDERPATH_GL11:
3177                 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
3178                 Cvar_SetValueQuick(&gl_combine, 0);
3179                 Cvar_SetValueQuick(&r_glsl, 0);
3180                 r_loadnormalmap = false;
3181                 r_loadgloss = false;
3182                 r_loadfog = true;
3183                 break;
3184         }
3185
3186         R_AnimCache_Free();
3187         R_FrameData_Reset();
3188
3189         r_numqueries = 0;
3190         r_maxqueries = 0;
3191         memset(r_queries, 0, sizeof(r_queries));
3192
3193         r_qwskincache = NULL;
3194         r_qwskincache_size = 0;
3195
3196         // set up r_skinframe loading system for textures
3197         memset(&r_skinframe, 0, sizeof(r_skinframe));
3198         r_skinframe.loadsequence = 1;
3199         Mem_ExpandableArray_NewArray(&r_skinframe.array, r_main_mempool, sizeof(skinframe_t), 256);
3200
3201         r_main_texturepool = R_AllocTexturePool();
3202         R_BuildBlankTextures();
3203         R_BuildNoTexture();
3204         if (vid.support.arb_texture_cube_map)
3205         {
3206                 R_BuildWhiteCube();
3207                 R_BuildNormalizationCube();
3208         }
3209         r_texture_fogattenuation = NULL;
3210         r_texture_gammaramps = NULL;
3211         //r_texture_fogintensity = NULL;
3212         memset(&r_bloomstate, 0, sizeof(r_bloomstate));
3213         memset(&r_waterstate, 0, sizeof(r_waterstate));
3214         memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
3215         Mem_ExpandableArray_NewArray(&r_glsl_permutationarray, r_main_mempool, sizeof(r_glsl_permutation_t), 256);
3216         memset(&r_svbsp, 0, sizeof (r_svbsp));
3217
3218         r_refdef.fogmasktable_density = 0;
3219 }
3220
3221 void gl_main_shutdown(void)
3222 {
3223         R_AnimCache_Free();
3224         R_FrameData_Reset();
3225
3226         R_Main_FreeViewCache();
3227
3228         if (r_maxqueries)
3229                 qglDeleteQueriesARB(r_maxqueries, r_queries);
3230
3231         r_numqueries = 0;
3232         r_maxqueries = 0;
3233         memset(r_queries, 0, sizeof(r_queries));
3234
3235         r_qwskincache = NULL;
3236         r_qwskincache_size = 0;
3237
3238         // clear out the r_skinframe state
3239         Mem_ExpandableArray_FreeArray(&r_skinframe.array);
3240         memset(&r_skinframe, 0, sizeof(r_skinframe));
3241
3242         if (r_svbsp.nodes)
3243                 Mem_Free(r_svbsp.nodes);
3244         memset(&r_svbsp, 0, sizeof (r_svbsp));
3245         R_FreeTexturePool(&r_main_texturepool);
3246         loadingscreentexture = NULL;
3247         r_texture_blanknormalmap = NULL;
3248         r_texture_white = NULL;
3249         r_texture_grey128 = NULL;
3250         r_texture_black = NULL;
3251         r_texture_whitecube = NULL;
3252         r_texture_normalizationcube = NULL;
3253         r_texture_fogattenuation = NULL;
3254         r_texture_gammaramps = NULL;
3255         //r_texture_fogintensity = NULL;
3256         memset(&r_bloomstate, 0, sizeof(r_bloomstate));
3257         memset(&r_waterstate, 0, sizeof(r_waterstate));
3258         R_GLSL_Restart_f();
3259 }
3260
3261 extern void CL_ParseEntityLump(char *entitystring);
3262 void gl_main_newmap(void)
3263 {
3264         // FIXME: move this code to client
3265         int l;
3266         char *entities, entname[MAX_QPATH];
3267         if (r_qwskincache)
3268                 Mem_Free(r_qwskincache);
3269         r_qwskincache = NULL;
3270         r_qwskincache_size = 0;
3271         if (cl.worldmodel)
3272         {
3273                 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
3274                 l = (int)strlen(entname) - 4;
3275                 if (l >= 0 && !strcmp(entname + l, ".bsp"))
3276                 {
3277                         memcpy(entname + l, ".ent", 5);
3278                         if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
3279                         {
3280                                 CL_ParseEntityLump(entities);
3281                                 Mem_Free(entities);
3282                                 return;
3283                         }
3284                 }
3285                 if (cl.worldmodel->brush.entities)
3286                         CL_ParseEntityLump(cl.worldmodel->brush.entities);
3287         }
3288         R_Main_FreeViewCache();
3289
3290         R_FrameData_Reset();
3291 }
3292
3293 void GL_Main_Init(void)
3294 {
3295         r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
3296
3297         Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed");
3298         Cmd_AddCommand("r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl");
3299         // FIXME: the client should set up r_refdef.fog stuff including the fogmasktable
3300         if (gamemode == GAME_NEHAHRA)
3301         {
3302                 Cvar_RegisterVariable (&gl_fogenable);
3303                 Cvar_RegisterVariable (&gl_fogdensity);
3304                 Cvar_RegisterVariable (&gl_fogred);
3305                 Cvar_RegisterVariable (&gl_foggreen);
3306                 Cvar_RegisterVariable (&gl_fogblue);
3307                 Cvar_RegisterVariable (&gl_fogstart);
3308                 Cvar_RegisterVariable (&gl_fogend);
3309                 Cvar_RegisterVariable (&gl_skyclip);
3310         }
3311         Cvar_RegisterVariable(&r_motionblur);
3312         Cvar_RegisterVariable(&r_motionblur_maxblur);
3313         Cvar_RegisterVariable(&r_motionblur_bmin);
3314         Cvar_RegisterVariable(&r_motionblur_vmin);
3315         Cvar_RegisterVariable(&r_motionblur_vmax);
3316         Cvar_RegisterVariable(&r_motionblur_vcoeff);
3317         Cvar_RegisterVariable(&r_motionblur_randomize);
3318         Cvar_RegisterVariable(&r_damageblur);
3319         Cvar_RegisterVariable(&r_equalize_entities_fullbright);
3320         Cvar_RegisterVariable(&r_equalize_entities_minambient);
3321         Cvar_RegisterVariable(&r_equalize_entities_by);
3322         Cvar_RegisterVariable(&r_equalize_entities_to);
3323         Cvar_RegisterVariable(&r_depthfirst);
3324         Cvar_RegisterVariable(&r_useinfinitefarclip);
3325         Cvar_RegisterVariable(&r_farclip_base);
3326         Cvar_RegisterVariable(&r_farclip_world);
3327         Cvar_RegisterVariable(&r_nearclip);
3328         Cvar_RegisterVariable(&r_showbboxes);
3329         Cvar_RegisterVariable(&r_showsurfaces);
3330         Cvar_RegisterVariable(&r_showtris);
3331         Cvar_RegisterVariable(&r_shownormals);
3332         Cvar_RegisterVariable(&r_showlighting);
3333         Cvar_RegisterVariable(&r_showshadowvolumes);
3334         Cvar_RegisterVariable(&r_showcollisionbrushes);
3335         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
3336         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
3337         Cvar_RegisterVariable(&r_showdisabledepthtest);
3338         Cvar_RegisterVariable(&r_drawportals);
3339         Cvar_RegisterVariable(&r_drawentities);
3340         Cvar_RegisterVariable(&r_cullentities_trace);
3341         Cvar_RegisterVariable(&r_cullentities_trace_samples);
3342         Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
3343         Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
3344         Cvar_RegisterVariable(&r_cullentities_trace_delay);
3345         Cvar_RegisterVariable(&r_drawviewmodel);
3346         Cvar_RegisterVariable(&r_speeds);
3347         Cvar_RegisterVariable(&r_fullbrights);
3348         Cvar_RegisterVariable(&r_wateralpha);
3349         Cvar_RegisterVariable(&r_dynamic);
3350         Cvar_RegisterVariable(&r_fullbright);
3351         Cvar_RegisterVariable(&r_shadows);
3352         Cvar_RegisterVariable(&r_shadows_darken);
3353         Cvar_RegisterVariable(&r_shadows_drawafterrtlighting);
3354         Cvar_RegisterVariable(&r_shadows_castfrombmodels);
3355         Cvar_RegisterVariable(&r_shadows_throwdistance);
3356         Cvar_RegisterVariable(&r_shadows_throwdirection);
3357         Cvar_RegisterVariable(&r_q1bsp_skymasking);
3358         Cvar_RegisterVariable(&r_polygonoffset_submodel_factor);
3359         Cvar_RegisterVariable(&r_polygonoffset_submodel_offset);
3360         Cvar_RegisterVariable(&r_polygonoffset_decals_factor);
3361         Cvar_RegisterVariable(&r_polygonoffset_decals_offset);
3362         Cvar_RegisterVariable(&r_fog_exp2);
3363         Cvar_RegisterVariable(&r_drawfog);
3364         Cvar_RegisterVariable(&r_transparentdepthmasking);
3365         Cvar_RegisterVariable(&r_textureunits);
3366         Cvar_RegisterVariable(&gl_combine);
3367         Cvar_RegisterVariable(&r_glsl);
3368         Cvar_RegisterVariable(&r_glsl_deluxemapping);
3369         Cvar_RegisterVariable(&r_glsl_offsetmapping);
3370         Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
3371         Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
3372         Cvar_RegisterVariable(&r_glsl_postprocess);
3373         Cvar_RegisterVariable(&r_glsl_postprocess_uservec1);
3374         Cvar_RegisterVariable(&r_glsl_postprocess_uservec2);
3375         Cvar_RegisterVariable(&r_glsl_postprocess_uservec3);
3376         Cvar_RegisterVariable(&r_glsl_postprocess_uservec4);
3377         Cvar_RegisterVariable(&r_water);
3378         Cvar_RegisterVariable(&r_water_resolutionmultiplier);
3379         Cvar_RegisterVariable(&r_water_clippingplanebias);
3380         Cvar_RegisterVariable(&r_water_refractdistort);
3381         Cvar_RegisterVariable(&r_water_reflectdistort);
3382         Cvar_RegisterVariable(&r_lerpsprites);
3383         Cvar_RegisterVariable(&r_lerpmodels);
3384         Cvar_RegisterVariable(&r_lerplightstyles);
3385         Cvar_RegisterVariable(&r_waterscroll);
3386         Cvar_RegisterVariable(&r_bloom);
3387         Cvar_RegisterVariable(&r_bloom_colorscale);
3388         Cvar_RegisterVariable(&r_bloom_brighten);
3389         Cvar_RegisterVariable(&r_bloom_blur);
3390         Cvar_RegisterVariable(&r_bloom_resolution);
3391         Cvar_RegisterVariable(&r_bloom_colorexponent);
3392         Cvar_RegisterVariable(&r_bloom_colorsubtract);
3393         Cvar_RegisterVariable(&r_hdr);
3394         Cvar_RegisterVariable(&r_hdr_scenebrightness);
3395         Cvar_RegisterVariable(&r_hdr_glowintensity);
3396         Cvar_RegisterVariable(&r_hdr_range);
3397         Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
3398         Cvar_RegisterVariable(&developer_texturelogging);
3399         Cvar_RegisterVariable(&gl_lightmaps);
3400         Cvar_RegisterVariable(&r_test);
3401         Cvar_RegisterVariable(&r_batchmode);
3402         Cvar_RegisterVariable(&r_glsl_saturation);
3403         Cvar_RegisterVariable(&r_framedatasize);
3404         if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
3405                 Cvar_SetValue("r_fullbrights", 0);
3406         R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
3407
3408         Cvar_RegisterVariable(&r_track_sprites);
3409         Cvar_RegisterVariable(&r_track_sprites_flags);
3410         Cvar_RegisterVariable(&r_track_sprites_scalew);
3411         Cvar_RegisterVariable(&r_track_sprites_scaleh);
3412 }
3413
3414 extern void R_Textures_Init(void);
3415 extern void GL_Draw_Init(void);
3416 extern void GL_Main_Init(void);
3417 extern void R_Shadow_Init(void);
3418 extern void R_Sky_Init(void);
3419 extern void GL_Surf_Init(void);
3420 extern void R_Particles_Init(void);
3421 extern void R_Explosion_Init(void);
3422 extern void gl_backend_init(void);
3423 extern void Sbar_Init(void);
3424 extern void R_LightningBeams_Init(void);
3425 extern void Mod_RenderInit(void);
3426
3427 void Render_Init(void)
3428 {
3429         gl_backend_init();
3430         R_Textures_Init();
3431         GL_Main_Init();
3432         GL_Draw_Init();
3433         R_Shadow_Init();
3434         R_Sky_Init();
3435         GL_Surf_Init();
3436         Sbar_Init();
3437         R_Particles_Init();
3438         R_Explosion_Init();
3439         R_LightningBeams_Init();
3440         Mod_RenderInit();
3441 }
3442
3443 /*
3444 ===============
3445 GL_Init
3446 ===============
3447 */
3448 extern char *ENGINE_EXTENSIONS;
3449 void GL_Init (void)
3450 {
3451         gl_renderer = (const char *)qglGetString(GL_RENDERER);
3452         gl_vendor = (const char *)qglGetString(GL_VENDOR);
3453         gl_version = (const char *)qglGetString(GL_VERSION);
3454         gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
3455
3456         if (!gl_extensions)
3457                 gl_extensions = "";
3458         if (!gl_platformextensions)
3459                 gl_platformextensions = "";
3460
3461         Con_Printf("GL_VENDOR: %s\n", gl_vendor);
3462         Con_Printf("GL_RENDERER: %s\n", gl_renderer);
3463         Con_Printf("GL_VERSION: %s\n", gl_version);
3464         Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
3465         Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
3466
3467         VID_CheckExtensions();
3468
3469         // LordHavoc: report supported extensions
3470         Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
3471
3472         // clear to black (loading plaque will be seen over this)
3473         CHECKGLERROR
3474         qglClearColor(0,0,0,1);CHECKGLERROR
3475         qglClear(GL_COLOR_BUFFER_BIT);CHECKGLERROR
3476 }
3477
3478 int R_CullBox(const vec3_t mins, const vec3_t maxs)
3479 {
3480         int i;
3481         mplane_t *p;
3482         for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
3483         {
3484                 // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
3485                 if (i == 4)
3486                         continue;
3487                 p = r_refdef.view.frustum + i;
3488                 switch(p->signbits)
3489                 {
3490                 default:
3491                 case 0:
3492                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
3493                                 return true;
3494                         break;
3495                 case 1:
3496                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
3497                                 return true;
3498                         break;
3499                 case 2:
3500                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
3501                                 return true;
3502                         break;
3503                 case 3:
3504                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
3505                                 return true;
3506                         break;
3507                 case 4:
3508                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
3509                                 return true;
3510                         break;
3511                 case 5:
3512                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
3513                                 return true;
3514                         break;
3515                 case 6:
3516                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
3517                                 return true;
3518                         break;
3519                 case 7:
3520                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
3521                                 return true;
3522                         break;
3523                 }
3524         }
3525         return false;
3526 }
3527
3528 int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
3529 {
3530         int i;
3531         const mplane_t *p;
3532         for (i = 0;i < numplanes;i++)
3533         {
3534                 p = planes + i;
3535                 switch(p->signbits)
3536                 {
3537                 default:
3538                 case 0:
3539                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
3540                                 return true;
3541                         break;
3542                 case 1:
3543                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
3544                                 return true;
3545                         break;
3546                 case 2:
3547                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
3548                                 return true;
3549                         break;
3550                 case 3:
3551                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
3552                                 return true;
3553                         break;
3554                 case 4:
3555                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
3556                                 return true;
3557                         break;
3558                 case 5:
3559                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
3560                                 return true;
3561                         break;
3562                 case 6:
3563                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
3564                                 return true;
3565                         break;
3566                 case 7:
3567                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
3568                                 return true;
3569                         break;
3570                 }
3571         }
3572         return false;
3573 }
3574
3575 //==================================================================================
3576
3577 // LordHavoc: this stores temporary data used within the same frame
3578
3579 qboolean r_framedata_failed;
3580 static size_t r_framedata_size;
3581 static size_t r_framedata_current;
3582 static void *r_framedata_base;
3583
3584 void R_FrameData_Reset(void)
3585 {
3586         if (r_framedata_base);
3587                 Mem_Free(r_framedata_base);
3588         r_framedata_base = NULL;
3589         r_framedata_size = 0;
3590         r_framedata_current = 0;
3591         r_framedata_failed = false;
3592 }
3593
3594 void R_FrameData_NewFrame(void)
3595 {
3596         size_t wantedsize;
3597         if (r_framedata_failed)
3598                 Cvar_SetValueQuick(&r_framedatasize, r_framedatasize.value + 1.0f);
3599         wantedsize = (size_t)(r_framedatasize.value * 1024*1024);
3600         wantedsize = bound(65536, wantedsize, 128*1024*1024);
3601         if (r_framedata_size != wantedsize)
3602         {
3603                 r_framedata_size = wantedsize;
3604                 if (r_framedata_base);
3605                         Mem_Free(r_framedata_base);
3606                 r_framedata_base = Mem_Alloc(r_main_mempool, r_framedata_size);
3607         }
3608         r_framedata_current = 0;
3609         r_framedata_failed = false;
3610 }
3611
3612 void *R_FrameData_Alloc(size_t size)
3613 {
3614         void *data;
3615
3616         // align to 16 byte boundary
3617         size = (size + 15) & ~15;
3618         data = (void *)((unsigned char*)r_framedata_base + r_framedata_current);
3619         r_framedata_current += size;
3620
3621         // check overflow
3622         if (r_framedata_current > r_framedata_size)
3623                 r_framedata_failed = true;
3624
3625         // return NULL on everything after a failure
3626         if (r_framedata_failed)
3627                 return NULL;
3628
3629         return data;
3630 }
3631
3632 void *R_FrameData_Store(size_t size, void *data)
3633 {
3634         void *d = R_FrameData_Alloc(size);
3635         if (d)
3636                 memcpy(d, data, size);
3637         return d;
3638 }
3639
3640 //==================================================================================
3641
3642 // LordHavoc: animcache originally written by Echon, rewritten since then
3643
3644 /**
3645  * Animation cache prevents re-generating mesh data for an animated model
3646  * multiple times in one frame for lighting, shadowing, reflections, etc.
3647  */
3648
3649 void R_AnimCache_Free(void)
3650 {
3651 }
3652
3653 void R_AnimCache_ClearCache(void)
3654 {
3655         int i;
3656         entity_render_t *ent;
3657
3658         for (i = 0;i < r_refdef.scene.numentities;i++)
3659         {
3660                 ent = r_refdef.scene.entities[i];
3661                 ent->animcache_vertex3f = NULL;
3662                 ent->animcache_normal3f = NULL;
3663                 ent->animcache_svector3f = NULL;
3664                 ent->animcache_tvector3f = NULL;
3665         }
3666 }
3667
3668 qboolean R_AnimCache_GetEntity(entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
3669 {
3670         dp_model_t *model = ent->model;
3671         int numvertices;
3672         // see if it's already cached this frame
3673         if (ent->animcache_vertex3f)
3674         {
3675                 // add normals/tangents if needed
3676                 if (wantnormals || wanttangents)
3677                 {
3678                         if (ent->animcache_normal3f)
3679                                 wantnormals = false;
3680                         if (ent->animcache_svector3f)
3681                                 wanttangents = false;
3682                         if (wantnormals || wanttangents)
3683                         {
3684                                 numvertices = model->surfmesh.num_vertices;
3685                                 if (wantnormals)
3686                                         ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
3687                                 if (wanttangents)
3688                                 {
3689                                         ent->animcache_svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
3690                                         ent->animcache_tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
3691                                 }
3692                                 if (!r_framedata_failed)
3693                                         model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? ent->animcache_normal3f : NULL, wanttangents ? ent->animcache_svector3f : NULL, wanttangents ? ent->animcache_tvector3f : NULL);
3694                         }
3695                 }
3696         }
3697         else
3698         {
3699                 // see if this ent is worth caching
3700                 if (!model || !model->Draw || !model->surfmesh.isanimated || !model->AnimateVertices || (ent->frameblend[0].lerp == 1 && ent->frameblend[0].subframe == 0 && !ent->skeleton))
3701                         return false;
3702                 // get some memory for this entity and generate mesh data
3703                 numvertices = model->surfmesh.num_vertices;
3704                 ent->animcache_vertex3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
3705                 if (wantnormals)
3706                         ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
3707                 if (wanttangents)
3708                 {
3709 &n