Add a cvar: r_water_cameraentitiesonly.
[xonotic/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 #include "ft2.h"
28 #include "csprogs.h"
29 #include "cl_video.h"
30 #include "dpsoftrast.h"
31
32 #ifdef SUPPORTD3D
33 #include <d3d9.h>
34 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
35 #endif
36
37 mempool_t *r_main_mempool;
38 rtexturepool_t *r_main_texturepool;
39
40 static int r_textureframe = 0; ///< used only by R_GetCurrentTexture
41
42 static qboolean r_loadnormalmap;
43 static qboolean r_loadgloss;
44 qboolean r_loadfog;
45 static qboolean r_loaddds;
46 static qboolean r_savedds;
47 static qboolean r_gpuskeletal;
48
49 //
50 // screen size info
51 //
52 r_refdef_t r_refdef;
53
54 cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "screen motionblur - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
55 cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "screen motionblur based on damage - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
56 cvar_t r_motionblur_averaging = {CVAR_SAVE, "r_motionblur_averaging", "0.1", "sliding average reaction time for velocity (higher = slower adaption to change)"};
57 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
58 cvar_t r_motionblur_minblur = {CVAR_SAVE, "r_motionblur_minblur", "0.5", "factor of blur to apply at all times (always have this amount of blur no matter what the other factors are)"};
59 cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.9", "maxmimum amount of blur"};
60 cvar_t r_motionblur_velocityfactor = {CVAR_SAVE, "r_motionblur_velocityfactor", "1", "factoring in of player velocity to the blur equation - the faster the player moves around the map, the more blur they get"};
61 cvar_t r_motionblur_velocityfactor_minspeed = {CVAR_SAVE, "r_motionblur_velocityfactor_minspeed", "400", "lower value of velocity when it starts to factor into blur equation"};
62 cvar_t r_motionblur_velocityfactor_maxspeed = {CVAR_SAVE, "r_motionblur_velocityfactor_maxspeed", "800", "upper value of velocity when it reaches the peak factor into blur equation"};
63 cvar_t r_motionblur_mousefactor = {CVAR_SAVE, "r_motionblur_mousefactor", "2", "factoring in of mouse acceleration to the blur equation - the faster the player turns their mouse, the more blur they get"};
64 cvar_t r_motionblur_mousefactor_minspeed = {CVAR_SAVE, "r_motionblur_mousefactor_minspeed", "0", "lower value of mouse acceleration when it starts to factor into blur equation"};
65 cvar_t r_motionblur_mousefactor_maxspeed = {CVAR_SAVE, "r_motionblur_mousefactor_maxspeed", "50", "upper value of mouse acceleration when it reaches the peak factor into blur equation"};
66
67 // TODO do we want a r_equalize_entities cvar that works on all ents, or would that be a cheat?
68 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"};
69 cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio"};
70 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)"};
71 cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level"};
72
73 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"};
74 cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
75 cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
76 cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
77 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
78 cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
79 cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
80 cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"};
81 cvar_t r_transparent_sortsurfacesbynearest = {0, "r_transparent_sortsurfacesbynearest", "1", "sort entity and world surfaces by nearest point on bounding box instead of using the center of the bounding box, usually reduces sorting artifacts"};
82 cvar_t r_transparent_useplanardistance = {0, "r_transparent_useplanardistance", "0", "sort transparent meshes by distance from view plane rather than spherical distance to the chosen point"};
83 cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"};
84 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%,  10 = 100%)"};
85 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)"};
86 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
87 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
88 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"};
89 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"};
90 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
91 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"};
92 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"};
93 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"};
94 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
95 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
96 cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
97 cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
98 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
99 cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
100 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
101 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)"};
102 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)"};
103 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
104 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
105 cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
106 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
107 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
108
109 cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"};
110 cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"};
111 #define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
112
113 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
114 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
115 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
116 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."};
117 cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
118 cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
119 cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
120 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."};
121 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
122 cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
123 cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
124 cvar_t r_shadows_shadowmapbias = {CVAR_SAVE, "r_shadows_shadowmapbias", "-1", "sets shadowmap bias for fake shadows. -1 sets the value of r_shadow_shadowmapping_bias. Needs shadowmapping ON."};
125 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
126 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"};
127 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"};
128 cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
129 cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
130 cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
131 cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
132 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
133 cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
134 cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
135 cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
136 cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
137 cvar_t r_celshading = {CVAR_SAVE, "r_celshading", "0", "cartoon-style light shading (OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
138 cvar_t r_celoutlines = {CVAR_SAVE, "r_celoutlines", "0", "cartoon-style outlines (requires r_shadow_deferred; OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
139
140 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
141 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
142 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
143 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
144 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
145 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
146 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
147 cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
148
149 cvar_t r_texture_dds_load = {CVAR_SAVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"};
150 cvar_t r_texture_dds_save = {CVAR_SAVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"};
151
152 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"};
153 static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
154 static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
155
156 cvar_t r_usedepthtextures = {CVAR_SAVE, "r_usedepthtextures", "1", "use depth texture instead of depth renderbuffer where possible, uses less video memory but may render slower (or faster) depending on hardware"};
157 cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"};
158 cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"};
159 cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
160 cvar_t r_viewscale_fpsscaling_min = {CVAR_SAVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"};
161 cvar_t r_viewscale_fpsscaling_multiply = {CVAR_SAVE, "r_viewscale_fpsscaling_multiply", "5", "adjust quality up or down by the frametime difference from 1.0/target, multiplied by this factor"};
162 cvar_t r_viewscale_fpsscaling_stepsize = {CVAR_SAVE, "r_viewscale_fpsscaling_stepsize", "0.01", "smallest adjustment to hit the target framerate (this value prevents minute oscillations)"};
163 cvar_t r_viewscale_fpsscaling_stepmax = {CVAR_SAVE, "r_viewscale_fpsscaling_stepmax", "1.00", "largest adjustment to hit the target framerate (this value prevents wild overshooting of the estimate)"};
164 cvar_t r_viewscale_fpsscaling_target = {CVAR_SAVE, "r_viewscale_fpsscaling_target", "70", "desired framerate"};
165
166 cvar_t r_glsl_skeletal = {CVAR_SAVE, "r_glsl_skeletal", "1", "render skeletal models faster using a gpu-skinning technique"};
167 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)"};
168 cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
169 cvar_t r_glsl_offsetmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_steps", "2", "offset mapping steps (note: too high values may be not supported by your GPU)"};
170 cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
171 cvar_t r_glsl_offsetmapping_reliefmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_steps", "10", "relief mapping steps (note: too high values may be not supported by your GPU)"};
172 cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_refinesteps", "5", "relief mapping refine steps (these are a binary search executed as the last step as given by r_glsl_offsetmapping_reliefmapping_steps)"};
173 cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
174 cvar_t r_glsl_offsetmapping_lod = {CVAR_SAVE, "r_glsl_offsetmapping_lod", "0", "apply distance-based level-of-detail correction to number of offsetmappig steps, effectively making it render faster on large open-area maps"};
175 cvar_t r_glsl_offsetmapping_lod_distance = {CVAR_SAVE, "r_glsl_offsetmapping_lod_distance", "32", "first LOD level distance, second level (-50% steps) is 2x of this, third (33%) - 3x etc."};
176 cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
177 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)"};
178 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)"};
179 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)"};
180 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)"};
181 cvar_t r_glsl_postprocess_uservec1_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec1_enable", "1", "enables postprocessing uservec1 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
182 cvar_t r_glsl_postprocess_uservec2_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec2_enable", "1", "enables postprocessing uservec2 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
183 cvar_t r_glsl_postprocess_uservec3_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec3_enable", "1", "enables postprocessing uservec3 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
184 cvar_t r_glsl_postprocess_uservec4_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
185
186 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)"};
187 cvar_t r_water_cameraentitiesonly = {CVAR_SAVE, "r_water_cameraentitiesonly", "0", "whether to only show QC-defined reflections/refractions (typically used for camera- or portal-like effects)"};
188 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
189 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"};
190 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
191 cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
192 cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
193 cvar_t r_water_lowquality = {0, "r_water_lowquality", "0", "special option to accelerate water rendering, 1 disables shadows and particles, 2 disables all dynamic lights"};
194 cvar_t r_water_hideplayer = {CVAR_SAVE, "r_water_hideplayer", "0", "if set to 1 then player will be hidden in refraction views, if set to 2 then player will also be hidden in reflection views, player is always visible in camera views"};
195 cvar_t r_water_fbo = {CVAR_SAVE, "r_water_fbo", "1", "enables use of render to texture for water effects, otherwise copy to texture is used (slower)"};
196
197 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
198 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
199 cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
200 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
201
202 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
203 cvar_t r_bloom_colorscale = {CVAR_SAVE, "r_bloom_colorscale", "1", "how bright the glow is"};
204
205 cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
206 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
207 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
208 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
209 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
210 cvar_t r_bloom_scenebrightness = {CVAR_SAVE, "r_bloom_scenebrightness", "1", "global rendering brightness when bloom is enabled"};
211
212 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
213 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
214 cvar_t r_hdr_irisadaptation = {CVAR_SAVE, "r_hdr_irisadaptation", "0", "adjust scene brightness according to light intensity at player location"};
215 cvar_t r_hdr_irisadaptation_multiplier = {CVAR_SAVE, "r_hdr_irisadaptation_multiplier", "2", "brightness at which value will be 1.0"};
216 cvar_t r_hdr_irisadaptation_minvalue = {CVAR_SAVE, "r_hdr_irisadaptation_minvalue", "0.5", "minimum value that can result from multiplier / brightness"};
217 cvar_t r_hdr_irisadaptation_maxvalue = {CVAR_SAVE, "r_hdr_irisadaptation_maxvalue", "4", "maximum value that can result from multiplier / brightness"};
218 cvar_t r_hdr_irisadaptation_value = {0, "r_hdr_irisadaptation_value", "1", "current value as scenebrightness multiplier, changes continuously when irisadaptation is active"};
219 cvar_t r_hdr_irisadaptation_fade_up = {CVAR_SAVE, "r_hdr_irisadaptation_fade_up", "0.1", "fade rate at which value adjusts to darkness"};
220 cvar_t r_hdr_irisadaptation_fade_down = {CVAR_SAVE, "r_hdr_irisadaptation_fade_down", "0.5", "fade rate at which value adjusts to brightness"};
221 cvar_t r_hdr_irisadaptation_radius = {CVAR_SAVE, "r_hdr_irisadaptation_radius", "15", "lighting within this many units of the eye is averaged"};
222
223 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"};
224
225 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"};
226
227 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers), a value of 2 keeps normalmap shading"};
228
229 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
230
231 cvar_t r_batch_multidraw = {CVAR_SAVE, "r_batch_multidraw", "1", "issue multiple glDrawElements calls when rendering a batch of surfaces with the same texture (otherwise the index data is copied to make it one draw)"};
232 cvar_t r_batch_multidraw_mintriangles = {CVAR_SAVE, "r_batch_multidraw_mintriangles", "0", "minimum number of triangles to activate multidraw path (copying small groups of triangles may be faster)"};
233 cvar_t r_batch_debugdynamicvertexpath = {CVAR_SAVE, "r_batch_debugdynamicvertexpath", "0", "force the dynamic batching code path for debugging purposes"};
234 cvar_t r_batch_dynamicbuffer = {CVAR_SAVE, "r_batch_dynamicbuffer", "0", "use vertex/index buffers for drawing dynamic and copytriangles batches"};
235
236 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
237 cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"};
238
239 cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer, requires mod_q3shader_force_terrain_alphaflag on."};
240
241 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
242 cvar_t r_buffermegs[R_BUFFERDATA_COUNT] =
243 {
244         {CVAR_SAVE, "r_buffermegs_vertex", "4", "vertex buffer size for one frame"},
245         {CVAR_SAVE, "r_buffermegs_index16", "1", "index buffer size for one frame (16bit indices)"},
246         {CVAR_SAVE, "r_buffermegs_index32", "1", "index buffer size for one frame (32bit indices)"},
247         {CVAR_SAVE, "r_buffermegs_uniform", "0.25", "uniform buffer size for one frame"},
248 };
249
250 extern cvar_t v_glslgamma;
251 extern cvar_t v_glslgamma_2d;
252
253 extern qboolean v_flipped_state;
254
255 r_framebufferstate_t r_fb;
256
257 /// shadow volume bsp struct with automatically growing nodes buffer
258 svbsp_t r_svbsp;
259
260 int r_uniformbufferalignment = 32; // dynamically updated to match GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
261
262 rtexture_t *r_texture_blanknormalmap;
263 rtexture_t *r_texture_white;
264 rtexture_t *r_texture_grey128;
265 rtexture_t *r_texture_black;
266 rtexture_t *r_texture_notexture;
267 rtexture_t *r_texture_whitecube;
268 rtexture_t *r_texture_normalizationcube;
269 rtexture_t *r_texture_fogattenuation;
270 rtexture_t *r_texture_fogheighttexture;
271 rtexture_t *r_texture_gammaramps;
272 unsigned int r_texture_gammaramps_serial;
273 //rtexture_t *r_texture_fogintensity;
274 rtexture_t *r_texture_reflectcube;
275
276 // TODO: hash lookups?
277 typedef struct cubemapinfo_s
278 {
279         char basename[64];
280         rtexture_t *texture;
281 }
282 cubemapinfo_t;
283
284 int r_texture_numcubemaps;
285 cubemapinfo_t *r_texture_cubemaps[MAX_CUBEMAPS];
286
287 unsigned int r_queries[MAX_OCCLUSION_QUERIES];
288 unsigned int r_numqueries;
289 unsigned int r_maxqueries;
290
291 typedef struct r_qwskincache_s
292 {
293         char name[MAX_QPATH];
294         skinframe_t *skinframe;
295 }
296 r_qwskincache_t;
297
298 static r_qwskincache_t *r_qwskincache;
299 static int r_qwskincache_size;
300
301 /// vertex coordinates for a quad that covers the screen exactly
302 extern const float r_screenvertex3f[12];
303 extern const float r_d3dscreenvertex3f[12];
304 const float r_screenvertex3f[12] =
305 {
306         0, 0, 0,
307         1, 0, 0,
308         1, 1, 0,
309         0, 1, 0
310 };
311 const float r_d3dscreenvertex3f[12] =
312 {
313         0, 1, 0,
314         1, 1, 0,
315         1, 0, 0,
316         0, 0, 0
317 };
318
319 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
320 {
321         int i;
322         for (i = 0;i < verts;i++)
323         {
324                 out[0] = in[0] * r;
325                 out[1] = in[1] * g;
326                 out[2] = in[2] * b;
327                 out[3] = in[3];
328                 in += 4;
329                 out += 4;
330         }
331 }
332
333 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
334 {
335         int i;
336         for (i = 0;i < verts;i++)
337         {
338                 out[0] = r;
339                 out[1] = g;
340                 out[2] = b;
341                 out[3] = a;
342                 out += 4;
343         }
344 }
345
346 // FIXME: move this to client?
347 void FOG_clear(void)
348 {
349         if (gamemode == GAME_NEHAHRA)
350         {
351                 Cvar_Set("gl_fogenable", "0");
352                 Cvar_Set("gl_fogdensity", "0.2");
353                 Cvar_Set("gl_fogred", "0.3");
354                 Cvar_Set("gl_foggreen", "0.3");
355                 Cvar_Set("gl_fogblue", "0.3");
356         }
357         r_refdef.fog_density = 0;
358         r_refdef.fog_red = 0;
359         r_refdef.fog_green = 0;
360         r_refdef.fog_blue = 0;
361         r_refdef.fog_alpha = 1;
362         r_refdef.fog_start = 0;
363         r_refdef.fog_end = 16384;
364         r_refdef.fog_height = 1<<30;
365         r_refdef.fog_fadedepth = 128;
366         memset(r_refdef.fog_height_texturename, 0, sizeof(r_refdef.fog_height_texturename));
367 }
368
369 static void R_BuildBlankTextures(void)
370 {
371         unsigned char data[4];
372         data[2] = 128; // normal X
373         data[1] = 128; // normal Y
374         data[0] = 255; // normal Z
375         data[3] = 255; // height
376         r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
377         data[0] = 255;
378         data[1] = 255;
379         data[2] = 255;
380         data[3] = 255;
381         r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
382         data[0] = 128;
383         data[1] = 128;
384         data[2] = 128;
385         data[3] = 255;
386         r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
387         data[0] = 0;
388         data[1] = 0;
389         data[2] = 0;
390         data[3] = 255;
391         r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
392 }
393
394 static void R_BuildNoTexture(void)
395 {
396         int x, y;
397         unsigned char pix[16][16][4];
398         // this makes a light grey/dark grey checkerboard texture
399         for (y = 0;y < 16;y++)
400         {
401                 for (x = 0;x < 16;x++)
402                 {
403                         if ((y < 8) ^ (x < 8))
404                         {
405                                 pix[y][x][0] = 128;
406                                 pix[y][x][1] = 128;
407                                 pix[y][x][2] = 128;
408                                 pix[y][x][3] = 255;
409                         }
410                         else
411                         {
412                                 pix[y][x][0] = 64;
413                                 pix[y][x][1] = 64;
414                                 pix[y][x][2] = 64;
415                                 pix[y][x][3] = 255;
416                         }
417                 }
418         }
419         r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, -1, NULL);
420 }
421
422 static void R_BuildWhiteCube(void)
423 {
424         unsigned char data[6*1*1*4];
425         memset(data, 255, sizeof(data));
426         r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
427 }
428
429 static void R_BuildNormalizationCube(void)
430 {
431         int x, y, side;
432         vec3_t v;
433         vec_t s, t, intensity;
434 #define NORMSIZE 64
435         unsigned char *data;
436         data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
437         for (side = 0;side < 6;side++)
438         {
439                 for (y = 0;y < NORMSIZE;y++)
440                 {
441                         for (x = 0;x < NORMSIZE;x++)
442                         {
443                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
444                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
445                                 switch(side)
446                                 {
447                                 default:
448                                 case 0:
449                                         v[0] = 1;
450                                         v[1] = -t;
451                                         v[2] = -s;
452                                         break;
453                                 case 1:
454                                         v[0] = -1;
455                                         v[1] = -t;
456                                         v[2] = s;
457                                         break;
458                                 case 2:
459                                         v[0] = s;
460                                         v[1] = 1;
461                                         v[2] = t;
462                                         break;
463                                 case 3:
464                                         v[0] = s;
465                                         v[1] = -1;
466                                         v[2] = -t;
467                                         break;
468                                 case 4:
469                                         v[0] = s;
470                                         v[1] = -t;
471                                         v[2] = 1;
472                                         break;
473                                 case 5:
474                                         v[0] = -s;
475                                         v[1] = -t;
476                                         v[2] = -1;
477                                         break;
478                                 }
479                                 intensity = 127.0f / sqrt(DotProduct(v, v));
480                                 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
481                                 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
482                                 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
483                                 data[((side*64+y)*64+x)*4+3] = 255;
484                         }
485                 }
486         }
487         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
488         Mem_Free(data);
489 }
490
491 static void R_BuildFogTexture(void)
492 {
493         int x, b;
494 #define FOGWIDTH 256
495         unsigned char data1[FOGWIDTH][4];
496         //unsigned char data2[FOGWIDTH][4];
497         double d, r, alpha;
498
499         r_refdef.fogmasktable_start = r_refdef.fog_start;
500         r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
501         r_refdef.fogmasktable_range = r_refdef.fogrange;
502         r_refdef.fogmasktable_density = r_refdef.fog_density;
503
504         r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
505         for (x = 0;x < FOGMASKTABLEWIDTH;x++)
506         {
507                 d = (x * r - r_refdef.fogmasktable_start);
508                 if(developer_extra.integer)
509                         Con_DPrintf("%f ", d);
510                 d = max(0, d);
511                 if (r_fog_exp2.integer)
512                         alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
513                 else
514                         alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
515                 if(developer_extra.integer)
516                         Con_DPrintf(" : %f ", alpha);
517                 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
518                 if(developer_extra.integer)
519                         Con_DPrintf(" = %f\n", alpha);
520                 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
521         }
522
523         for (x = 0;x < FOGWIDTH;x++)
524         {
525                 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
526                 data1[x][0] = b;
527                 data1[x][1] = b;
528                 data1[x][2] = b;
529                 data1[x][3] = 255;
530                 //data2[x][0] = 255 - b;
531                 //data2[x][1] = 255 - b;
532                 //data2[x][2] = 255 - b;
533                 //data2[x][3] = 255;
534         }
535         if (r_texture_fogattenuation)
536         {
537                 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
538                 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
539         }
540         else
541         {
542                 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
543                 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
544         }
545 }
546
547 static void R_BuildFogHeightTexture(void)
548 {
549         unsigned char *inpixels;
550         int size;
551         int x;
552         int y;
553         int j;
554         float c[4];
555         float f;
556         inpixels = NULL;
557         strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename));
558         if (r_refdef.fogheighttexturename[0])
559                 inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false, NULL);
560         if (!inpixels)
561         {
562                 r_refdef.fog_height_tablesize = 0;
563                 if (r_texture_fogheighttexture)
564                         R_FreeTexture(r_texture_fogheighttexture);
565                 r_texture_fogheighttexture = NULL;
566                 if (r_refdef.fog_height_table2d)
567                         Mem_Free(r_refdef.fog_height_table2d);
568                 r_refdef.fog_height_table2d = NULL;
569                 if (r_refdef.fog_height_table1d)
570                         Mem_Free(r_refdef.fog_height_table1d);
571                 r_refdef.fog_height_table1d = NULL;
572                 return;
573         }
574         size = image_width;
575         r_refdef.fog_height_tablesize = size;
576         r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
577         r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
578         memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
579         Mem_Free(inpixels);
580         // LordHavoc: now the magic - what is that table2d for?  it is a cooked
581         // average fog color table accounting for every fog layer between a point
582         // and the camera.  (Note: attenuation is handled separately!)
583         for (y = 0;y < size;y++)
584         {
585                 for (x = 0;x < size;x++)
586                 {
587                         Vector4Clear(c);
588                         f = 0;
589                         if (x < y)
590                         {
591                                 for (j = x;j <= y;j++)
592                                 {
593                                         Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
594                                         f++;
595                                 }
596                         }
597                         else
598                         {
599                                 for (j = x;j >= y;j--)
600                                 {
601                                         Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
602                                         f++;
603                                 }
604                         }
605                         f = 1.0f / f;
606                         r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f);
607                         r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f);
608                         r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f);
609                         r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
610                 }
611         }
612         r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, -1, NULL);
613 }
614
615 //=======================================================================================================================================================
616
617 static const char *builtinshaderstrings[] =
618 {
619 #include "shader_glsl.h"
620 0
621 };
622
623 const char *builtinhlslshaderstrings[] =
624 {
625 #include "shader_hlsl.h"
626 0
627 };
628
629 char *glslshaderstring = NULL;
630 char *hlslshaderstring = NULL;
631
632 //=======================================================================================================================================================
633
634 typedef struct shaderpermutationinfo_s
635 {
636         const char *pretext;
637         const char *name;
638 }
639 shaderpermutationinfo_t;
640
641 typedef struct shadermodeinfo_s
642 {
643         const char *filename;
644         const char *pretext;
645         const char *name;
646 }
647 shadermodeinfo_t;
648
649 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
650 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
651 {
652         {"#define USEDIFFUSE\n", " diffuse"},
653         {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
654         {"#define USEVIEWTINT\n", " viewtint"},
655         {"#define USECOLORMAPPING\n", " colormapping"},
656         {"#define USESATURATION\n", " saturation"},
657         {"#define USEFOGINSIDE\n", " foginside"},
658         {"#define USEFOGOUTSIDE\n", " fogoutside"},
659         {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
660         {"#define USEFOGALPHAHACK\n", " fogalphahack"},
661         {"#define USEGAMMARAMPS\n", " gammaramps"},
662         {"#define USECUBEFILTER\n", " cubefilter"},
663         {"#define USEGLOW\n", " glow"},
664         {"#define USEBLOOM\n", " bloom"},
665         {"#define USESPECULAR\n", " specular"},
666         {"#define USEPOSTPROCESSING\n", " postprocessing"},
667         {"#define USEREFLECTION\n", " reflection"},
668         {"#define USEOFFSETMAPPING\n", " offsetmapping"},
669         {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
670         {"#define USESHADOWMAP2D\n", " shadowmap2d"},
671         {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm
672         {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
673         {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
674         {"#define USEALPHAKILL\n", " alphakill"},
675         {"#define USEREFLECTCUBE\n", " reflectcube"},
676         {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
677         {"#define USEBOUNCEGRID\n", " bouncegrid"},
678         {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm
679         {"#define USETRIPPY\n", " trippy"},
680         {"#define USEDEPTHRGB\n", " depthrgb"},
681         {"#define USEALPHAGENVERTEX\n", " alphagenvertex"},
682         {"#define USESKELETAL\n", " skeletal"},
683         {"#define USEOCCLUDE\n", " occlude"}
684 };
685
686 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
687 shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
688 {
689         {"glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
690         {"glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
691         {"glsl/default.glsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
692         {"glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
693         {"glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
694         {"glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
695         {"glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
696         {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
697         {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
698         {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
699         {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
700         {"glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
701         {"glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
702         {"glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
703         {"glsl/default.glsl", "#define MODE_WATER\n", " water"},
704         {"glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
705         {"glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
706 };
707
708 shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
709 {
710         {"hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"},
711         {"hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"},
712         {"hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
713         {"hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
714         {"hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
715         {"hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"},
716         {"hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
717         {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
718         {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
719         {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
720         {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
721         {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
722         {"hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
723         {"hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
724         {"hlsl/default.hlsl", "#define MODE_WATER\n", " water"},
725         {"hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
726         {"hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
727 };
728
729 struct r_glsl_permutation_s;
730 typedef struct r_glsl_permutation_s
731 {
732         /// hash lookup data
733         struct r_glsl_permutation_s *hashnext;
734         unsigned int mode;
735         unsigned int permutation;
736
737         /// indicates if we have tried compiling this permutation already
738         qboolean compiled;
739         /// 0 if compilation failed
740         int program;
741         // texture units assigned to each detected uniform
742         int tex_Texture_First;
743         int tex_Texture_Second;
744         int tex_Texture_GammaRamps;
745         int tex_Texture_Normal;
746         int tex_Texture_Color;
747         int tex_Texture_Gloss;
748         int tex_Texture_Glow;
749         int tex_Texture_SecondaryNormal;
750         int tex_Texture_SecondaryColor;
751         int tex_Texture_SecondaryGloss;
752         int tex_Texture_SecondaryGlow;
753         int tex_Texture_Pants;
754         int tex_Texture_Shirt;
755         int tex_Texture_FogHeightTexture;
756         int tex_Texture_FogMask;
757         int tex_Texture_Lightmap;
758         int tex_Texture_Deluxemap;
759         int tex_Texture_Attenuation;
760         int tex_Texture_Cube;
761         int tex_Texture_Refraction;
762         int tex_Texture_Reflection;
763         int tex_Texture_ShadowMap2D;
764         int tex_Texture_CubeProjection;
765         int tex_Texture_ScreenNormalMap;
766         int tex_Texture_ScreenDiffuse;
767         int tex_Texture_ScreenSpecular;
768         int tex_Texture_ReflectMask;
769         int tex_Texture_ReflectCube;
770         int tex_Texture_BounceGrid;
771         /// locations of detected uniforms in program object, or -1 if not found
772         int loc_Texture_First;
773         int loc_Texture_Second;
774         int loc_Texture_GammaRamps;
775         int loc_Texture_Normal;
776         int loc_Texture_Color;
777         int loc_Texture_Gloss;
778         int loc_Texture_Glow;
779         int loc_Texture_SecondaryNormal;
780         int loc_Texture_SecondaryColor;
781         int loc_Texture_SecondaryGloss;
782         int loc_Texture_SecondaryGlow;
783         int loc_Texture_Pants;
784         int loc_Texture_Shirt;
785         int loc_Texture_FogHeightTexture;
786         int loc_Texture_FogMask;
787         int loc_Texture_Lightmap;
788         int loc_Texture_Deluxemap;
789         int loc_Texture_Attenuation;
790         int loc_Texture_Cube;
791         int loc_Texture_Refraction;
792         int loc_Texture_Reflection;
793         int loc_Texture_ShadowMap2D;
794         int loc_Texture_CubeProjection;
795         int loc_Texture_ScreenNormalMap;
796         int loc_Texture_ScreenDiffuse;
797         int loc_Texture_ScreenSpecular;
798         int loc_Texture_ReflectMask;
799         int loc_Texture_ReflectCube;
800         int loc_Texture_BounceGrid;
801         int loc_Alpha;
802         int loc_BloomBlur_Parameters;
803         int loc_ClientTime;
804         int loc_Color_Ambient;
805         int loc_Color_Diffuse;
806         int loc_Color_Specular;
807         int loc_Color_Glow;
808         int loc_Color_Pants;
809         int loc_Color_Shirt;
810         int loc_DeferredColor_Ambient;
811         int loc_DeferredColor_Diffuse;
812         int loc_DeferredColor_Specular;
813         int loc_DeferredMod_Diffuse;
814         int loc_DeferredMod_Specular;
815         int loc_DistortScaleRefractReflect;
816         int loc_EyePosition;
817         int loc_FogColor;
818         int loc_FogHeightFade;
819         int loc_FogPlane;
820         int loc_FogPlaneViewDist;
821         int loc_FogRangeRecip;
822         int loc_LightColor;
823         int loc_LightDir;
824         int loc_LightPosition;
825         int loc_OffsetMapping_ScaleSteps;
826         int loc_OffsetMapping_LodDistance;
827         int loc_OffsetMapping_Bias;
828         int loc_PixelSize;
829         int loc_ReflectColor;
830         int loc_ReflectFactor;
831         int loc_ReflectOffset;
832         int loc_RefractColor;
833         int loc_Saturation;
834         int loc_ScreenCenterRefractReflect;
835         int loc_ScreenScaleRefractReflect;
836         int loc_ScreenToDepth;
837         int loc_ShadowMap_Parameters;
838         int loc_ShadowMap_TextureScale;
839         int loc_SpecularPower;
840         int loc_Skeletal_Transform12;
841         int loc_UserVec1;
842         int loc_UserVec2;
843         int loc_UserVec3;
844         int loc_UserVec4;
845         int loc_ViewTintColor;
846         int loc_ViewToLight;
847         int loc_ModelToLight;
848         int loc_TexMatrix;
849         int loc_BackgroundTexMatrix;
850         int loc_ModelViewProjectionMatrix;
851         int loc_ModelViewMatrix;
852         int loc_PixelToScreenTexCoord;
853         int loc_ModelToReflectCube;
854         int loc_ShadowMapMatrix;
855         int loc_BloomColorSubtract;
856         int loc_NormalmapScrollBlend;
857         int loc_BounceGridMatrix;
858         int loc_BounceGridIntensity;
859         /// uniform block bindings
860         int ubibind_Skeletal_Transform12_UniformBlock;
861         /// uniform block indices
862         int ubiloc_Skeletal_Transform12_UniformBlock;
863 }
864 r_glsl_permutation_t;
865
866 #define SHADERPERMUTATION_HASHSIZE 256
867
868
869 // non-degradable "lightweight" shader parameters to keep the permutations simpler
870 // these can NOT degrade! only use for simple stuff
871 enum
872 {
873         SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0, ///< red compensation filter for saturation
874         SHADERSTATICPARM_EXACTSPECULARMATH = 1, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
875         SHADERSTATICPARM_POSTPROCESS_USERVEC1 = 2, ///< postprocess uservec1 is enabled
876         SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
877         SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
878         SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5,  ///< postprocess uservec4 is enabled
879         SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
880         SHADERSTATICPARM_OFFSETMAPPING_USELOD = 7,  ///< LOD for offsetmapping
881         SHADERSTATICPARM_SHADOWMAPPCF_1 = 8, ///< PCF 1
882         SHADERSTATICPARM_SHADOWMAPPCF_2 = 9, ///< PCF 2
883         SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler
884         SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math)
885         SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines)
886         SHADERSTATICPARM_FXAA = 13 ///< fast approximate anti aliasing
887 };
888 #define SHADERSTATICPARMS_COUNT 14
889
890 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
891 static int shaderstaticparms_count = 0;
892
893 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
894 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
895
896 extern qboolean r_shadow_shadowmapsampler;
897 extern int r_shadow_shadowmappcf;
898 qboolean R_CompileShader_CheckStaticParms(void)
899 {
900         static int r_compileshader_staticparms_save[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5];
901         memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
902         memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
903
904         // detect all
905         if (r_glsl_saturation_redcompensate.integer)
906                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
907         if (r_glsl_vertextextureblend_usebothalphas.integer)
908                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS);
909         if (r_shadow_glossexact.integer)
910                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_EXACTSPECULARMATH);
911         if (r_glsl_postprocess.integer)
912         {
913                 if (r_glsl_postprocess_uservec1_enable.integer)
914                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC1);
915                 if (r_glsl_postprocess_uservec2_enable.integer)
916                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC2);
917                 if (r_glsl_postprocess_uservec3_enable.integer)
918                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC3);
919                 if (r_glsl_postprocess_uservec4_enable.integer)
920                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
921         }
922         if (r_fxaa.integer)
923                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_FXAA);
924         if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
925                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
926
927         if (r_shadow_shadowmapsampler)
928                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWSAMPLER);
929         if (r_shadow_shadowmappcf > 1)
930                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_2);
931         else if (r_shadow_shadowmappcf)
932                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_1);
933         if (r_celshading.integer)
934                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELSHADING);
935         if (r_celoutlines.integer)
936                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELOUTLINES);
937
938         return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
939 }
940
941 #define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
942         if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
943                 shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
944         else \
945                 shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
946 static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
947 {
948         shaderstaticparms_count = 0;
949
950         // emit all
951         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
952         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_EXACTSPECULARMATH, "USEEXACTSPECULARMATH");
953         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC1, "USERVEC1");
954         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC2, "USERVEC2");
955         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
956         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
957         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
958         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_OFFSETMAPPING_USELOD, "USEOFFSETMAPPING_LOD");
959         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_1, "USESHADOWMAPPCF 1");
960         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_2, "USESHADOWMAPPCF 2");
961         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER");
962         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING");
963         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES");
964         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_FXAA, "USEFXAA");
965 }
966
967 /// information about each possible shader permutation
968 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
969 /// currently selected permutation
970 r_glsl_permutation_t *r_glsl_permutation;
971 /// storage for permutations linked in the hash table
972 memexpandablearray_t r_glsl_permutationarray;
973
974 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation)
975 {
976         //unsigned int hashdepth = 0;
977         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
978         r_glsl_permutation_t *p;
979         for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
980         {
981                 if (p->mode == mode && p->permutation == permutation)
982                 {
983                         //if (hashdepth > 10)
984                         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
985                         return p;
986                 }
987                 //hashdepth++;
988         }
989         p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
990         p->mode = mode;
991         p->permutation = permutation;
992         p->hashnext = r_glsl_permutationhash[mode][hashindex];
993         r_glsl_permutationhash[mode][hashindex] = p;
994         //if (hashdepth > 10)
995         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
996         return p;
997 }
998
999 static char *R_ShaderStrCat(const char **strings)
1000 {
1001         char *string, *s;
1002         const char **p = strings;
1003         const char *t;
1004         size_t len = 0;
1005         for (p = strings;(t = *p);p++)
1006                 len += strlen(t);
1007         len++;
1008         s = string = (char *)Mem_Alloc(r_main_mempool, len);
1009         len = 0;
1010         for (p = strings;(t = *p);p++)
1011         {
1012                 len = strlen(t);
1013                 memcpy(s, t, len);
1014                 s += len;
1015         }
1016         *s = 0;
1017         return string;
1018 }
1019
1020 static char *R_GetShaderText(const char *filename, qboolean printfromdisknotice, qboolean builtinonly)
1021 {
1022         char *shaderstring;
1023         if (!filename || !filename[0])
1024                 return NULL;
1025         // LordHavoc: note that FS_LoadFile appends a 0 byte to make it a valid string, so does R_ShaderStrCat
1026         if (!strcmp(filename, "glsl/default.glsl"))
1027         {
1028                 if (builtinonly)
1029                         return R_ShaderStrCat(builtinshaderstrings);
1030                 if (!glslshaderstring)
1031                 {
1032                         glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1033                         if (glslshaderstring)
1034                                 Con_DPrintf("Loading shaders from file %s...\n", filename);
1035                         else
1036                                 glslshaderstring = R_ShaderStrCat(builtinshaderstrings);
1037                 }
1038                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1);
1039                 memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1);
1040                 return shaderstring;
1041         }
1042         if (!strcmp(filename, "hlsl/default.hlsl"))
1043         {
1044                 if (builtinonly)
1045                         return R_ShaderStrCat(builtinhlslshaderstrings);
1046                 if (!hlslshaderstring)
1047                 {
1048                         hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1049                         if (hlslshaderstring)
1050                                 Con_DPrintf("Loading shaders from file %s...\n", filename);
1051                         else
1052                                 hlslshaderstring = R_ShaderStrCat(builtinhlslshaderstrings);
1053                 }
1054                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
1055                 memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
1056                 return shaderstring;
1057         }
1058         // we don't have builtin strings for any other files
1059         if (builtinonly)
1060                 return NULL;
1061         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1062         if (shaderstring)
1063         {
1064                 if (printfromdisknotice)
1065                         Con_DPrintf("from disk %s... ", filename);
1066                 return shaderstring;
1067         }
1068         return shaderstring;
1069 }
1070
1071 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1072 {
1073         int i;
1074         int ubibind;
1075         int sampler;
1076         shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
1077         char *sourcestring;
1078         char permutationname[256];
1079         int vertstrings_count = 0;
1080         int geomstrings_count = 0;
1081         int fragstrings_count = 0;
1082         const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1083         const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1084         const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1085
1086         if (p->compiled)
1087                 return;
1088         p->compiled = true;
1089         p->program = 0;
1090
1091         permutationname[0] = 0;
1092         sourcestring  = R_GetShaderText(modeinfo->filename, true, false);
1093
1094         strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
1095
1096         // we need 140 for r_glsl_skeletal (GL_ARB_uniform_buffer_object)
1097         if(vid.support.glshaderversion >= 140)
1098         {
1099                 vertstrings_list[vertstrings_count++] = "#version 140\n";
1100                 geomstrings_list[geomstrings_count++] = "#version 140\n";
1101                 fragstrings_list[fragstrings_count++] = "#version 140\n";
1102                 vertstrings_list[vertstrings_count++] = "#define GLSL140\n";
1103                 geomstrings_list[geomstrings_count++] = "#define GLSL140\n";
1104                 fragstrings_list[fragstrings_count++] = "#define GLSL140\n";
1105         }
1106         // if we can do #version 130, we should (this improves quality of offset/reliefmapping thanks to textureGrad)
1107         else if(vid.support.glshaderversion >= 130)
1108         {
1109                 vertstrings_list[vertstrings_count++] = "#version 130\n";
1110                 geomstrings_list[geomstrings_count++] = "#version 130\n";
1111                 fragstrings_list[fragstrings_count++] = "#version 130\n";
1112                 vertstrings_list[vertstrings_count++] = "#define GLSL130\n";
1113                 geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
1114                 fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
1115         }
1116
1117         // the first pretext is which type of shader to compile as
1118         // (later these will all be bound together as a program object)
1119         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1120         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1121         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1122
1123         // the second pretext is the mode (for example a light source)
1124         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1125         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1126         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1127         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1128
1129         // now add all the permutation pretexts
1130         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1131         {
1132                 if (permutation & (1<<i))
1133                 {
1134                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1135                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1136                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1137                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1138                 }
1139                 else
1140                 {
1141                         // keep line numbers correct
1142                         vertstrings_list[vertstrings_count++] = "\n";
1143                         geomstrings_list[geomstrings_count++] = "\n";
1144                         fragstrings_list[fragstrings_count++] = "\n";
1145                 }
1146         }
1147
1148         // add static parms
1149         R_CompileShader_AddStaticParms(mode, permutation);
1150         memcpy((char *)(vertstrings_list + vertstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1151         vertstrings_count += shaderstaticparms_count;
1152         memcpy((char *)(geomstrings_list + geomstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1153         geomstrings_count += shaderstaticparms_count;
1154         memcpy((char *)(fragstrings_list + fragstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1155         fragstrings_count += shaderstaticparms_count;
1156
1157         // now append the shader text itself
1158         vertstrings_list[vertstrings_count++] = sourcestring;
1159         geomstrings_list[geomstrings_count++] = sourcestring;
1160         fragstrings_list[fragstrings_count++] = sourcestring;
1161
1162         // compile the shader program
1163         if (vertstrings_count + geomstrings_count + fragstrings_count)
1164                 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1165         if (p->program)
1166         {
1167                 CHECKGLERROR
1168                 qglUseProgram(p->program);CHECKGLERROR
1169                 // look up all the uniform variable names we care about, so we don't
1170                 // have to look them up every time we set them
1171
1172 #if 0
1173                 // debugging aid
1174                 {
1175                         GLint activeuniformindex = 0;
1176                         GLint numactiveuniforms = 0;
1177                         char uniformname[128];
1178                         GLsizei uniformnamelength = 0;
1179                         GLint uniformsize = 0;
1180                         GLenum uniformtype = 0;
1181                         memset(uniformname, 0, sizeof(uniformname));
1182                         qglGetProgramiv(p->program, GL_ACTIVE_UNIFORMS, &numactiveuniforms);
1183                         Con_Printf("Shader has %i uniforms\n", numactiveuniforms);
1184                         for (activeuniformindex = 0;activeuniformindex < numactiveuniforms;activeuniformindex++)
1185                         {
1186                                 qglGetActiveUniform(p->program, activeuniformindex, sizeof(uniformname) - 1, &uniformnamelength, &uniformsize, &uniformtype, uniformname);
1187                                 Con_Printf("Uniform %i name \"%s\" size %i type %i\n", (int)activeuniformindex, uniformname, (int)uniformsize, (int)uniformtype);
1188                         }
1189                 }
1190 #endif
1191
1192                 p->loc_Texture_First              = qglGetUniformLocation(p->program, "Texture_First");
1193                 p->loc_Texture_Second             = qglGetUniformLocation(p->program, "Texture_Second");
1194                 p->loc_Texture_GammaRamps         = qglGetUniformLocation(p->program, "Texture_GammaRamps");
1195                 p->loc_Texture_Normal             = qglGetUniformLocation(p->program, "Texture_Normal");
1196                 p->loc_Texture_Color              = qglGetUniformLocation(p->program, "Texture_Color");
1197                 p->loc_Texture_Gloss              = qglGetUniformLocation(p->program, "Texture_Gloss");
1198                 p->loc_Texture_Glow               = qglGetUniformLocation(p->program, "Texture_Glow");
1199                 p->loc_Texture_SecondaryNormal    = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
1200                 p->loc_Texture_SecondaryColor     = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
1201                 p->loc_Texture_SecondaryGloss     = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
1202                 p->loc_Texture_SecondaryGlow      = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
1203                 p->loc_Texture_Pants              = qglGetUniformLocation(p->program, "Texture_Pants");
1204                 p->loc_Texture_Shirt              = qglGetUniformLocation(p->program, "Texture_Shirt");
1205                 p->loc_Texture_FogHeightTexture   = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
1206                 p->loc_Texture_FogMask            = qglGetUniformLocation(p->program, "Texture_FogMask");
1207                 p->loc_Texture_Lightmap           = qglGetUniformLocation(p->program, "Texture_Lightmap");
1208                 p->loc_Texture_Deluxemap          = qglGetUniformLocation(p->program, "Texture_Deluxemap");
1209                 p->loc_Texture_Attenuation        = qglGetUniformLocation(p->program, "Texture_Attenuation");
1210                 p->loc_Texture_Cube               = qglGetUniformLocation(p->program, "Texture_Cube");
1211                 p->loc_Texture_Refraction         = qglGetUniformLocation(p->program, "Texture_Refraction");
1212                 p->loc_Texture_Reflection         = qglGetUniformLocation(p->program, "Texture_Reflection");
1213                 p->loc_Texture_ShadowMap2D        = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
1214                 p->loc_Texture_CubeProjection     = qglGetUniformLocation(p->program, "Texture_CubeProjection");
1215                 p->loc_Texture_ScreenNormalMap    = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
1216                 p->loc_Texture_ScreenDiffuse      = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
1217                 p->loc_Texture_ScreenSpecular     = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
1218                 p->loc_Texture_ReflectMask        = qglGetUniformLocation(p->program, "Texture_ReflectMask");
1219                 p->loc_Texture_ReflectCube        = qglGetUniformLocation(p->program, "Texture_ReflectCube");
1220                 p->loc_Texture_BounceGrid         = qglGetUniformLocation(p->program, "Texture_BounceGrid");
1221                 p->loc_Alpha                      = qglGetUniformLocation(p->program, "Alpha");
1222                 p->loc_BloomBlur_Parameters       = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
1223                 p->loc_ClientTime                 = qglGetUniformLocation(p->program, "ClientTime");
1224                 p->loc_Color_Ambient              = qglGetUniformLocation(p->program, "Color_Ambient");
1225                 p->loc_Color_Diffuse              = qglGetUniformLocation(p->program, "Color_Diffuse");
1226                 p->loc_Color_Specular             = qglGetUniformLocation(p->program, "Color_Specular");
1227                 p->loc_Color_Glow                 = qglGetUniformLocation(p->program, "Color_Glow");
1228                 p->loc_Color_Pants                = qglGetUniformLocation(p->program, "Color_Pants");
1229                 p->loc_Color_Shirt                = qglGetUniformLocation(p->program, "Color_Shirt");
1230                 p->loc_DeferredColor_Ambient      = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
1231                 p->loc_DeferredColor_Diffuse      = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
1232                 p->loc_DeferredColor_Specular     = qglGetUniformLocation(p->program, "DeferredColor_Specular");
1233                 p->loc_DeferredMod_Diffuse        = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
1234                 p->loc_DeferredMod_Specular       = qglGetUniformLocation(p->program, "DeferredMod_Specular");
1235                 p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
1236                 p->loc_EyePosition                = qglGetUniformLocation(p->program, "EyePosition");
1237                 p->loc_FogColor                   = qglGetUniformLocation(p->program, "FogColor");
1238                 p->loc_FogHeightFade              = qglGetUniformLocation(p->program, "FogHeightFade");
1239                 p->loc_FogPlane                   = qglGetUniformLocation(p->program, "FogPlane");
1240                 p->loc_FogPlaneViewDist           = qglGetUniformLocation(p->program, "FogPlaneViewDist");
1241                 p->loc_FogRangeRecip              = qglGetUniformLocation(p->program, "FogRangeRecip");
1242                 p->loc_LightColor                 = qglGetUniformLocation(p->program, "LightColor");
1243                 p->loc_LightDir                   = qglGetUniformLocation(p->program, "LightDir");
1244                 p->loc_LightPosition              = qglGetUniformLocation(p->program, "LightPosition");
1245                 p->loc_OffsetMapping_ScaleSteps   = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
1246                 p->loc_OffsetMapping_LodDistance  = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
1247                 p->loc_OffsetMapping_Bias         = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
1248                 p->loc_PixelSize                  = qglGetUniformLocation(p->program, "PixelSize");
1249                 p->loc_ReflectColor               = qglGetUniformLocation(p->program, "ReflectColor");
1250                 p->loc_ReflectFactor              = qglGetUniformLocation(p->program, "ReflectFactor");
1251                 p->loc_ReflectOffset              = qglGetUniformLocation(p->program, "ReflectOffset");
1252                 p->loc_RefractColor               = qglGetUniformLocation(p->program, "RefractColor");
1253                 p->loc_Saturation                 = qglGetUniformLocation(p->program, "Saturation");
1254                 p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
1255                 p->loc_ScreenScaleRefractReflect  = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
1256                 p->loc_ScreenToDepth              = qglGetUniformLocation(p->program, "ScreenToDepth");
1257                 p->loc_ShadowMap_Parameters       = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
1258                 p->loc_ShadowMap_TextureScale     = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
1259                 p->loc_SpecularPower              = qglGetUniformLocation(p->program, "SpecularPower");
1260                 p->loc_UserVec1                   = qglGetUniformLocation(p->program, "UserVec1");
1261                 p->loc_UserVec2                   = qglGetUniformLocation(p->program, "UserVec2");
1262                 p->loc_UserVec3                   = qglGetUniformLocation(p->program, "UserVec3");
1263                 p->loc_UserVec4                   = qglGetUniformLocation(p->program, "UserVec4");
1264                 p->loc_ViewTintColor              = qglGetUniformLocation(p->program, "ViewTintColor");
1265                 p->loc_ViewToLight                = qglGetUniformLocation(p->program, "ViewToLight");
1266                 p->loc_ModelToLight               = qglGetUniformLocation(p->program, "ModelToLight");
1267                 p->loc_TexMatrix                  = qglGetUniformLocation(p->program, "TexMatrix");
1268                 p->loc_BackgroundTexMatrix        = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
1269                 p->loc_ModelViewMatrix            = qglGetUniformLocation(p->program, "ModelViewMatrix");
1270                 p->loc_ModelViewProjectionMatrix  = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
1271                 p->loc_PixelToScreenTexCoord      = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
1272                 p->loc_ModelToReflectCube         = qglGetUniformLocation(p->program, "ModelToReflectCube");
1273                 p->loc_ShadowMapMatrix            = qglGetUniformLocation(p->program, "ShadowMapMatrix");
1274                 p->loc_BloomColorSubtract         = qglGetUniformLocation(p->program, "BloomColorSubtract");
1275                 p->loc_NormalmapScrollBlend       = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
1276                 p->loc_BounceGridMatrix           = qglGetUniformLocation(p->program, "BounceGridMatrix");
1277                 p->loc_BounceGridIntensity        = qglGetUniformLocation(p->program, "BounceGridIntensity");
1278                 // initialize the samplers to refer to the texture units we use
1279                 p->tex_Texture_First = -1;
1280                 p->tex_Texture_Second = -1;
1281                 p->tex_Texture_GammaRamps = -1;
1282                 p->tex_Texture_Normal = -1;
1283                 p->tex_Texture_Color = -1;
1284                 p->tex_Texture_Gloss = -1;
1285                 p->tex_Texture_Glow = -1;
1286                 p->tex_Texture_SecondaryNormal = -1;
1287                 p->tex_Texture_SecondaryColor = -1;
1288                 p->tex_Texture_SecondaryGloss = -1;
1289                 p->tex_Texture_SecondaryGlow = -1;
1290                 p->tex_Texture_Pants = -1;
1291                 p->tex_Texture_Shirt = -1;
1292                 p->tex_Texture_FogHeightTexture = -1;
1293                 p->tex_Texture_FogMask = -1;
1294                 p->tex_Texture_Lightmap = -1;
1295                 p->tex_Texture_Deluxemap = -1;
1296                 p->tex_Texture_Attenuation = -1;
1297                 p->tex_Texture_Cube = -1;
1298                 p->tex_Texture_Refraction = -1;
1299                 p->tex_Texture_Reflection = -1;
1300                 p->tex_Texture_ShadowMap2D = -1;
1301                 p->tex_Texture_CubeProjection = -1;
1302                 p->tex_Texture_ScreenNormalMap = -1;
1303                 p->tex_Texture_ScreenDiffuse = -1;
1304                 p->tex_Texture_ScreenSpecular = -1;
1305                 p->tex_Texture_ReflectMask = -1;
1306                 p->tex_Texture_ReflectCube = -1;
1307                 p->tex_Texture_BounceGrid = -1;
1308                 // bind the texture samplers in use
1309                 sampler = 0;
1310                 if (p->loc_Texture_First           >= 0) {p->tex_Texture_First            = sampler;qglUniform1i(p->loc_Texture_First           , sampler);sampler++;}
1311                 if (p->loc_Texture_Second          >= 0) {p->tex_Texture_Second           = sampler;qglUniform1i(p->loc_Texture_Second          , sampler);sampler++;}
1312                 if (p->loc_Texture_GammaRamps      >= 0) {p->tex_Texture_GammaRamps       = sampler;qglUniform1i(p->loc_Texture_GammaRamps      , sampler);sampler++;}
1313                 if (p->loc_Texture_Normal          >= 0) {p->tex_Texture_Normal           = sampler;qglUniform1i(p->loc_Texture_Normal          , sampler);sampler++;}
1314                 if (p->loc_Texture_Color           >= 0) {p->tex_Texture_Color            = sampler;qglUniform1i(p->loc_Texture_Color           , sampler);sampler++;}
1315                 if (p->loc_Texture_Gloss           >= 0) {p->tex_Texture_Gloss            = sampler;qglUniform1i(p->loc_Texture_Gloss           , sampler);sampler++;}
1316                 if (p->loc_Texture_Glow            >= 0) {p->tex_Texture_Glow             = sampler;qglUniform1i(p->loc_Texture_Glow            , sampler);sampler++;}
1317                 if (p->loc_Texture_SecondaryNormal >= 0) {p->tex_Texture_SecondaryNormal  = sampler;qglUniform1i(p->loc_Texture_SecondaryNormal , sampler);sampler++;}
1318                 if (p->loc_Texture_SecondaryColor  >= 0) {p->tex_Texture_SecondaryColor   = sampler;qglUniform1i(p->loc_Texture_SecondaryColor  , sampler);sampler++;}
1319                 if (p->loc_Texture_SecondaryGloss  >= 0) {p->tex_Texture_SecondaryGloss   = sampler;qglUniform1i(p->loc_Texture_SecondaryGloss  , sampler);sampler++;}
1320                 if (p->loc_Texture_SecondaryGlow   >= 0) {p->tex_Texture_SecondaryGlow    = sampler;qglUniform1i(p->loc_Texture_SecondaryGlow   , sampler);sampler++;}
1321                 if (p->loc_Texture_Pants           >= 0) {p->tex_Texture_Pants            = sampler;qglUniform1i(p->loc_Texture_Pants           , sampler);sampler++;}
1322                 if (p->loc_Texture_Shirt           >= 0) {p->tex_Texture_Shirt            = sampler;qglUniform1i(p->loc_Texture_Shirt           , sampler);sampler++;}
1323                 if (p->loc_Texture_FogHeightTexture>= 0) {p->tex_Texture_FogHeightTexture = sampler;qglUniform1i(p->loc_Texture_FogHeightTexture, sampler);sampler++;}
1324                 if (p->loc_Texture_FogMask         >= 0) {p->tex_Texture_FogMask          = sampler;qglUniform1i(p->loc_Texture_FogMask         , sampler);sampler++;}
1325                 if (p->loc_Texture_Lightmap        >= 0) {p->tex_Texture_Lightmap         = sampler;qglUniform1i(p->loc_Texture_Lightmap        , sampler);sampler++;}
1326                 if (p->loc_Texture_Deluxemap       >= 0) {p->tex_Texture_Deluxemap        = sampler;qglUniform1i(p->loc_Texture_Deluxemap       , sampler);sampler++;}
1327                 if (p->loc_Texture_Attenuation     >= 0) {p->tex_Texture_Attenuation      = sampler;qglUniform1i(p->loc_Texture_Attenuation     , sampler);sampler++;}
1328                 if (p->loc_Texture_Cube            >= 0) {p->tex_Texture_Cube             = sampler;qglUniform1i(p->loc_Texture_Cube            , sampler);sampler++;}
1329                 if (p->loc_Texture_Refraction      >= 0) {p->tex_Texture_Refraction       = sampler;qglUniform1i(p->loc_Texture_Refraction      , sampler);sampler++;}
1330                 if (p->loc_Texture_Reflection      >= 0) {p->tex_Texture_Reflection       = sampler;qglUniform1i(p->loc_Texture_Reflection      , sampler);sampler++;}
1331                 if (p->loc_Texture_ShadowMap2D     >= 0) {p->tex_Texture_ShadowMap2D      = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D     , sampler);sampler++;}
1332                 if (p->loc_Texture_CubeProjection  >= 0) {p->tex_Texture_CubeProjection   = sampler;qglUniform1i(p->loc_Texture_CubeProjection  , sampler);sampler++;}
1333                 if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap  = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
1334                 if (p->loc_Texture_ScreenDiffuse   >= 0) {p->tex_Texture_ScreenDiffuse    = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse   , sampler);sampler++;}
1335                 if (p->loc_Texture_ScreenSpecular  >= 0) {p->tex_Texture_ScreenSpecular   = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular  , sampler);sampler++;}
1336                 if (p->loc_Texture_ReflectMask     >= 0) {p->tex_Texture_ReflectMask      = sampler;qglUniform1i(p->loc_Texture_ReflectMask     , sampler);sampler++;}
1337                 if (p->loc_Texture_ReflectCube     >= 0) {p->tex_Texture_ReflectCube      = sampler;qglUniform1i(p->loc_Texture_ReflectCube     , sampler);sampler++;}
1338                 if (p->loc_Texture_BounceGrid      >= 0) {p->tex_Texture_BounceGrid       = sampler;qglUniform1i(p->loc_Texture_BounceGrid      , sampler);sampler++;}
1339                 // get the uniform block indices so we can bind them
1340 #ifndef USE_GLES2 /* FIXME: GLES3 only */
1341                 if (vid.support.arb_uniform_buffer_object)
1342                         p->ubiloc_Skeletal_Transform12_UniformBlock = qglGetUniformBlockIndex(p->program, "Skeletal_Transform12_UniformBlock");
1343                 else
1344 #endif
1345                         p->ubiloc_Skeletal_Transform12_UniformBlock = -1;
1346                 // clear the uniform block bindings
1347                 p->ubibind_Skeletal_Transform12_UniformBlock = -1;
1348                 // bind the uniform blocks in use
1349                 ubibind = 0;
1350 #ifndef USE_GLES2 /* FIXME: GLES3 only */
1351                 if (p->ubiloc_Skeletal_Transform12_UniformBlock >= 0) {p->ubibind_Skeletal_Transform12_UniformBlock = ubibind;qglUniformBlockBinding(p->program, p->ubiloc_Skeletal_Transform12_UniformBlock, ubibind);ubibind++;}
1352 #endif
1353                 // we're done compiling and setting up the shader, at least until it is used
1354                 CHECKGLERROR
1355                 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
1356         }
1357         else
1358                 Con_Printf("^1GLSL shader %s failed!  some features may not work properly.\n", permutationname);
1359
1360         // free the strings
1361         if (sourcestring)
1362                 Mem_Free(sourcestring);
1363 }
1364
1365 static void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
1366 {
1367         r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
1368         if (r_glsl_permutation != perm)
1369         {
1370                 r_glsl_permutation = perm;
1371                 if (!r_glsl_permutation->program)
1372                 {
1373                         if (!r_glsl_permutation->compiled)
1374                         {
1375                                 Con_DPrintf("Compiling shader mode %u permutation %u\n", mode, permutation);
1376                                 R_GLSL_CompilePermutation(perm, mode, permutation);
1377                         }
1378                         if (!r_glsl_permutation->program)
1379                         {
1380                                 // remove features until we find a valid permutation
1381                                 int i;
1382                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1383                                 {
1384                                         // reduce i more quickly whenever it would not remove any bits
1385                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1386                                         if (!(permutation & j))
1387                                                 continue;
1388                                         permutation -= j;
1389                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1390                                         if (!r_glsl_permutation->compiled)
1391                                                 R_GLSL_CompilePermutation(perm, mode, permutation);
1392                                         if (r_glsl_permutation->program)
1393                                                 break;
1394                                 }
1395                                 if (i >= SHADERPERMUTATION_COUNT)
1396                                 {
1397                                         //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].filename, shadermodeinfo[mode].pretext);
1398                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1399                                         qglUseProgram(0);CHECKGLERROR
1400                                         return; // no bit left to clear, entire mode is broken
1401                                 }
1402                         }
1403                 }
1404                 CHECKGLERROR
1405                 qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
1406         }
1407         if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
1408         if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
1409         if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
1410         CHECKGLERROR
1411 }
1412
1413 #ifdef SUPPORTD3D
1414
1415 #ifdef SUPPORTD3D
1416 #include <d3d9.h>
1417 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
1418 extern D3DCAPS9 vid_d3d9caps;
1419 #endif
1420
1421 struct r_hlsl_permutation_s;
1422 typedef struct r_hlsl_permutation_s
1423 {
1424         /// hash lookup data
1425         struct r_hlsl_permutation_s *hashnext;
1426         unsigned int mode;
1427         unsigned int permutation;
1428
1429         /// indicates if we have tried compiling this permutation already
1430         qboolean compiled;
1431         /// NULL if compilation failed
1432         IDirect3DVertexShader9 *vertexshader;
1433         IDirect3DPixelShader9 *pixelshader;
1434 }
1435 r_hlsl_permutation_t;
1436
1437 typedef enum D3DVSREGISTER_e
1438 {
1439         D3DVSREGISTER_TexMatrix = 0, // float4x4
1440         D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
1441         D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
1442         D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
1443         D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
1444         D3DVSREGISTER_ModelToLight = 20, // float4x4
1445         D3DVSREGISTER_EyePosition = 24,
1446         D3DVSREGISTER_FogPlane = 25,
1447         D3DVSREGISTER_LightDir = 26,
1448         D3DVSREGISTER_LightPosition = 27,
1449 }
1450 D3DVSREGISTER_t;
1451
1452 typedef enum D3DPSREGISTER_e
1453 {
1454         D3DPSREGISTER_Alpha = 0,
1455         D3DPSREGISTER_BloomBlur_Parameters = 1,
1456         D3DPSREGISTER_ClientTime = 2,
1457         D3DPSREGISTER_Color_Ambient = 3,
1458         D3DPSREGISTER_Color_Diffuse = 4,
1459         D3DPSREGISTER_Color_Specular = 5,
1460         D3DPSREGISTER_Color_Glow = 6,
1461         D3DPSREGISTER_Color_Pants = 7,
1462         D3DPSREGISTER_Color_Shirt = 8,
1463         D3DPSREGISTER_DeferredColor_Ambient = 9,
1464         D3DPSREGISTER_DeferredColor_Diffuse = 10,
1465         D3DPSREGISTER_DeferredColor_Specular = 11,
1466         D3DPSREGISTER_DeferredMod_Diffuse = 12,
1467         D3DPSREGISTER_DeferredMod_Specular = 13,
1468         D3DPSREGISTER_DistortScaleRefractReflect = 14,
1469         D3DPSREGISTER_EyePosition = 15, // unused
1470         D3DPSREGISTER_FogColor = 16,
1471         D3DPSREGISTER_FogHeightFade = 17,
1472         D3DPSREGISTER_FogPlane = 18,
1473         D3DPSREGISTER_FogPlaneViewDist = 19,
1474         D3DPSREGISTER_FogRangeRecip = 20,
1475         D3DPSREGISTER_LightColor = 21,
1476         D3DPSREGISTER_LightDir = 22, // unused
1477         D3DPSREGISTER_LightPosition = 23,
1478         D3DPSREGISTER_OffsetMapping_ScaleSteps = 24,
1479         D3DPSREGISTER_PixelSize = 25,
1480         D3DPSREGISTER_ReflectColor = 26,
1481         D3DPSREGISTER_ReflectFactor = 27,
1482         D3DPSREGISTER_ReflectOffset = 28,
1483         D3DPSREGISTER_RefractColor = 29,
1484         D3DPSREGISTER_Saturation = 30,
1485         D3DPSREGISTER_ScreenCenterRefractReflect = 31,
1486         D3DPSREGISTER_ScreenScaleRefractReflect = 32,
1487         D3DPSREGISTER_ScreenToDepth = 33,
1488         D3DPSREGISTER_ShadowMap_Parameters = 34,
1489         D3DPSREGISTER_ShadowMap_TextureScale = 35,
1490         D3DPSREGISTER_SpecularPower = 36,
1491         D3DPSREGISTER_UserVec1 = 37,
1492         D3DPSREGISTER_UserVec2 = 38,
1493         D3DPSREGISTER_UserVec3 = 39,
1494         D3DPSREGISTER_UserVec4 = 40,
1495         D3DPSREGISTER_ViewTintColor = 41,
1496         D3DPSREGISTER_PixelToScreenTexCoord = 42,
1497         D3DPSREGISTER_BloomColorSubtract = 43,
1498         D3DPSREGISTER_ViewToLight = 44, // float4x4
1499         D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
1500         D3DPSREGISTER_NormalmapScrollBlend = 52,
1501         D3DPSREGISTER_OffsetMapping_LodDistance = 53,
1502         D3DPSREGISTER_OffsetMapping_Bias = 54,
1503         // next at 54
1504 }
1505 D3DPSREGISTER_t;
1506
1507 /// information about each possible shader permutation
1508 r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
1509 /// currently selected permutation
1510 r_hlsl_permutation_t *r_hlsl_permutation;
1511 /// storage for permutations linked in the hash table
1512 memexpandablearray_t r_hlsl_permutationarray;
1513
1514 static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, unsigned int permutation)
1515 {
1516         //unsigned int hashdepth = 0;
1517         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
1518         r_hlsl_permutation_t *p;
1519         for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1520         {
1521                 if (p->mode == mode && p->permutation == permutation)
1522                 {
1523                         //if (hashdepth > 10)
1524                         //      Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1525                         return p;
1526                 }
1527                 //hashdepth++;
1528         }
1529         p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
1530         p->mode = mode;
1531         p->permutation = permutation;
1532         p->hashnext = r_hlsl_permutationhash[mode][hashindex];
1533         r_hlsl_permutationhash[mode][hashindex] = p;
1534         //if (hashdepth > 10)
1535         //      Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1536         return p;
1537 }
1538
1539 #include <d3dx9.h>
1540 //#include <d3dx9shader.h>
1541 //#include <d3dx9mesh.h>
1542
1543 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
1544 {
1545         DWORD *vsbin = NULL;
1546         DWORD *psbin = NULL;
1547         fs_offset_t vsbinsize;
1548         fs_offset_t psbinsize;
1549 //      IDirect3DVertexShader9 *vs = NULL;
1550 //      IDirect3DPixelShader9 *ps = NULL;
1551         ID3DXBuffer *vslog = NULL;
1552         ID3DXBuffer *vsbuffer = NULL;
1553         ID3DXConstantTable *vsconstanttable = NULL;
1554         ID3DXBuffer *pslog = NULL;
1555         ID3DXBuffer *psbuffer = NULL;
1556         ID3DXConstantTable *psconstanttable = NULL;
1557         int vsresult = 0;
1558         int psresult = 0;
1559         char temp[MAX_INPUTLINE];
1560         const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
1561         char vabuf[1024];
1562         qboolean debugshader = gl_paranoid.integer != 0;
1563         if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1564         if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1565         if (!debugshader)
1566         {
1567                 vsbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
1568                 psbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.psbin", cachename), r_main_mempool, true, &psbinsize);
1569         }
1570         if ((!vsbin && vertstring) || (!psbin && fragstring))
1571         {
1572                 const char* dllnames_d3dx9 [] =
1573                 {
1574                         "d3dx9_43.dll",
1575                         "d3dx9_42.dll",
1576                         "d3dx9_41.dll",
1577                         "d3dx9_40.dll",
1578                         "d3dx9_39.dll",
1579                         "d3dx9_38.dll",
1580                         "d3dx9_37.dll",
1581                         "d3dx9_36.dll",
1582                         "d3dx9_35.dll",
1583                         "d3dx9_34.dll",
1584                         "d3dx9_33.dll",
1585                         "d3dx9_32.dll",
1586                         "d3dx9_31.dll",
1587                         "d3dx9_30.dll",
1588                         "d3dx9_29.dll",
1589                         "d3dx9_28.dll",
1590                         "d3dx9_27.dll",
1591                         "d3dx9_26.dll",
1592                         "d3dx9_25.dll",
1593                         "d3dx9_24.dll",
1594                         NULL
1595                 };
1596                 dllhandle_t d3dx9_dll = NULL;
1597                 HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1598                 HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
1599                 HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1600                 dllfunction_t d3dx9_dllfuncs[] =
1601                 {
1602                         {"D3DXCompileShaderFromFileA",  (void **) &qD3DXCompileShaderFromFileA},
1603                         {"D3DXPreprocessShader",                (void **) &qD3DXPreprocessShader},
1604                         {"D3DXCompileShader",                   (void **) &qD3DXCompileShader},
1605                         {NULL, NULL}
1606                 };
1607                 // LordHavoc: the June 2010 SDK lacks these macros to make ID3DXBuffer usable in C, and to make it work in both C and C++ the macros are needed...
1608 #ifndef ID3DXBuffer_GetBufferPointer
1609 #if !defined(__cplusplus) || defined(CINTERFACE)
1610 #define ID3DXBuffer_GetBufferPointer(p)   (p)->lpVtbl->GetBufferPointer(p)
1611 #define ID3DXBuffer_GetBufferSize(p)      (p)->lpVtbl->GetBufferSize(p)
1612 #define ID3DXBuffer_Release(p)            (p)->lpVtbl->Release(p)
1613 #else
1614 #define ID3DXBuffer_GetBufferPointer(p)   (p)->GetBufferPointer()
1615 #define ID3DXBuffer_GetBufferSize(p)      (p)->GetBufferSize()
1616 #define ID3DXBuffer_Release(p)            (p)->Release()
1617 #endif
1618 #endif
1619                 if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
1620                 {
1621                         DWORD shaderflags = 0;
1622                         if (debugshader)
1623                                 shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
1624                         vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1625                         psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1626                         if (vertstring && vertstring[0])
1627                         {
1628                                 if (debugshader)
1629                                 {
1630                                         FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vertstring, strlen(vertstring));
1631                                         vsresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1632                                 }
1633                                 else
1634                                         vsresult = qD3DXCompileShader(vertstring, (unsigned int)strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1635                                 if (vsbuffer)
1636                                 {
1637                                         vsbinsize = ID3DXBuffer_GetBufferSize(vsbuffer);
1638                                         vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
1639                                         memcpy(vsbin, ID3DXBuffer_GetBufferPointer(vsbuffer), vsbinsize);
1640                                         ID3DXBuffer_Release(vsbuffer);
1641                                 }
1642                                 if (vslog)
1643                                 {
1644                                         strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(vslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(vslog)));
1645                                         Con_DPrintf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
1646                                         ID3DXBuffer_Release(vslog);
1647                                 }
1648                         }
1649                         if (fragstring && fragstring[0])
1650                         {
1651                                 if (debugshader)
1652                                 {
1653                                         FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), fragstring, strlen(fragstring));
1654                                         psresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1655                                 }
1656                                 else
1657                                         psresult = qD3DXCompileShader(fragstring, (unsigned int)strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1658                                 if (psbuffer)
1659                                 {
1660                                         psbinsize = ID3DXBuffer_GetBufferSize(psbuffer);
1661                                         psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
1662                                         memcpy(psbin, ID3DXBuffer_GetBufferPointer(psbuffer), psbinsize);
1663                                         ID3DXBuffer_Release(psbuffer);
1664                                 }
1665                                 if (pslog)
1666                                 {
1667                                         strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(pslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(pslog)));
1668                                         Con_DPrintf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
1669                                         ID3DXBuffer_Release(pslog);
1670                                 }
1671                         }
1672                         Sys_UnloadLibrary(&d3dx9_dll);
1673                 }
1674                 else
1675                         Con_DPrintf("Unable to compile shader - D3DXCompileShader function not found\n");
1676         }
1677         if (vsbin && psbin)
1678         {
1679                 vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
1680                 if (FAILED(vsresult))
1681                         Con_DPrintf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
1682                 psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
1683                 if (FAILED(psresult))
1684                         Con_DPrintf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
1685         }
1686         // free the shader data
1687         vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1688         psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1689 }
1690
1691 static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1692 {
1693         int i;
1694         shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
1695         int vertstring_length = 0;
1696         int geomstring_length = 0;
1697         int fragstring_length = 0;
1698         char *t;
1699         char *sourcestring;
1700         char *vertstring, *geomstring, *fragstring;
1701         char permutationname[256];
1702         char cachename[256];
1703         int vertstrings_count = 0;
1704         int geomstrings_count = 0;
1705         int fragstrings_count = 0;
1706         const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1707         const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1708         const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1709
1710         if (p->compiled)
1711                 return;
1712         p->compiled = true;
1713         p->vertexshader = NULL;
1714         p->pixelshader = NULL;
1715
1716         permutationname[0] = 0;
1717         cachename[0] = 0;
1718         sourcestring = R_GetShaderText(modeinfo->filename, true, false);
1719
1720         strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
1721         strlcat(cachename, "hlsl/", sizeof(cachename));
1722
1723         // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
1724         vertstrings_count = 0;
1725         geomstrings_count = 0;
1726         fragstrings_count = 0;
1727         vertstrings_list[vertstrings_count++] = "#define HLSL\n";
1728         geomstrings_list[geomstrings_count++] = "#define HLSL\n";
1729         fragstrings_list[fragstrings_count++] = "#define HLSL\n";
1730
1731         // the first pretext is which type of shader to compile as
1732         // (later these will all be bound together as a program object)
1733         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1734         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1735         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1736
1737         // the second pretext is the mode (for example a light source)
1738         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1739         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1740         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1741         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1742         strlcat(cachename, modeinfo->name, sizeof(cachename));
1743
1744         // now add all the permutation pretexts
1745         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1746         {
1747                 if (permutation & (1<<i))
1748                 {
1749                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1750                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1751                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1752                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1753                         strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
1754                 }
1755                 else
1756                 {
1757                         // keep line numbers correct
1758                         vertstrings_list[vertstrings_count++] = "\n";
1759                         geomstrings_list[geomstrings_count++] = "\n";
1760                         fragstrings_list[fragstrings_count++] = "\n";
1761                 }
1762         }
1763
1764         // add static parms
1765         R_CompileShader_AddStaticParms(mode, permutation);
1766         memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1767         vertstrings_count += shaderstaticparms_count;
1768         memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1769         geomstrings_count += shaderstaticparms_count;
1770         memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1771         fragstrings_count += shaderstaticparms_count;
1772
1773         // replace spaces in the cachename with _ characters
1774         for (i = 0;cachename[i];i++)
1775                 if (cachename[i] == ' ')
1776                         cachename[i] = '_';
1777
1778         // now append the shader text itself
1779         vertstrings_list[vertstrings_count++] = sourcestring;
1780         geomstrings_list[geomstrings_count++] = sourcestring;
1781         fragstrings_list[fragstrings_count++] = sourcestring;
1782
1783         vertstring_length = 0;
1784         for (i = 0;i < vertstrings_count;i++)
1785                 vertstring_length += (int)strlen(vertstrings_list[i]);
1786         vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
1787         for (i = 0;i < vertstrings_count;t += (int)strlen(vertstrings_list[i]), i++)
1788                 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
1789
1790         geomstring_length = 0;
1791         for (i = 0;i < geomstrings_count;i++)
1792                 geomstring_length += (int)strlen(geomstrings_list[i]);
1793         geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
1794         for (i = 0;i < geomstrings_count;t += (int)strlen(geomstrings_list[i]), i++)
1795                 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
1796
1797         fragstring_length = 0;
1798         for (i = 0;i < fragstrings_count;i++)
1799                 fragstring_length += (int)strlen(fragstrings_list[i]);
1800         fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
1801         for (i = 0;i < fragstrings_count;t += (int)strlen(fragstrings_list[i]), i++)
1802                 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
1803
1804         // try to load the cached shader, or generate one
1805         R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
1806
1807         if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
1808                 Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
1809         else
1810                 Con_Printf("^1HLSL shader %s failed!  some features may not work properly.\n", permutationname);
1811
1812         // free the strings
1813         if (vertstring)
1814                 Mem_Free(vertstring);
1815         if (geomstring)
1816                 Mem_Free(geomstring);
1817         if (fragstring)
1818                 Mem_Free(fragstring);
1819         if (sourcestring)
1820                 Mem_Free(sourcestring);
1821 }
1822
1823 static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
1824 static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
1825 static inline void hlslVSSetParameter4f(D3DVSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1826 static inline void hlslVSSetParameter3f(D3DVSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1827 static inline void hlslVSSetParameter2f(D3DVSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1828 static inline void hlslVSSetParameter1f(D3DVSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1829
1830 static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
1831 static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
1832 static inline void hlslPSSetParameter4f(D3DPSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1833 static inline void hlslPSSetParameter3f(D3DPSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1834 static inline void hlslPSSetParameter2f(D3DPSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1835 static inline void hlslPSSetParameter1f(D3DPSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1836
1837 void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
1838 {
1839         r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
1840         if (r_hlsl_permutation != perm)
1841         {
1842                 r_hlsl_permutation = perm;
1843                 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1844                 {
1845                         if (!r_hlsl_permutation->compiled)
1846                                 R_HLSL_CompilePermutation(perm, mode, permutation);
1847                         if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1848                         {
1849                                 // remove features until we find a valid permutation
1850                                 int i;
1851                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1852                                 {
1853                                         // reduce i more quickly whenever it would not remove any bits
1854                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1855                                         if (!(permutation & j))
1856                                                 continue;
1857                                         permutation -= j;
1858                                         r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1859                                         if (!r_hlsl_permutation->compiled)
1860                                                 R_HLSL_CompilePermutation(perm, mode, permutation);
1861                                         if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
1862                                                 break;
1863                                 }
1864                                 if (i >= SHADERPERMUTATION_COUNT)
1865                                 {
1866                                         //Con_Printf("Could not find a working HLSL shader for permutation %s %s\n", shadermodeinfo[mode].filename, shadermodeinfo[mode].pretext);
1867                                         r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1868                                         return; // no bit left to clear, entire mode is broken
1869                                 }
1870                         }
1871                 }
1872                 IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
1873                 IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
1874         }
1875         hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
1876         hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
1877         hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
1878 }
1879 #endif
1880
1881 static void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
1882 {
1883         DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer);
1884         DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
1885         DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
1886         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
1887 }
1888
1889 void R_GLSL_Restart_f(void)
1890 {
1891         unsigned int i, limit;
1892         if (glslshaderstring)
1893                 Mem_Free(glslshaderstring);
1894         glslshaderstring = NULL;
1895         if (hlslshaderstring)
1896                 Mem_Free(hlslshaderstring);
1897         hlslshaderstring = NULL;
1898         switch(vid.renderpath)
1899         {
1900         case RENDERPATH_D3D9:
1901 #ifdef SUPPORTD3D
1902                 {
1903                         r_hlsl_permutation_t *p;
1904                         r_hlsl_permutation = NULL;
1905                         limit = (unsigned int)Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
1906                         for (i = 0;i < limit;i++)
1907                         {
1908                                 if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
1909                                 {
1910                                         if (p->vertexshader)
1911                                                 IDirect3DVertexShader9_Release(p->vertexshader);
1912                                         if (p->pixelshader)
1913                                                 IDirect3DPixelShader9_Release(p->pixelshader);
1914                                         Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
1915                                 }
1916                         }
1917                         memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
1918                 }
1919 #endif
1920                 break;
1921         case RENDERPATH_D3D10:
1922                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1923                 break;
1924         case RENDERPATH_D3D11:
1925                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1926                 break;
1927         case RENDERPATH_GL20:
1928         case RENDERPATH_GLES2:
1929                 {
1930                         r_glsl_permutation_t *p;
1931                         r_glsl_permutation = NULL;
1932                         limit = (unsigned int)Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
1933                         for (i = 0;i < limit;i++)
1934                         {
1935                                 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
1936                                 {
1937                                         GL_Backend_FreeProgram(p->program);
1938                                         Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
1939                                 }
1940                         }
1941                         memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
1942                 }
1943                 break;
1944         case RENDERPATH_GL11:
1945         case RENDERPATH_GL13:
1946         case RENDERPATH_GLES1:
1947                 break;
1948         case RENDERPATH_SOFT:
1949                 break;
1950         }
1951 }
1952
1953 static void R_GLSL_DumpShader_f(void)
1954 {
1955         int i, language, mode, dupe;
1956         char *text;
1957         shadermodeinfo_t *modeinfo;
1958         qfile_t *file;
1959
1960         for (language = 0;language < 2;language++)
1961         {
1962                 modeinfo = (language == 0 ? glslshadermodeinfo : hlslshadermodeinfo);
1963                 for (mode = 0;mode < SHADERMODE_COUNT;mode++)
1964                 {
1965                         // don't dump the same file multiple times (most or all shaders come from the same file)
1966                         for (dupe = mode - 1;dupe >= 0;dupe--)
1967                                 if (!strcmp(modeinfo[mode].filename, modeinfo[dupe].filename))
1968                                         break;
1969                         if (dupe >= 0)
1970                                 continue;
1971                         text = R_GetShaderText(modeinfo[mode].filename, false, true);
1972                         if (!text)
1973                                 continue;
1974                         file = FS_OpenRealFile(modeinfo[mode].filename, "w", false);
1975                         if (file)
1976                         {
1977                                 FS_Print(file, "/* The engine may define the following macros:\n");
1978                                 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1979                                 for (i = 0;i < SHADERMODE_COUNT;i++)
1980                                         FS_Print(file, modeinfo[i].pretext);
1981                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1982                                         FS_Print(file, shaderpermutationinfo[i].pretext);
1983                                 FS_Print(file, "*/\n");
1984                                 FS_Print(file, text);
1985                                 FS_Close(file);
1986                                 Con_Printf("%s written\n", modeinfo[mode].filename);
1987                         }
1988                         else
1989                                 Con_Printf("failed to write to %s\n", modeinfo[mode].filename);
1990                         Mem_Free(text);
1991                 }
1992         }
1993 }
1994
1995 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha)
1996 {
1997         unsigned int permutation = 0;
1998         if (r_trippy.integer && !notrippy)
1999                 permutation |= SHADERPERMUTATION_TRIPPY;
2000         permutation |= SHADERPERMUTATION_VIEWTINT;
2001         if (first)
2002                 permutation |= SHADERPERMUTATION_DIFFUSE;
2003         if (second)
2004                 permutation |= SHADERPERMUTATION_SPECULAR;
2005         if (texturemode == GL_MODULATE)
2006                 permutation |= SHADERPERMUTATION_COLORMAPPING;
2007         else if (texturemode == GL_ADD)
2008                 permutation |= SHADERPERMUTATION_GLOW;
2009         else if (texturemode == GL_DECAL)
2010                 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2011         if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
2012                 permutation |= SHADERPERMUTATION_GAMMARAMPS;
2013         if (suppresstexalpha)
2014                 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2015         if (!second)
2016                 texturemode = GL_MODULATE;
2017         if (vid.allowalphatocoverage)
2018                 GL_AlphaToCoverage(false);
2019         switch (vid.renderpath)
2020         {
2021         case RENDERPATH_D3D9:
2022 #ifdef SUPPORTD3D
2023                 R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, permutation);
2024                 R_Mesh_TexBind(GL20TU_FIRST , first );
2025                 R_Mesh_TexBind(GL20TU_SECOND, second);
2026                 if (permutation & SHADERPERMUTATION_GAMMARAMPS)
2027                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
2028 #endif
2029                 break;
2030         case RENDERPATH_D3D10:
2031                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2032                 break;
2033         case RENDERPATH_D3D11:
2034                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2035                 break;
2036         case RENDERPATH_GL20:
2037         case RENDERPATH_GLES2:
2038                 R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, permutation);
2039                 if (r_glsl_permutation->tex_Texture_First >= 0)
2040                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
2041                 if (r_glsl_permutation->tex_Texture_Second >= 0)
2042                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
2043                 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0)
2044                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
2045                 break;
2046         case RENDERPATH_GL13:
2047         case RENDERPATH_GLES1:
2048                 R_Mesh_TexBind(0, first );
2049                 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
2050                 R_Mesh_TexMatrix(0, NULL);
2051                 R_Mesh_TexBind(1, second);
2052                 if (second)
2053                 {
2054                         R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
2055                         R_Mesh_TexMatrix(1, NULL);
2056                 }
2057                 break;
2058         case RENDERPATH_GL11:
2059                 R_Mesh_TexBind(0, first );
2060                 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
2061                 R_Mesh_TexMatrix(0, NULL);
2062                 break;
2063         case RENDERPATH_SOFT:
2064                 R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, permutation);
2065                 R_Mesh_TexBind(GL20TU_FIRST , first );
2066                 R_Mesh_TexBind(GL20TU_SECOND, second);
2067                 break;
2068         }
2069 }
2070
2071 void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy)
2072 {
2073         R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false);
2074 }
2075
2076 void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean skeletal)
2077 {
2078         unsigned int permutation = 0;
2079         if (r_trippy.integer && !notrippy)
2080                 permutation |= SHADERPERMUTATION_TRIPPY;
2081         if (depthrgb)
2082                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2083         if (skeletal)
2084                 permutation |= SHADERPERMUTATION_SKELETAL;
2085
2086         if (vid.allowalphatocoverage)
2087                 GL_AlphaToCoverage(false);
2088         switch (vid.renderpath)
2089         {
2090         case RENDERPATH_D3D9:
2091 #ifdef SUPPORTD3D
2092                 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2093 #endif
2094                 break;
2095         case RENDERPATH_D3D10:
2096                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2097                 break;
2098         case RENDERPATH_D3D11:
2099                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2100                 break;
2101         case RENDERPATH_GL20:
2102         case RENDERPATH_GLES2:
2103                 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2104 #ifndef USE_GLES2 /* FIXME: GLES3 only */
2105                 if (r_glsl_permutation->ubiloc_Skeletal_Transform12_UniformBlock >= 0 && rsurface.batchskeletaltransform3x4buffer) qglBindBufferRange(GL_UNIFORM_BUFFER, r_glsl_permutation->ubibind_Skeletal_Transform12_UniformBlock, rsurface.batchskeletaltransform3x4buffer->bufferobject, rsurface.batchskeletaltransform3x4offset, rsurface.batchskeletaltransform3x4size);
2106 #endif
2107                 break;
2108         case RENDERPATH_GL13:
2109         case RENDERPATH_GLES1:
2110                 R_Mesh_TexBind(0, 0);
2111                 R_Mesh_TexBind(1, 0);
2112                 break;
2113         case RENDERPATH_GL11:
2114                 R_Mesh_TexBind(0, 0);
2115                 break;
2116         case RENDERPATH_SOFT:
2117                 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2118                 break;
2119         }
2120 }
2121
2122 extern qboolean r_shadow_usingdeferredprepass;
2123 extern rtexture_t *r_shadow_attenuationgradienttexture;
2124 extern rtexture_t *r_shadow_attenuation2dtexture;
2125 extern rtexture_t *r_shadow_attenuation3dtexture;
2126 extern qboolean r_shadow_usingshadowmap2d;
2127 extern qboolean r_shadow_usingshadowmaportho;
2128 extern float r_shadow_shadowmap_texturescale[2];
2129 extern float r_shadow_shadowmap_parameters[4];
2130 extern qboolean r_shadow_shadowmapvsdct;
2131 extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
2132 extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
2133 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
2134 extern matrix4x4_t r_shadow_shadowmapmatrix;
2135 extern int r_shadow_shadowmaplod; // changes for each light based on distance
2136 extern int r_shadow_prepass_width;
2137 extern int r_shadow_prepass_height;
2138 extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
2139 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
2140 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
2141 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
2142
2143 #define BLENDFUNC_ALLOWS_COLORMOD      1
2144 #define BLENDFUNC_ALLOWS_FOG           2
2145 #define BLENDFUNC_ALLOWS_FOG_HACK0     4
2146 #define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
2147 #define BLENDFUNC_ALLOWS_ANYFOG        (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2148 static int R_BlendFuncFlags(int src, int dst)
2149 {
2150         int r = 0;
2151
2152         // a blendfunc allows colormod if:
2153         // a) it can never keep the destination pixel invariant, or
2154         // b) it can keep the destination pixel invariant, and still can do so if colormodded
2155         // this is to prevent unintended side effects from colormod
2156
2157         // a blendfunc allows fog if:
2158         // blend(fog(src), fog(dst)) == fog(blend(src, dst))
2159         // this is to prevent unintended side effects from fog
2160
2161         // these checks are the output of fogeval.pl
2162
2163         r |= BLENDFUNC_ALLOWS_COLORMOD;
2164         if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2165         if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2166         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2167         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2168         if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2169         if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2170         if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2171         if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2172         if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
2173         if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
2174         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2175         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2176         if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2177         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2178         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2179         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2180         if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2181         if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2182         if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2183         if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
2184         if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2185
2186         return r;
2187 }
2188
2189 void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy)
2190 {
2191         // select a permutation of the lighting shader appropriate to this
2192         // combination of texture, entity, light source, and fogging, only use the
2193         // minimum features necessary to avoid wasting rendering time in the
2194         // fragment shader on features that are not being used
2195         unsigned int permutation = 0;
2196         unsigned int mode = 0;
2197         int blendfuncflags;
2198         static float dummy_colormod[3] = {1, 1, 1};
2199         float *colormod = rsurface.colormod;
2200         float m16f[16];
2201         matrix4x4_t tempmatrix;
2202         r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
2203         if (r_trippy.integer && !notrippy)
2204                 permutation |= SHADERPERMUTATION_TRIPPY;
2205         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2206                 permutation |= SHADERPERMUTATION_ALPHAKILL;
2207         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_OCCLUDE)
2208                 permutation |= SHADERPERMUTATION_OCCLUDE;
2209         if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
2210                 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
2211         if (rsurfacepass == RSURFPASS_BACKGROUND)
2212         {
2213                 // distorted background
2214                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2215                 {
2216                         mode = SHADERMODE_WATER;
2217                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2218                                 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2219                         if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
2220                         {
2221                                 // this is the right thing to do for wateralpha
2222                                 GL_BlendFunc(GL_ONE, GL_ZERO);
2223                                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2224                         }
2225                         else
2226                         {
2227                                 // this is the right thing to do for entity alpha
2228                                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2229                                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2230                         }
2231                 }
2232                 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
2233                 {
2234                         mode = SHADERMODE_REFRACTION;
2235                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2236                                 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2237                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2238                         blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2239                 }
2240                 else
2241                 {
2242                         mode = SHADERMODE_GENERIC;
2243                         permutation |= SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_ALPHAKILL;
2244                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2245                         blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2246                 }
2247                 if (vid.allowalphatocoverage)
2248                         GL_AlphaToCoverage(false);
2249         }
2250         else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2251         {
2252                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2253                 {
2254                         switch(rsurface.texture->offsetmapping)
2255                         {
2256                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2257                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2258                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2259                         case OFFSETMAPPING_OFF: break;
2260                         }
2261                 }
2262                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2263                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2264                 // normalmap (deferred prepass), may use alpha test on diffuse
2265                 mode = SHADERMODE_DEFERREDGEOMETRY;
2266                 GL_BlendFunc(GL_ONE, GL_ZERO);
2267                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2268                 if (vid.allowalphatocoverage)
2269                         GL_AlphaToCoverage(false);
2270         }
2271         else if (rsurfacepass == RSURFPASS_RTLIGHT)
2272         {
2273                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2274                 {
2275                         switch(rsurface.texture->offsetmapping)
2276                         {
2277                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2278                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2279                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2280                         case OFFSETMAPPING_OFF: break;
2281                         }
2282                 }
2283                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2284                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2285                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2286                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2287                 // light source
2288                 mode = SHADERMODE_LIGHTSOURCE;
2289                 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2290                         permutation |= SHADERPERMUTATION_CUBEFILTER;
2291                 if (diffusescale > 0)
2292                         permutation |= SHADERPERMUTATION_DIFFUSE;
2293                 if (specularscale > 0)
2294                         permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2295                 if (r_refdef.fogenabled)
2296                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2297                 if (rsurface.texture->colormapping)
2298                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2299                 if (r_shadow_usingshadowmap2d)
2300                 {
2301                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2302                         if(r_shadow_shadowmapvsdct)
2303                                 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2304
2305                         if (r_shadow_shadowmap2ddepthbuffer)
2306                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2307                 }
2308                 if (rsurface.texture->reflectmasktexture)
2309                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2310                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2311                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
2312                 if (vid.allowalphatocoverage)
2313                         GL_AlphaToCoverage(false);
2314         }
2315         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2316         {
2317                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2318                 {
2319                         switch(rsurface.texture->offsetmapping)
2320                         {
2321                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2322                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2323                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2324                         case OFFSETMAPPING_OFF: break;
2325                         }
2326                 }
2327                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2328                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2329                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2330                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2331                 // unshaded geometry (fullbright or ambient model lighting)
2332                 mode = SHADERMODE_FLATCOLOR;
2333                 ambientscale = diffusescale = specularscale = 0;
2334                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2335                         permutation |= SHADERPERMUTATION_GLOW;
2336                 if (r_refdef.fogenabled)
2337                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2338                 if (rsurface.texture->colormapping)
2339                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2340                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2341                 {
2342                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2343                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2344
2345                         if (r_shadow_shadowmap2ddepthbuffer)
2346                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2347                 }
2348                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2349                         permutation |= SHADERPERMUTATION_REFLECTION;
2350                 if (rsurface.texture->reflectmasktexture)
2351                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2352                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2353                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2354                 // when using alphatocoverage, we don't need alphakill
2355                 if (vid.allowalphatocoverage)
2356                 {
2357                         if (r_transparent_alphatocoverage.integer)
2358                         {
2359                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2360                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2361                         }
2362                         else
2363                                 GL_AlphaToCoverage(false);
2364                 }
2365         }
2366         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2367         {
2368                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2369                 {
2370                         switch(rsurface.texture->offsetmapping)
2371                         {
2372                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2373                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2374                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2375                         case OFFSETMAPPING_OFF: break;
2376                         }
2377                 }
2378                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2379                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2380                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2381                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2382                 // directional model lighting
2383                 mode = SHADERMODE_LIGHTDIRECTION;
2384                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2385                         permutation |= SHADERPERMUTATION_GLOW;
2386                 permutation |= SHADERPERMUTATION_DIFFUSE;
2387                 if (specularscale > 0)
2388                         permutation |= SHADERPERMUTATION_SPECULAR;
2389                 if (r_refdef.fogenabled)
2390                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2391                 if (rsurface.texture->colormapping)
2392                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2393                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2394                 {
2395                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2396                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2397
2398                         if (r_shadow_shadowmap2ddepthbuffer)
2399                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2400                 }
2401                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2402                         permutation |= SHADERPERMUTATION_REFLECTION;
2403                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2404                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2405                 if (rsurface.texture->reflectmasktexture)
2406                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2407                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2408                 {
2409                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2410                         if (r_shadow_bouncegriddirectional)
2411                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2412                 }
2413                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2414                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2415                 // when using alphatocoverage, we don't need alphakill
2416                 if (vid.allowalphatocoverage)
2417                 {
2418                         if (r_transparent_alphatocoverage.integer)
2419                         {
2420                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2421                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2422                         }
2423                         else
2424                                 GL_AlphaToCoverage(false);
2425                 }
2426         }
2427         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2428         {
2429                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2430                 {
2431                         switch(rsurface.texture->offsetmapping)
2432                         {
2433                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2434                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2435                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2436                         case OFFSETMAPPING_OFF: break;
2437                         }
2438                 }
2439                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2440                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2441                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2442                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2443                 // ambient model lighting
2444                 mode = SHADERMODE_LIGHTDIRECTION;
2445                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2446                         permutation |= SHADERPERMUTATION_GLOW;
2447                 if (r_refdef.fogenabled)
2448                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2449                 if (rsurface.texture->colormapping)
2450                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2451                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2452                 {
2453                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2454                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2455
2456                         if (r_shadow_shadowmap2ddepthbuffer)
2457                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2458                 }
2459                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2460                         permutation |= SHADERPERMUTATION_REFLECTION;
2461                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2462                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2463                 if (rsurface.texture->reflectmasktexture)
2464                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2465                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2466                 {
2467                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2468                         if (r_shadow_bouncegriddirectional)
2469                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2470                 }
2471                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2472                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2473                 // when using alphatocoverage, we don't need alphakill
2474                 if (vid.allowalphatocoverage)
2475                 {
2476                         if (r_transparent_alphatocoverage.integer)
2477                         {
2478                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2479                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2480                         }
2481                         else
2482                                 GL_AlphaToCoverage(false);
2483                 }
2484         }
2485         else
2486         {
2487                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2488                 {
2489                         switch(rsurface.texture->offsetmapping)
2490                         {
2491                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2492                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2493                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2494                         case OFFSETMAPPING_OFF: break;
2495                         }
2496                 }
2497                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2498                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2499                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2500                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2501                 // lightmapped wall
2502                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2503                         permutation |= SHADERPERMUTATION_GLOW;
2504                 if (r_refdef.fogenabled)
2505                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2506                 if (rsurface.texture->colormapping)
2507                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2508                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2509                 {
2510                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2511                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2512
2513                         if (r_shadow_shadowmap2ddepthbuffer)
2514                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2515                 }
2516                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2517                         permutation |= SHADERPERMUTATION_REFLECTION;
2518                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2519                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2520                 if (rsurface.texture->reflectmasktexture)
2521                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2522                 if (FAKELIGHT_ENABLED)
2523                 {
2524                         // fake lightmapping (q1bsp, q3bsp, fullbright map)
2525                         mode = SHADERMODE_FAKELIGHT;
2526                         permutation |= SHADERPERMUTATION_DIFFUSE;
2527                         if (specularscale > 0)
2528                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2529                 }
2530                 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2531                 {
2532                         // deluxemapping (light direction texture)
2533                         if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2534                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2535                         else
2536                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2537                         permutation |= SHADERPERMUTATION_DIFFUSE;
2538                         if (specularscale > 0)
2539                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2540                 }
2541                 else if (r_glsl_deluxemapping.integer >= 2)
2542                 {
2543                         // fake deluxemapping (uniform light direction in tangentspace)
2544                         if (rsurface.uselightmaptexture)
2545                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP;
2546                         else
2547                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
2548                         permutation |= SHADERPERMUTATION_DIFFUSE;
2549                         if (specularscale > 0)
2550                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2551                 }
2552                 else if (rsurface.uselightmaptexture)
2553                 {
2554                         // ordinary lightmapping (q1bsp, q3bsp)
2555                         mode = SHADERMODE_LIGHTMAP;
2556                 }
2557                 else
2558                 {
2559                         // ordinary vertex coloring (q3bsp)
2560                         mode = SHADERMODE_VERTEXCOLOR;
2561                 }
2562                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2563                 {
2564                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2565                         if (r_shadow_bouncegriddirectional)
2566                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2567                 }
2568                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2569                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2570                 // when using alphatocoverage, we don't need alphakill
2571                 if (vid.allowalphatocoverage)
2572                 {
2573                         if (r_transparent_alphatocoverage.integer)
2574                         {
2575                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2576                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2577                         }
2578                         else
2579                                 GL_AlphaToCoverage(false);
2580                 }
2581         }
2582         if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
2583                 colormod = dummy_colormod;
2584         if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
2585                 permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
2586         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2587                 permutation |= SHADERPERMUTATION_FOGALPHAHACK;
2588         switch(vid.renderpath)
2589         {
2590         case RENDERPATH_D3D9:
2591 #ifdef SUPPORTD3D
2592                 RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2593                 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmesh_vertexbuffer, rsurface.batchvertexmesh_bufferoffset);
2594                 R_SetupShader_SetPermutationHLSL(mode, permutation);
2595                 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
2596                 if (mode == SHADERMODE_LIGHTSOURCE)
2597                 {
2598                         Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
2599                         hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2600                 }
2601                 else
2602                 {
2603                         if (mode == SHADERMODE_LIGHTDIRECTION)
2604                         {
2605                                 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2606                         }
2607                 }
2608                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
2609                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
2610                 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
2611                 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2612                 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2613
2614                 if (mode == SHADERMODE_LIGHTSOURCE)
2615                 {
2616                         hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2617                         hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2618                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2619                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2620                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2621
2622                         // additive passes are only darkened by fog, not tinted
2623                         hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2624                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2625                 }
2626                 else
2627                 {
2628                         if (mode == SHADERMODE_FLATCOLOR)
2629                         {
2630                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2631                         }
2632                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2633                         {
2634                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);
2635                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2636                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2637                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2638                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2639                                 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
2640                                 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2641                         }
2642                         else
2643                         {
2644                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2645                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2646                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2647                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2648                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2649                         }
2650                         // additive passes are only darkened by fog, not tinted
2651                         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2652                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2653                         else
2654                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2655                         hlslPSSetParameter4f(D3DPSREGISTER_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);
2656                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2657                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2658                         hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2659                         hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2660                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2661                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
2662                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
2663                         if (mode == SHADERMODE_WATER)
2664                                 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2665                 }
2666                 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2667                 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2668                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2669                 hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
2670                 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2671                 if (rsurface.texture->pantstexture)
2672                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2673                 else
2674                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
2675                 if (rsurface.texture->shirttexture)
2676                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2677                 else
2678                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
2679                 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2680                 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
2681                 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
2682                 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
2683                 hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
2684                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2685                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2686                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2687                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2688                         );
2689                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2690                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
2691                 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2692                 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
2693
2694                 R_Mesh_TexBind(GL20TU_NORMAL            , rsurface.texture->nmaptexture                       );
2695                 R_Mesh_TexBind(GL20TU_COLOR             , rsurface.texture->basetexture                       );
2696                 R_Mesh_TexBind(GL20TU_GLOSS             , rsurface.texture->glosstexture                      );
2697                 R_Mesh_TexBind(GL20TU_GLOW              , rsurface.texture->glowtexture                       );
2698                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL  , rsurface.texture->backgroundnmaptexture             );
2699                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR   , rsurface.texture->backgroundbasetexture             );
2700                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS   , rsurface.texture->backgroundglosstexture            );
2701                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW    , rsurface.texture->backgroundglowtexture             );
2702                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS             , rsurface.texture->pantstexture                      );
2703                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT             , rsurface.texture->shirttexture                      );
2704                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK       , rsurface.texture->reflectmasktexture                );
2705                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE       , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2706                 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE  , r_texture_fogheighttexture                          );
2707                 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK           , r_texture_fogattenuation                            );
2708                 R_Mesh_TexBind(GL20TU_LIGHTMAP          , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2709                 R_Mesh_TexBind(GL20TU_DELUXEMAP         , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2710                 if (rsurface.rtlight                                  ) R_Mesh_TexBind(GL20TU_ATTENUATION       , r_shadow_attenuationgradienttexture                 );
2711                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2712                 {
2713                         R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2714                         if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2715                         R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2716                 }
2717                 else
2718                 {
2719                         if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2720                 }
2721 //              if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
2722                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
2723                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
2724                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2725                 {
2726                         R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2727                         if (rsurface.rtlight)
2728                         {
2729                                 if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
2730                                 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT    ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
2731                         }
2732                 }
2733 #endif
2734                 break;
2735         case RENDERPATH_D3D10:
2736                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2737                 break;
2738         case RENDERPATH_D3D11:
2739                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2740                 break;
2741         case RENDERPATH_GL20:
2742         case RENDERPATH_GLES2:
2743                 if (!vid.useinterleavedarrays)
2744                 {
2745                         RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2746                         R_Mesh_VertexPointer(     3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
2747                         R_Mesh_ColorPointer(      4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
2748                         R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
2749                         R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
2750                         R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
2751                         R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
2752                         R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
2753                         R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
2754                         R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, rsurface.batchskeletalindex4ub_vertexbuffer, rsurface.batchskeletalindex4ub_bufferoffset);
2755                         R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, rsurface.batchskeletalweight4ub_vertexbuffer, rsurface.batchskeletalweight4ub_bufferoffset);
2756                 }
2757                 else
2758                 {
2759                         RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0) | (rsurface.entityskeletaltransform3x4 ? BATCHNEED_VERTEXMESH_SKELETAL : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2760                         R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmesh_vertexbuffer, rsurface.batchvertexmesh_bufferoffset);
2761                 }
2762                 // this has to be after RSurf_PrepareVerticesForBatch
2763                 if (rsurface.batchskeletaltransform3x4buffer)
2764                         permutation |= SHADERPERMUTATION_SKELETAL;
2765                 R_SetupShader_SetPermutationGLSL(mode, permutation);
2766 #ifndef USE_GLES2 /* FIXME: GLES3 only */
2767                 if (r_glsl_permutation->ubiloc_Skeletal_Transform12_UniformBlock >= 0 && rsurface.batchskeletaltransform3x4buffer) qglBindBufferRange(GL_UNIFORM_BUFFER, r_glsl_permutation->ubibind_Skeletal_Transform12_UniformBlock, rsurface.batchskeletaltransform3x4buffer->bufferobject, rsurface.batchskeletaltransform3x4offset, rsurface.batchskeletaltransform3x4size);
2768 #endif
2769                 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
2770                 if (mode == SHADERMODE_LIGHTSOURCE)
2771                 {
2772                         if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2773                         if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2774                         if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2775                         if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2776                         if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2777                         if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2778         
2779                         // additive passes are only darkened by fog, not tinted
2780                         if (r_glsl_permutation->loc_FogColor >= 0)
2781                                 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2782                         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2783                 }
2784                 else
2785                 {
2786                         if (mode == SHADERMODE_FLATCOLOR)
2787                         {
2788                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2789                         }
2790                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2791                         {
2792                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
2793                                 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2794                                 if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2795                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2796                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2797                                 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
2798                                 if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2799                         }
2800                         else
2801                         {
2802                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2803                                 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2804                                 if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2805                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2806                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2807                         }
2808                         // additive passes are only darkened by fog, not tinted
2809                         if (r_glsl_permutation->loc_FogColor >= 0)
2810                         {
2811                                 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2812                                         qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2813                                 else
2814                                         qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2815                         }
2816                         if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(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);
2817                         if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2818                         if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2819                         if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2820                         if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2821                         if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2822                         if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2823                         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2824                         if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2825                 }
2826                 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
2827                 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
2828                 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
2829                 if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2830                 if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(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]);
2831
2832                 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2833                 if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
2834                 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2835                 if (r_glsl_permutation->loc_Color_Pants >= 0)
2836                 {
2837                         if (rsurface.texture->pantstexture)
2838                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2839                         else
2840                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
2841                 }
2842                 if (r_glsl_permutation->loc_Color_Shirt >= 0)
2843                 {
2844                         if (rsurface.texture->shirttexture)
2845                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2846                         else
2847                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
2848                 }
2849                 if (r_glsl_permutation->loc_FogPlane >= 0) qglUniform4f(r_glsl_permutation->loc_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2850                 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
2851                 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
2852                 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
2853                 if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps,
2854                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2855                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2856                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2857                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2858                         );
2859                 if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2860                 if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
2861                 if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2862                 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
2863                 if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
2864                 if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale);
2865
2866                 if (r_glsl_permutation->tex_Texture_First           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First            , r_texture_white                                     );
2867                 if (r_glsl_permutation->tex_Texture_Second          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second           , r_texture_white                                     );
2868                 if (r_glsl_permutation->tex_Texture_GammaRamps      >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps       , r_texture_gammaramps                                );
2869                 if (r_glsl_permutation->tex_Texture_Normal          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal           , rsurface.texture->nmaptexture                       );
2870                 if (r_glsl_permutation->tex_Texture_Color           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color            , rsurface.texture->basetexture                       );
2871                 if (r_glsl_permutation->tex_Texture_Gloss           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss            , rsurface.texture->glosstexture                      );
2872                 if (r_glsl_permutation->tex_Texture_Glow            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow             , rsurface.texture->glowtexture                       );
2873                 if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal  , rsurface.texture->backgroundnmaptexture             );
2874                 if (r_glsl_permutation->tex_Texture_SecondaryColor  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor   , rsurface.texture->backgroundbasetexture             );
2875                 if (r_glsl_permutation->tex_Texture_SecondaryGloss  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss   , rsurface.texture->backgroundglosstexture            );
2876                 if (r_glsl_permutation->tex_Texture_SecondaryGlow   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow    , rsurface.texture->backgroundglowtexture             );
2877                 if (r_glsl_permutation->tex_Texture_Pants           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants            , rsurface.texture->pantstexture                      );
2878                 if (r_glsl_permutation->tex_Texture_Shirt           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt            , rsurface.texture->shirttexture                      );
2879                 if (r_glsl_permutation->tex_Texture_ReflectMask     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask      , rsurface.texture->reflectmasktexture                );
2880                 if (r_glsl_permutation->tex_Texture_ReflectCube     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube      , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2881                 if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture                          );
2882                 if (r_glsl_permutation->tex_Texture_FogMask         >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask          , r_texture_fogattenuation                            );
2883                 if (r_glsl_permutation->tex_Texture_Lightmap        >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap         , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2884                 if (r_glsl_permutation->tex_Texture_Deluxemap       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap        , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2885                 if (r_glsl_permutation->tex_Texture_Attenuation     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation      , r_shadow_attenuationgradienttexture                 );
2886                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2887                 {
2888                         if (r_glsl_permutation->tex_Texture_Refraction  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Refraction        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2889                         if (r_glsl_permutation->tex_Texture_First       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2890                         if (r_glsl_permutation->tex_Texture_Reflection  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2891                 }
2892                 else
2893                 {
2894                         if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2895                 }
2896                 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap   , r_shadow_prepassgeometrynormalmaptexture            );
2897                 if (r_glsl_permutation->tex_Texture_ScreenDiffuse   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse     , r_shadow_prepasslightingdiffusetexture              );
2898                 if (r_glsl_permutation->tex_Texture_ScreenSpecular  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular    , r_shadow_prepasslightingspeculartexture             );
2899                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2900                 {
2901                         if (r_glsl_permutation->tex_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2ddepthtexture                           );
2902                         if (rsurface.rtlight)
2903                         {
2904                                 if (r_glsl_permutation->tex_Texture_Cube            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube              , rsurface.rtlight->currentcubemap                    );
2905                                 if (r_glsl_permutation->tex_Texture_CubeProjection  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection    , r_shadow_shadowmapvsdcttexture                      );
2906                         }
2907                 }
2908                 if (r_glsl_permutation->tex_Texture_BounceGrid  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture);
2909                 CHECKGLERROR
2910                 break;
2911         case RENDERPATH_GL11:
2912         case RENDERPATH_GL13:
2913         case RENDERPATH_GLES1:
2914                 break;
2915         case RENDERPATH_SOFT:
2916                 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2917                 R_Mesh_PrepareVertices_Mesh_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchsvector3f, rsurface.batchtvector3f, rsurface.batchnormal3f, rsurface.batchlightmapcolor4f, rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f);
2918                 R_SetupShader_SetPermutationSoft(mode, permutation);
2919                 {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
2920                 if (mode == SHADERMODE_LIGHTSOURCE)
2921                 {
2922                         {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
2923                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2924                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2925                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2926                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2927                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2928         
2929                         // additive passes are only darkened by fog, not tinted
2930                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
2931                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2932                 }
2933                 else
2934                 {
2935                         if (mode == SHADERMODE_FLATCOLOR)
2936                         {
2937                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2938                         }
2939                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2940                         {
2941                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
2942                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2943                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2944                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2945                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
2946                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
2947                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2948                         }
2949                         else
2950                         {
2951                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2952                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2953                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2954                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2955                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
2956                         }
2957                         // additive passes are only darkened by fog, not tinted
2958                         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2959                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
2960                         else
2961                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2962                         DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_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);
2963                         DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2964                         DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2965                         DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2966                         DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2967                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2968                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
2969                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2970                         DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2971                 }
2972                 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
2973                 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
2974                 {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
2975                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2976                 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2977
2978                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2979                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
2980                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2981                 if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
2982                 {
2983                         if (rsurface.texture->pantstexture)
2984                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2985                         else
2986                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
2987                 }
2988                 if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
2989                 {
2990                         if (rsurface.texture->shirttexture)
2991                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2992                         else
2993                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
2994                 }
2995                 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2996                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist);
2997                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
2998                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
2999                 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps,
3000                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
3001                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
3002                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
3003                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
3004                         );
3005                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
3006                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias);
3007                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3008                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
3009
3010                 R_Mesh_TexBind(GL20TU_NORMAL            , rsurface.texture->nmaptexture                       );
3011                 R_Mesh_TexBind(GL20TU_COLOR             , rsurface.texture->basetexture                       );
3012                 R_Mesh_TexBind(GL20TU_GLOSS             , rsurface.texture->glosstexture                      );
3013                 R_Mesh_TexBind(GL20TU_GLOW              , rsurface.texture->glowtexture                       );
3014                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL  , rsurface.texture->backgroundnmaptexture             );
3015                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR   , rsurface.texture->backgroundbasetexture             );
3016                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS   , rsurface.texture->backgroundglosstexture            );
3017                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW    , rsurface.texture->backgroundglowtexture             );
3018                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS             , rsurface.texture->pantstexture                      );
3019                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT             , rsurface.texture->shirttexture                      );
3020                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK       , rsurface.texture->reflectmasktexture                );
3021                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE       , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
3022                 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE  , r_texture_fogheighttexture                          );
3023                 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK           , r_texture_fogattenuation                            );
3024                 R_Mesh_TexBind(GL20TU_LIGHTMAP          , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
3025                 R_Mesh_TexBind(GL20TU_DELUXEMAP         , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
3026                 if (rsurface.rtlight                                  ) R_Mesh_TexBind(GL20TU_ATTENUATION       , r_shadow_attenuationgradienttexture                 );
3027                 if (rsurfacepass == RSURFPASS_BACKGROUND)
3028                 {
3029                         R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
3030                         if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
3031                         R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
3032                 }
3033                 else
3034                 {
3035                         if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
3036                 }
3037 //              if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
3038                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
3039                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
3040                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
3041                 {
3042                         R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
3043                         if (rsurface.rtlight)
3044                         {
3045                                 if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
3046                                 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT    ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
3047                         }
3048                 }
3049                 break;
3050         }
3051 }
3052
3053 void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
3054 {
3055         // select a permutation of the lighting shader appropriate to this
3056         // combination of texture, entity, light source, and fogging, only use the
3057         // minimum features necessary to avoid wasting rendering time in the
3058         // fragment shader on features that are not being used
3059         unsigned int permutation = 0;
3060         unsigned int mode = 0;
3061         const float *lightcolorbase = rtlight->currentcolor;
3062         float ambientscale = rtlight->ambientscale;
3063         float diffusescale = rtlight->diffusescale;
3064         float specularscale = rtlight->specularscale;
3065         // this is the location of the light in view space
3066         vec3_t viewlightorigin;
3067         // this transforms from view space (camera) to light space (cubemap)
3068         matrix4x4_t viewtolight;
3069         matrix4x4_t lighttoview;
3070         float viewtolight16f[16];
3071         // light source
3072         mode = SHADERMODE_DEFERREDLIGHTSOURCE;
3073         if (rtlight->currentcubemap != r_texture_whitecube)
3074                 permutation |= SHADERPERMUTATION_CUBEFILTER;
3075         if (diffusescale > 0)
3076                 permutation |= SHADERPERMUTATION_DIFFUSE;
3077         if (specularscale > 0 && r_shadow_gloss.integer > 0)
3078                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
3079         if (r_shadow_usingshadowmap2d)
3080         {
3081                 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
3082                 if (r_shadow_shadowmapvsdct)
3083                         permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
3084
3085                 if (r_shadow_shadowmap2ddepthbuffer)
3086                         permutation |= SHADERPERMUTATION_DEPTHRGB;
3087         }
3088         if (vid.allowalphatocoverage)
3089                 GL_AlphaToCoverage(false);
3090         Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
3091         Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
3092         Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
3093         Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
3094         switch(vid.renderpath)
3095         {
3096         case RENDERPATH_D3D9:
3097 #ifdef SUPPORTD3D
3098                 R_SetupShader_SetPermutationHLSL(mode, permutation);
3099                 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3100                 hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f);
3101                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3102                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3103                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3104                 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3105                 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
3106                 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
3107                 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3108                 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
3109
3110                 R_Mesh_TexBind(GL20TU_ATTENUATION        , r_shadow_attenuationgradienttexture                 );
3111                 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP    , r_shadow_prepassgeometrynormalmaptexture            );
3112                 R_Mesh_TexBind(GL20TU_CUBE               , rsurface.rtlight->currentcubemap                    );
3113                 R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2ddepthtexture                    );
3114                 R_Mesh_TexBind(GL20TU_CUBEPROJECTION     , r_shadow_shadowmapvsdcttexture                      );
3115 #endif
3116                 break;
3117         case RENDERPATH_D3D10:
3118                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3119                 break;
3120         case RENDERPATH_D3D11:
3121                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3122                 break;
3123         case RENDERPATH_GL20:
3124         case RENDERPATH_GLES2:
3125                 R_SetupShader_SetPermutationGLSL(mode, permutation);
3126                 if (r_glsl_permutation->loc_LightPosition             >= 0) qglUniform3f(       r_glsl_permutation->loc_LightPosition            , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3127                 if (r_glsl_permutation->loc_ViewToLight               >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ViewToLight              , 1, false, viewtolight16f);
3128                 if (r_glsl_permutation->loc_DeferredColor_Ambient     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3129                 if (r_glsl_permutation->loc_DeferredColor_Diffuse     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3130                 if (r_glsl_permutation->loc_DeferredColor_Specular    >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Specular   , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3131                 if (r_glsl_permutation->loc_ShadowMap_TextureScale    >= 0) qglUniform2f(       r_glsl_permutation->loc_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3132                 if (r_glsl_permutation->loc_ShadowMap_Parameters      >= 0) qglUniform4f(       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]);
3133                 if (r_glsl_permutation->loc_SpecularPower             >= 0) qglUniform1f(       r_glsl_permutation->loc_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
3134                 if (r_glsl_permutation->loc_ScreenToDepth             >= 0) qglUniform2f(       r_glsl_permutation->loc_ScreenToDepth            , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3135                 if (r_glsl_permutation->loc_PixelToScreenTexCoord     >= 0) qglUniform2f(       r_glsl_permutation->loc_PixelToScreenTexCoord    , 1.0f/vid.width, 1.0f/vid.height);
3136
3137                 if (r_glsl_permutation->tex_Texture_Attenuation       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation        , r_shadow_attenuationgradienttexture                 );
3138                 if (r_glsl_permutation->tex_Texture_ScreenNormalMap   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap    , r_shadow_prepassgeometrynormalmaptexture            );
3139                 if (r_glsl_permutation->tex_Texture_Cube              >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube               , rsurface.rtlight->currentcubemap                    );
3140                 if (r_glsl_permutation->tex_Texture_ShadowMap2D       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D        , r_shadow_shadowmap2ddepthtexture                    );
3141                 if (r_glsl_permutation->tex_Texture_CubeProjection    >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection     , r_shadow_shadowmapvsdcttexture                      );
3142                 break;
3143         case RENDERPATH_GL11:
3144         case RENDERPATH_GL13:
3145         case RENDERPATH_GLES1:
3146                 break;
3147         case RENDERPATH_SOFT:
3148                 R_SetupShader_SetPermutationGLSL(mode, permutation);
3149                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_LightPosition            , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3150                 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ViewToLightM1            , 1, false, viewtolight16f);
3151                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3152                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3153                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Specular   , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3154                 DPSOFTRAST_Uniform2f(       DPSOFTRAST_UNIFORM_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3155                 DPSOFTRAST_Uniform4f(       DPSOFTRAST_UNIFORM_ShadowMap_Parameters     , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
3156                 DPSOFTRAST_Uniform1f(       DPSOFTRAST_UNIFORM_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
3157                 DPSOFTRAST_Uniform2f(       DPSOFTRAST_UNIFORM_ScreenToDepth            , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3158                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
3159
3160                 R_Mesh_TexBind(GL20TU_ATTENUATION        , r_shadow_attenuationgradienttexture                 );
3161                 R_Mesh_Tex