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