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