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