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