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