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