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