Change shadowless rtlights so that they are not occluded by anything - no pvs checks...
[xonotic/darkplaces.git] / r_shadow.c
1
2 /*
3 Terminology: Stencil Shadow Volume (sometimes called Stencil Shadows)
4 An extrusion of the lit faces, beginning at the original geometry and ending
5 further from the light source than the original geometry (presumably at least
6 as far as the light's radius, if the light has a radius at all), capped at
7 both front and back to avoid any problems (extrusion from dark faces also
8 works but has a different set of problems)
9
10 This is normally rendered using Carmack's Reverse technique, in which
11 backfaces behind zbuffer (zfail) increment the stencil, and frontfaces behind
12 zbuffer (zfail) decrement the stencil, the result is a stencil value of zero
13 where shadows did not intersect the visible geometry, suitable as a stencil
14 mask for rendering lighting everywhere but shadow.
15
16 In our case to hopefully avoid the Creative Labs patent, we draw the backfaces
17 as decrement and the frontfaces as increment, and we redefine the DepthFunc to
18 GL_LESS (the patent uses GL_GEQUAL) which causes zfail when behind surfaces
19 and zpass when infront (the patent draws where zpass with a GL_GEQUAL test),
20 additionally we clear stencil to 128 to avoid the need for the unclamped
21 incr/decr extension (not related to patent).
22
23 Patent warning:
24 This algorithm may be covered by Creative's patent (US Patent #6384822),
25 however that patent is quite specific about increment on backfaces and
26 decrement on frontfaces where zpass with GL_GEQUAL depth test, which is
27 opposite this implementation and partially opposite Carmack's Reverse paper
28 (which uses GL_LESS, but increments on backfaces and decrements on frontfaces).
29
30
31
32 Terminology: Stencil Light Volume (sometimes called Light Volumes)
33 Similar to a Stencil Shadow Volume, but inverted; rather than containing the
34 areas in shadow it contains the areas in light, this can only be built
35 quickly for certain limited cases (such as portal visibility from a point),
36 but is quite useful for some effects (sunlight coming from sky polygons is
37 one possible example, translucent occluders is another example).
38
39
40
41 Terminology: Optimized Stencil Shadow Volume
42 A Stencil Shadow Volume that has been processed sufficiently to ensure it has
43 no duplicate coverage of areas (no need to shadow an area twice), often this
44 greatly improves performance but is an operation too costly to use on moving
45 lights (however completely optimal Stencil Light Volumes can be constructed
46 in some ideal cases).
47
48
49
50 Terminology: Per Pixel Lighting (sometimes abbreviated PPL)
51 Per pixel evaluation of lighting equations, at a bare minimum this involves
52 DOT3 shading of diffuse lighting (per pixel dotproduct of negated incidence
53 vector and surface normal, using a texture of the surface bumps, called a
54 NormalMap) if supported by hardware; in our case there is support for cards
55 which are incapable of DOT3, the quality is quite poor however.  Additionally
56 it is desirable to have specular evaluation per pixel, per vertex
57 normalization of specular halfangle vectors causes noticable distortion but
58 is unavoidable on hardware without GL_ARB_fragment_program or
59 GL_ARB_fragment_shader.
60
61
62
63 Terminology: Normalization CubeMap
64 A cubemap containing normalized dot3-encoded (vectors of length 1 or less
65 encoded as RGB colors) for any possible direction, this technique allows per
66 pixel calculation of incidence vector for per pixel lighting purposes, which
67 would not otherwise be possible per pixel without GL_ARB_fragment_program or
68 GL_ARB_fragment_shader.
69
70
71
72 Terminology: 2D+1D Attenuation Texturing
73 A very crude approximation of light attenuation with distance which results
74 in cylindrical light shapes which fade vertically as a streak (some games
75 such as Doom3 allow this to be rotated to be less noticable in specific
76 cases), the technique is simply modulating lighting by two 2D textures (which
77 can be the same) on different axes of projection (XY and Z, typically), this
78 is the second best technique available without 3D Attenuation Texturing,
79 GL_ARB_fragment_program or GL_ARB_fragment_shader technology.
80
81
82
83 Terminology: 2D+1D Inverse Attenuation Texturing
84 A clever method described in papers on the Abducted engine, this has a squared
85 distance texture (bright on the outside, black in the middle), which is used
86 twice using GL_ADD blending, the result of this is used in an inverse modulate
87 (GL_ONE_MINUS_DST_ALPHA, GL_ZERO) to implement the equation
88 lighting*=(1-((X*X+Y*Y)+(Z*Z))) which is spherical (unlike 2D+1D attenuation
89 texturing).
90
91
92
93 Terminology: 3D Attenuation Texturing
94 A slightly crude approximation of light attenuation with distance, its flaws
95 are limited radius and resolution (performance tradeoffs).
96
97
98
99 Terminology: 3D Attenuation-Normalization Texturing
100 A 3D Attenuation Texture merged with a Normalization CubeMap, by making the
101 vectors shorter the lighting becomes darker, a very effective optimization of
102 diffuse lighting if 3D Attenuation Textures are already used.
103
104
105
106 Terminology: Light Cubemap Filtering
107 A technique for modeling non-uniform light distribution according to
108 direction, for example a lantern may use a cubemap to describe the light
109 emission pattern of the cage around the lantern (as well as soot buildup
110 discoloring the light in certain areas), often also used for softened grate
111 shadows and light shining through a stained glass window (done crudely by
112 texturing the lighting with a cubemap), another good example would be a disco
113 light.  This technique is used heavily in many games (Doom3 does not support
114 this however).
115
116
117
118 Terminology: Light Projection Filtering
119 A technique for modeling shadowing of light passing through translucent
120 surfaces, allowing stained glass windows and other effects to be done more
121 elegantly than possible with Light Cubemap Filtering by applying an occluder
122 texture to the lighting combined with a stencil light volume to limit the lit
123 area, this technique is used by Doom3 for spotlights and flashlights, among
124 other things, this can also be used more generally to render light passing
125 through multiple translucent occluders in a scene (using a light volume to
126 describe the area beyond the occluder, and thus mask off rendering of all
127 other areas).
128
129
130
131 Terminology: Doom3 Lighting
132 A combination of Stencil Shadow Volume, Per Pixel Lighting, Normalization
133 CubeMap, 2D+1D Attenuation Texturing, and Light Projection Filtering, as
134 demonstrated by the game Doom3.
135 */
136
137 #include "quakedef.h"
138 #include "r_shadow.h"
139 #include "cl_collision.h"
140 #include "portals.h"
141 #include "image.h"
142 #include "dpsoftrast.h"
143
144 #ifdef SUPPORTD3D
145 #include <d3d9.h>
146 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
147 #endif
148
149 static void R_Shadow_EditLights_Init(void);
150
151 typedef enum r_shadow_rendermode_e
152 {
153         R_SHADOW_RENDERMODE_NONE,
154         R_SHADOW_RENDERMODE_ZPASS_STENCIL,
155         R_SHADOW_RENDERMODE_ZPASS_SEPARATESTENCIL,
156         R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE,
157         R_SHADOW_RENDERMODE_ZFAIL_STENCIL,
158         R_SHADOW_RENDERMODE_ZFAIL_SEPARATESTENCIL,
159         R_SHADOW_RENDERMODE_ZFAIL_STENCILTWOSIDE,
160         R_SHADOW_RENDERMODE_LIGHT_VERTEX,
161         R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN,
162         R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN,
163         R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN,
164         R_SHADOW_RENDERMODE_LIGHT_GLSL,
165         R_SHADOW_RENDERMODE_VISIBLEVOLUMES,
166         R_SHADOW_RENDERMODE_VISIBLELIGHTING,
167         R_SHADOW_RENDERMODE_SHADOWMAP2D
168 }
169 r_shadow_rendermode_t;
170
171 typedef enum r_shadow_shadowmode_e
172 {
173         R_SHADOW_SHADOWMODE_STENCIL,
174         R_SHADOW_SHADOWMODE_SHADOWMAP2D
175 }
176 r_shadow_shadowmode_t;
177
178 r_shadow_rendermode_t r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
179 r_shadow_rendermode_t r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_NONE;
180 r_shadow_rendermode_t r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_NONE;
181 r_shadow_rendermode_t r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_NONE;
182 int r_shadow_scenemaxlights;
183 int r_shadow_scenenumlights;
184 rtlight_t **r_shadow_scenelightlist; // includes both static lights and dlights, as filtered by appropriate flags
185 qboolean r_shadow_usingshadowmap2d;
186 qboolean r_shadow_usingshadowmaportho;
187 int r_shadow_shadowmapside;
188 float r_shadow_lightshadowmap_texturescale[4]; // xy = scale, zw = offset
189 float r_shadow_lightshadowmap_parameters[4]; // x = frustum width in pixels (excludes border), y = z scale, z = size of viewport, w = z center
190 float r_shadow_modelshadowmap_texturescale[4]; // xy = scale, zw = offset
191 float r_shadow_modelshadowmap_parameters[4]; // xyz = scale, w = shadow brightness
192 #if 0
193 int r_shadow_drawbuffer;
194 int r_shadow_readbuffer;
195 #endif
196 int r_shadow_cullface_front, r_shadow_cullface_back;
197 GLuint r_shadow_fbo2d;
198 r_shadow_shadowmode_t r_shadow_shadowmode;
199 int r_shadow_shadowmapfilterquality;
200 int r_shadow_shadowmapdepthbits;
201 int r_shadow_shadowmapmaxsize;
202 int r_shadow_shadowmaptexturesize;
203 qboolean r_shadow_shadowmapvsdct;
204 qboolean r_shadow_shadowmapsampler;
205 qboolean r_shadow_shadowmapshadowsampler;
206 int r_shadow_shadowmappcf;
207 int r_shadow_shadowmapborder;
208 matrix4x4_t r_shadow_shadowmapmatrix;
209 int r_shadow_lightscissor[4];
210 qboolean r_shadow_usingdeferredprepass;
211 qboolean r_shadow_shadowmapdepthtexture;
212 mod_alloclightmap_state_t r_shadow_shadowmapatlas_state;
213 int r_shadow_shadowmapatlas_modelshadows_x;
214 int r_shadow_shadowmapatlas_modelshadows_y;
215 int r_shadow_shadowmapatlas_modelshadows_size;
216 int maxshadowtriangles;
217 int *shadowelements;
218
219 int maxshadowvertices;
220 float *shadowvertex3f;
221
222 int maxshadowmark;
223 int numshadowmark;
224 int *shadowmark;
225 int *shadowmarklist;
226 int shadowmarkcount;
227
228 int maxshadowsides;
229 int numshadowsides;
230 unsigned char *shadowsides;
231 int *shadowsideslist;
232
233 int maxvertexupdate;
234 int *vertexupdate;
235 int *vertexremap;
236 int vertexupdatenum;
237
238 int r_shadow_buffer_numleafpvsbytes;
239 unsigned char *r_shadow_buffer_visitingleafpvs;
240 unsigned char *r_shadow_buffer_leafpvs;
241 int *r_shadow_buffer_leaflist;
242
243 int r_shadow_buffer_numsurfacepvsbytes;
244 unsigned char *r_shadow_buffer_surfacepvs;
245 int *r_shadow_buffer_surfacelist;
246 unsigned char *r_shadow_buffer_surfacesides;
247
248 int r_shadow_buffer_numshadowtrispvsbytes;
249 unsigned char *r_shadow_buffer_shadowtrispvs;
250 int r_shadow_buffer_numlighttrispvsbytes;
251 unsigned char *r_shadow_buffer_lighttrispvs;
252
253 rtexturepool_t *r_shadow_texturepool;
254 rtexture_t *r_shadow_attenuationgradienttexture;
255 rtexture_t *r_shadow_attenuation2dtexture;
256 rtexture_t *r_shadow_attenuation3dtexture;
257 skinframe_t *r_shadow_lightcorona;
258 rtexture_t *r_shadow_shadowmap2ddepthbuffer;
259 rtexture_t *r_shadow_shadowmap2ddepthtexture;
260 rtexture_t *r_shadow_shadowmapvsdcttexture;
261
262 GLuint r_shadow_prepassgeometryfbo;
263 GLuint r_shadow_prepasslightingdiffusespecularfbo;
264 GLuint r_shadow_prepasslightingdiffusefbo;
265 int r_shadow_prepass_width;
266 int r_shadow_prepass_height;
267 rtexture_t *r_shadow_prepassgeometrydepthbuffer;
268 rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
269 rtexture_t *r_shadow_prepasslightingdiffusetexture;
270 rtexture_t *r_shadow_prepasslightingspeculartexture;
271
272 // keep track of the provided framebuffer info
273 static int r_shadow_fb_fbo;
274 static rtexture_t *r_shadow_fb_depthtexture;
275 static rtexture_t *r_shadow_fb_colortexture;
276
277 // lights are reloaded when this changes
278 char r_shadow_mapname[MAX_QPATH];
279
280 // buffer for doing corona fading
281 unsigned int r_shadow_occlusion_buf = 0;
282
283 // used only for light filters (cubemaps)
284 rtexturepool_t *r_shadow_filters_texturepool;
285
286 cvar_t r_shadow_bumpscale_basetexture = {0, "r_shadow_bumpscale_basetexture", "0", "generate fake bumpmaps from diffuse textures at this bumpyness, try 4 to match tenebrae, higher values increase depth, requires r_restart to take effect"};
287 cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4", "what magnitude to interpret _bump.tga textures as, higher values increase depth, requires r_restart to take effect"};
288 cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1", "renders only one light, for level design purposes or debugging"};
289 cvar_t r_shadow_deferred = {CVAR_SAVE, "r_shadow_deferred", "0", "uses image-based lighting instead of geometry-based lighting, the method used renders a depth image and a normalmap image, renders lights into separate diffuse and specular images, and then combines this into the normal rendering, requires r_shadow_shadowmapping"};
290 cvar_t r_shadow_usebihculling = {0, "r_shadow_usebihculling", "1", "use BIH (Bounding Interval Hierarchy) for culling lit surfaces instead of BSP (Binary Space Partitioning)"};
291 cvar_t r_shadow_usenormalmap = {CVAR_SAVE, "r_shadow_usenormalmap", "1", "enables use of directional shading on lights"};
292 cvar_t r_shadow_gloss = {CVAR_SAVE, "r_shadow_gloss", "1", "0 disables gloss (specularity) rendering, 1 uses gloss if textures are found, 2 forces a flat metallic specular effect on everything without textures (similar to tenebrae)"};
293 cvar_t r_shadow_gloss2intensity = {0, "r_shadow_gloss2intensity", "0.125", "how bright the forced flat gloss should look if r_shadow_gloss is 2"};
294 cvar_t r_shadow_glossintensity = {0, "r_shadow_glossintensity", "1", "how bright textured glossmaps should look if r_shadow_gloss is 1 or 2"};
295 cvar_t r_shadow_glossexponent = {0, "r_shadow_glossexponent", "32", "how 'sharp' the gloss should appear (specular power)"};
296 cvar_t r_shadow_gloss2exponent = {0, "r_shadow_gloss2exponent", "32", "same as r_shadow_glossexponent but for forced gloss (gloss 2) surfaces"};
297 cvar_t r_shadow_glossexact = {0, "r_shadow_glossexact", "0", "use exact reflection math for gloss (slightly slower, but should look a tad better)"};
298 cvar_t r_shadow_lightattenuationdividebias = {0, "r_shadow_lightattenuationdividebias", "1", "changes attenuation texture generation"};
299 cvar_t r_shadow_lightattenuationlinearscale = {0, "r_shadow_lightattenuationlinearscale", "2", "changes attenuation texture generation"};
300 cvar_t r_shadow_lightintensityscale = {0, "r_shadow_lightintensityscale", "1", "renders all world lights brighter or darker"};
301 cvar_t r_shadow_lightradiusscale = {0, "r_shadow_lightradiusscale", "1", "renders all world lights larger or smaller"};
302 cvar_t r_shadow_projectdistance = {0, "r_shadow_projectdistance", "0", "how far to cast shadows"};
303 cvar_t r_shadow_frontsidecasting = {0, "r_shadow_frontsidecasting", "1", "whether to cast shadows from illuminated triangles (front side of model) or unlit triangles (back side of model)"};
304 cvar_t r_shadow_realtime_dlight = {CVAR_SAVE, "r_shadow_realtime_dlight", "1", "enables rendering of dynamic lights such as explosions and rocket light"};
305 cvar_t r_shadow_realtime_dlight_shadows = {CVAR_SAVE, "r_shadow_realtime_dlight_shadows", "1", "enables rendering of shadows from dynamic lights"};
306 cvar_t r_shadow_realtime_dlight_svbspculling = {0, "r_shadow_realtime_dlight_svbspculling", "0", "enables svbsp optimization on dynamic lights (very slow!)"};
307 cvar_t r_shadow_realtime_dlight_portalculling = {0, "r_shadow_realtime_dlight_portalculling", "0", "enables portal optimization on dynamic lights (slow!)"};
308 cvar_t r_shadow_realtime_world = {CVAR_SAVE, "r_shadow_realtime_world", "0", "enables rendering of full world lighting (whether loaded from the map, or a .rtlights file, or a .ent file, or a .lights file produced by hlight)"};
309 cvar_t r_shadow_realtime_world_importlightentitiesfrommap = {0, "r_shadow_realtime_world_importlightentitiesfrommap", "1", "load lights from .ent file or map entities at startup if no .rtlights or .lights file is present (if set to 2, always use the .ent or map entities)"};
310 cvar_t r_shadow_realtime_world_lightmaps = {CVAR_SAVE, "r_shadow_realtime_world_lightmaps", "0", "brightness to render lightmaps when using full world lighting, try 0.5 for a tenebrae-like appearance"};
311 cvar_t r_shadow_realtime_world_shadows = {CVAR_SAVE, "r_shadow_realtime_world_shadows", "1", "enables rendering of shadows from world lights"};
312 cvar_t r_shadow_realtime_world_compile = {0, "r_shadow_realtime_world_compile", "1", "enables compilation of world lights for higher performance rendering"};
313 cvar_t r_shadow_realtime_world_compileshadow = {0, "r_shadow_realtime_world_compileshadow", "1", "enables compilation of shadows from world lights for higher performance rendering"};
314 cvar_t r_shadow_realtime_world_compilesvbsp = {0, "r_shadow_realtime_world_compilesvbsp", "1", "enables svbsp optimization during compilation (slower than compileportalculling but more exact)"};
315 cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "1", "enables portal-based culling optimization during compilation (overrides compilesvbsp)"};
316 cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1", "use scissor optimization of light rendering (restricts rendering to the portion of the screen affected by the light)"};
317 cvar_t r_shadow_shadowmapping = {CVAR_SAVE, "r_shadow_shadowmapping", "1", "enables use of shadowmapping (depth texture sampling) instead of stencil shadow volumes"};
318 cvar_t r_shadow_shadowmapping_filterquality = {CVAR_SAVE, "r_shadow_shadowmapping_filterquality", "-1", "shadowmap filter modes: -1 = auto-select, 0 = no filtering, 1 = bilinear, 2 = bilinear 2x2 blur (fast), 3 = 3x3 blur (moderate), 4 = 4x4 blur (slow)"};
319 cvar_t r_shadow_shadowmapping_useshadowsampler = {CVAR_SAVE, "r_shadow_shadowmapping_useshadowsampler", "1", "whether to use sampler2DShadow if available"};
320 cvar_t r_shadow_shadowmapping_depthbits = {CVAR_SAVE, "r_shadow_shadowmapping_depthbits", "24", "requested minimum shadowmap texture depth bits"};
321 cvar_t r_shadow_shadowmapping_vsdct = {CVAR_SAVE, "r_shadow_shadowmapping_vsdct", "1", "enables use of virtual shadow depth cube texture"};
322 cvar_t r_shadow_shadowmapping_minsize = {CVAR_SAVE, "r_shadow_shadowmapping_minsize", "32", "limit of shadowmap side size - must be at least r_shadow_shadowmapping_bordersize+2"};
323 cvar_t r_shadow_shadowmapping_maxsize = {CVAR_SAVE, "r_shadow_shadowmapping_maxsize", "512", "limit of shadowmap side size - can not be more than 1/8th of atlassize because lights store 6 sides (2x3 grid) and sometimes 12 sides (4x3 grid for shadows from EF_NOSELFSHADOW entities) and there are multiple lights..."};
324 cvar_t r_shadow_shadowmapping_texturesize = { CVAR_SAVE, "r_shadow_shadowmapping_texturesize", "8192", "size of shadowmap atlas texture - all shadowmaps are packed into this texture at frame start"};
325 cvar_t r_shadow_shadowmapping_precision = {CVAR_SAVE, "r_shadow_shadowmapping_precision", "1", "makes shadowmaps have a maximum resolution of this number of pixels per light source radius unit such that, for example, at precision 0.5 a light with radius 200 will have a maximum resolution of 100 pixels"};
326 //cvar_t r_shadow_shadowmapping_lod_bias = {CVAR_SAVE, "r_shadow_shadowmapping_lod_bias", "16", "shadowmap size bias"};
327 //cvar_t r_shadow_shadowmapping_lod_scale = {CVAR_SAVE, "r_shadow_shadowmapping_lod_scale", "128", "shadowmap size scaling parameter"};
328 cvar_t r_shadow_shadowmapping_bordersize = {CVAR_SAVE, "r_shadow_shadowmapping_bordersize", "4", "shadowmap size bias for filtering"};
329 cvar_t r_shadow_shadowmapping_nearclip = {CVAR_SAVE, "r_shadow_shadowmapping_nearclip", "1", "shadowmap nearclip in world units"};
330 cvar_t r_shadow_shadowmapping_bias = {CVAR_SAVE, "r_shadow_shadowmapping_bias", "0.03", "shadowmap bias parameter (this is multiplied by nearclip * 1024 / lodsize)"};
331 cvar_t r_shadow_shadowmapping_polygonfactor = {CVAR_SAVE, "r_shadow_shadowmapping_polygonfactor", "2", "slope-dependent shadowmapping bias"};
332 cvar_t r_shadow_shadowmapping_polygonoffset = {CVAR_SAVE, "r_shadow_shadowmapping_polygonoffset", "0", "constant shadowmapping bias"};
333 cvar_t r_shadow_sortsurfaces = {0, "r_shadow_sortsurfaces", "1", "improve performance by sorting illuminated surfaces by texture"};
334 cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"};
335 cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"};
336 cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel textures for spherical attenuation rather than cylindrical (does not affect OpenGL 2.0 render path)"};
337 cvar_t r_shadow_bouncegrid = {CVAR_SAVE, "r_shadow_bouncegrid", "0", "perform particle tracing for indirect lighting (Global Illumination / radiosity) using a 3D texture covering the scene, only active on levels with realtime lights active (r_shadow_realtime_world is usually required for these)"};
338 cvar_t r_shadow_bouncegrid_blur = {CVAR_SAVE, "r_shadow_bouncegrid_blur", "0", "apply a 1-radius blur on bouncegrid to denoise it and deal with boundary issues with surfaces"};
339 cvar_t r_shadow_bouncegrid_bounceanglediffuse = {CVAR_SAVE, "r_shadow_bouncegrid_bounceanglediffuse", "0", "use random bounce direction rather than true reflection, makes some corner areas dark"};
340 cvar_t r_shadow_bouncegrid_dynamic_bounceminimumintensity = { CVAR_SAVE, "r_shadow_bouncegrid_dynamic_bounceminimumintensity", "0.05", "stop bouncing once intensity drops below this fraction of the original particle color" };
341 cvar_t r_shadow_bouncegrid_dynamic_culllightpaths = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_culllightpaths", "1", "skip accumulating light in the bouncegrid texture where the light paths are out of view (dynamic mode only)"};
342 cvar_t r_shadow_bouncegrid_dynamic_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_directionalshading", "0", "use diffuse shading rather than ambient, 3D texture becomes 8x as many pixels to hold the additional data"};
343 cvar_t r_shadow_bouncegrid_dynamic_dlightparticlemultiplier = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_dlightparticlemultiplier", "1", "if set to a high value like 16 this can make dlights look great, but 0 is recommended for performance reasons"};
344 cvar_t r_shadow_bouncegrid_dynamic_hitmodels = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_hitmodels", "0", "enables hitting character model geometry (SLOW)"};
345 cvar_t r_shadow_bouncegrid_dynamic_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_lightradiusscale", "2", "particles stop at this fraction of light radius (can be more than 1)"};
346 cvar_t r_shadow_bouncegrid_dynamic_maxbounce = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_maxbounce", "2", "maximum number of bounces for a particle (minimum is 0)"};
347 cvar_t r_shadow_bouncegrid_dynamic_maxphotons = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_maxphotons", "25000", "upper bound on photons to shoot per update, divided proportionately between lights - normally the number of photons is calculated by energyperphoton"};
348 cvar_t r_shadow_bouncegrid_dynamic_quality = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_quality", "1", "amount of photons that should be fired (this is multiplied by spacing^2 to make it adaptive with spacing changes)"};
349 cvar_t r_shadow_bouncegrid_dynamic_spacing = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_spacing", "64", "unit size of bouncegrid pixel"};
350 cvar_t r_shadow_bouncegrid_dynamic_updateinterval = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_updateinterval", "0", "update bouncegrid texture once per this many seconds, useful values are 0, 0.05, or 1000000"};
351 cvar_t r_shadow_bouncegrid_dynamic_x = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_x", "64", "maximum texture size of bouncegrid on X axis"};
352 cvar_t r_shadow_bouncegrid_dynamic_y = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_y", "64", "maximum texture size of bouncegrid on Y axis"};
353 cvar_t r_shadow_bouncegrid_dynamic_z = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_z", "32", "maximum texture size of bouncegrid on Z axis"};
354 cvar_t r_shadow_bouncegrid_floatcolors = {CVAR_SAVE, "r_shadow_bouncegrid_floatcolors", "1", "upload texture as RGBA16F (or RGBA32F when set to 2) rather than RGBA8 format - this gives more dynamic range and accuracy"};
355 cvar_t r_shadow_bouncegrid_includedirectlighting = {CVAR_SAVE, "r_shadow_bouncegrid_includedirectlighting", "0", "allows direct lighting to be recorded, not just indirect (gives an effect somewhat like r_shadow_realtime_world_lightmaps)"};
356 cvar_t r_shadow_bouncegrid_intensity = {CVAR_SAVE, "r_shadow_bouncegrid_intensity", "4", "overall brightness of bouncegrid texture"};
357 cvar_t r_shadow_bouncegrid_lightpathsize_conespread = {CVAR_SAVE, "r_shadow_bouncegrid_lightpathsize_conespread", "0.015625", "increase lightpathsize over distance at this rate per grid cell"};
358 cvar_t r_shadow_bouncegrid_lightpathsize_initial = {CVAR_SAVE, "r_shadow_bouncegrid_lightpathsize_initial", "0.5", "width (in grid cells) of the light path for accumulation of light in the bouncegrid texture"};
359 cvar_t r_shadow_bouncegrid_normalizevectors = { CVAR_SAVE, "r_shadow_bouncegrid_normalizevectors", "1", "normalize random vectors (otherwise their length can vary, which dims the lighting further from the light)" };
360 cvar_t r_shadow_bouncegrid_particlebounceintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particlebounceintensity", "2", "amount of energy carried over after each bounce, this is a multiplier of texture color and the result is clamped to 1 or less, to prevent adding energy on each bounce"};
361 cvar_t r_shadow_bouncegrid_particleintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particleintensity", "0.25", "brightness of particles contributing to bouncegrid texture"};
362 cvar_t r_shadow_bouncegrid_rng_seed = { CVAR_SAVE, "r_shadow_bouncegrid_rng_seed", "0", "0+ = use this number as RNG seed, -1 = use time instead for disco-like craziness in dynamic mode" };
363 cvar_t r_shadow_bouncegrid_rng_type = { CVAR_SAVE, "r_shadow_bouncegrid_rng_type", "0", "0 = Lehmer 128bit RNG (slow but high quality), 1 = lhcheeserand 32bit RNG (quick)" };
364 cvar_t r_shadow_bouncegrid_sortlightpaths = {CVAR_SAVE, "r_shadow_bouncegrid_sortlightpaths", "1", "sort light paths before accumulating them into the bouncegrid texture, this reduces cpu cache misses"};
365 cvar_t r_shadow_bouncegrid_static = {CVAR_SAVE, "r_shadow_bouncegrid_static", "1", "use static radiosity solution (high quality) rather than dynamic (splotchy)"};
366 cvar_t r_shadow_bouncegrid_static_bounceminimumintensity = { CVAR_SAVE, "r_shadow_bouncegrid_static_bounceminimumintensity", "0.01", "stop bouncing once intensity drops below this fraction of the original particle color" };
367 cvar_t r_shadow_bouncegrid_static_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_static_directionalshading", "1", "whether to use directionalshading when in static mode"};
368 cvar_t r_shadow_bouncegrid_static_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_static_lightradiusscale", "2", "particles stop at this fraction of light radius (can be more than 1) when in static mode"};
369 cvar_t r_shadow_bouncegrid_static_maxbounce = {CVAR_SAVE, "r_shadow_bouncegrid_static_maxbounce", "5", "maximum number of bounces for a particle (minimum is 0) in static mode"};
370 cvar_t r_shadow_bouncegrid_static_maxphotons = {CVAR_SAVE, "r_shadow_bouncegrid_static_maxphotons", "250000", "upper bound on photons in static mode"};
371 cvar_t r_shadow_bouncegrid_static_quality = { CVAR_SAVE, "r_shadow_bouncegrid_static_quality", "16", "amount of photons that should be fired (this is multiplied by spacing^2 to make it adaptive with spacing changes)" };
372 cvar_t r_shadow_bouncegrid_static_spacing = {CVAR_SAVE, "r_shadow_bouncegrid_static_spacing", "64", "unit size of bouncegrid pixel when in static mode"};
373 cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "0", "brightness of corona flare effects around certain lights, 0 disables corona effects"};
374 cvar_t r_coronas_occlusionsizescale = {CVAR_SAVE, "r_coronas_occlusionsizescale", "0.1", "size of light source for corona occlusion checksum the proportion of hidden pixels controls corona intensity"};
375 cvar_t r_coronas_occlusionquery = {CVAR_SAVE, "r_coronas_occlusionquery", "0", "use GL_ARB_occlusion_query extension if supported (fades coronas according to visibility) - bad performance (synchronous rendering) - worse on multi-gpu!"};
376 cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"};
377 cvar_t gl_ext_separatestencil = {0, "gl_ext_separatestencil", "1", "make use of OpenGL 2.0 glStencilOpSeparate or GL_ATI_separate_stencil extension"};
378 cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1", "make use of GL_EXT_stenciltwoside extension (NVIDIA only)"};
379 cvar_t r_editlights = {0, "r_editlights", "0", "enables .rtlights file editing mode"};
380 cvar_t r_editlights_cursordistance = {0, "r_editlights_cursordistance", "1024", "maximum distance of cursor from eye"};
381 cvar_t r_editlights_cursorpushback = {0, "r_editlights_cursorpushback", "0", "how far to pull the cursor back toward the eye"};
382 cvar_t r_editlights_cursorpushoff = {0, "r_editlights_cursorpushoff", "4", "how far to push the cursor off the impacted surface"};
383 cvar_t r_editlights_cursorgrid = {0, "r_editlights_cursorgrid", "4", "snaps cursor to this grid size"};
384 cvar_t r_editlights_quakelightsizescale = {CVAR_SAVE, "r_editlights_quakelightsizescale", "1", "changes size of light entities loaded from a map"};
385 cvar_t r_editlights_drawproperties = {0, "r_editlights_drawproperties", "1", "draw properties of currently selected light"};
386 cvar_t r_editlights_current_origin = {0, "r_editlights_current_origin", "0 0 0", "origin of selected light"};
387 cvar_t r_editlights_current_angles = {0, "r_editlights_current_angles", "0 0 0", "angles of selected light"};
388 cvar_t r_editlights_current_color = {0, "r_editlights_current_color", "1 1 1", "color of selected light"};
389 cvar_t r_editlights_current_radius = {0, "r_editlights_current_radius", "0", "radius of selected light"};
390 cvar_t r_editlights_current_corona = {0, "r_editlights_current_corona", "0", "corona intensity of selected light"};
391 cvar_t r_editlights_current_coronasize = {0, "r_editlights_current_coronasize", "0", "corona size of selected light"};
392 cvar_t r_editlights_current_style = {0, "r_editlights_current_style", "0", "style of selected light"};
393 cvar_t r_editlights_current_shadows = {0, "r_editlights_current_shadows", "0", "shadows flag of selected light"};
394 cvar_t r_editlights_current_cubemap = {0, "r_editlights_current_cubemap", "0", "cubemap of selected light"};
395 cvar_t r_editlights_current_ambient = {0, "r_editlights_current_ambient", "0", "ambient intensity of selected light"};
396 cvar_t r_editlights_current_diffuse = {0, "r_editlights_current_diffuse", "1", "diffuse intensity of selected light"};
397 cvar_t r_editlights_current_specular = {0, "r_editlights_current_specular", "1", "specular intensity of selected light"};
398 cvar_t r_editlights_current_normalmode = {0, "r_editlights_current_normalmode", "0", "normalmode flag of selected light"};
399 cvar_t r_editlights_current_realtimemode = {0, "r_editlights_current_realtimemode", "0", "realtimemode flag of selected light"};
400
401 r_shadow_bouncegrid_state_t r_shadow_bouncegrid_state;
402
403 // note the table actually includes one more value, just to avoid the need to clamp the distance index due to minor math error
404 #define ATTENTABLESIZE 256
405 // 1D gradient, 2D circle and 3D sphere attenuation textures
406 #define ATTEN1DSIZE 32
407 #define ATTEN2DSIZE 64
408 #define ATTEN3DSIZE 32
409
410 static float r_shadow_attendividebias; // r_shadow_lightattenuationdividebias
411 static float r_shadow_attenlinearscale; // r_shadow_lightattenuationlinearscale
412 static float r_shadow_attentable[ATTENTABLESIZE+1];
413
414 rtlight_t *r_shadow_compilingrtlight;
415 static memexpandablearray_t r_shadow_worldlightsarray;
416 dlight_t *r_shadow_selectedlight;
417 dlight_t r_shadow_bufferlight;
418 vec3_t r_editlights_cursorlocation;
419 qboolean r_editlights_lockcursor;
420
421 extern int con_vislines;
422
423 void R_Shadow_UncompileWorldLights(void);
424 void R_Shadow_ClearWorldLights(void);
425 void R_Shadow_SaveWorldLights(void);
426 void R_Shadow_LoadWorldLights(void);
427 void R_Shadow_LoadLightsFile(void);
428 void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void);
429 void R_Shadow_EditLights_Reload_f(void);
430 void R_Shadow_ValidateCvars(void);
431 static void R_Shadow_MakeTextures(void);
432
433 #define EDLIGHTSPRSIZE                  8
434 skinframe_t *r_editlights_sprcursor;
435 skinframe_t *r_editlights_sprlight;
436 skinframe_t *r_editlights_sprnoshadowlight;
437 skinframe_t *r_editlights_sprcubemaplight;
438 skinframe_t *r_editlights_sprcubemapnoshadowlight;
439 skinframe_t *r_editlights_sprselection;
440
441 static void R_Shadow_DrawModelShadowMaps(void);
442 static void R_Shadow_MakeShadowMap(int texturesize);
443 static void R_Shadow_MakeVSDCT(void);
444 static void R_Shadow_SetShadowMode(void)
445 {
446         r_shadow_shadowmapborder = bound(1, r_shadow_shadowmapping_bordersize.integer, 16);
447         r_shadow_shadowmaptexturesize = bound(256, r_shadow_shadowmapping_texturesize.integer, (int)vid.maxtexturesize_2d);
448         r_shadow_shadowmapmaxsize = bound(r_shadow_shadowmapborder+2, r_shadow_shadowmapping_maxsize.integer, r_shadow_shadowmaptexturesize / 8);
449         r_shadow_shadowmapvsdct = r_shadow_shadowmapping_vsdct.integer != 0 && vid.renderpath == RENDERPATH_GL20;
450         r_shadow_shadowmapfilterquality = r_shadow_shadowmapping_filterquality.integer;
451         r_shadow_shadowmapshadowsampler = r_shadow_shadowmapping_useshadowsampler.integer != 0;
452         r_shadow_shadowmapdepthbits = r_shadow_shadowmapping_depthbits.integer;
453         r_shadow_shadowmapsampler = false;
454         r_shadow_shadowmappcf = 0;
455         r_shadow_shadowmapdepthtexture = r_fb.usedepthtextures;
456         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_STENCIL;
457         Mod_AllocLightmap_Init(&r_shadow_shadowmapatlas_state, r_main_mempool, r_shadow_shadowmaptexturesize, r_shadow_shadowmaptexturesize);
458         if ((r_shadow_shadowmapping.integer || r_shadow_deferred.integer) && vid.support.ext_framebuffer_object)
459         {
460                 switch(vid.renderpath)
461                 {
462                 case RENDERPATH_GL20:
463                         if(r_shadow_shadowmapfilterquality < 0)
464                         {
465                                 if (!r_fb.usedepthtextures)
466                                         r_shadow_shadowmappcf = 1;
467                                 else if((strstr(gl_vendor, "NVIDIA") || strstr(gl_renderer, "Radeon HD")) && vid.support.arb_shadow && r_shadow_shadowmapshadowsampler)
468                                 {
469                                         r_shadow_shadowmapsampler = true;
470                                         r_shadow_shadowmappcf = 1;
471                                 }
472                                 else if(vid.support.amd_texture_texture4 || vid.support.arb_texture_gather)
473                                         r_shadow_shadowmappcf = 1;
474                                 else if((strstr(gl_vendor, "ATI") || strstr(gl_vendor, "Advanced Micro Devices")) && !strstr(gl_renderer, "Mesa") && !strstr(gl_version, "Mesa"))
475                                         r_shadow_shadowmappcf = 1;
476                                 else
477                                         r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler;
478                         }
479                         else
480                         {
481                 r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler;
482                                 switch (r_shadow_shadowmapfilterquality)
483                                 {
484                                 case 1:
485                                         break;
486                                 case 2:
487                                         r_shadow_shadowmappcf = 1;
488                                         break;
489                                 case 3:
490                                         r_shadow_shadowmappcf = 1;
491                                         break;
492                                 case 4:
493                                         r_shadow_shadowmappcf = 2;
494                                         break;
495                                 }
496                         }
497                         if (!r_fb.usedepthtextures)
498                                 r_shadow_shadowmapsampler = false;
499                         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D;
500                         break;
501                 case RENDERPATH_D3D9:
502                 case RENDERPATH_D3D10:
503                 case RENDERPATH_D3D11:
504                 case RENDERPATH_SOFT:
505                         r_shadow_shadowmapsampler = false;
506                         r_shadow_shadowmappcf = 1;
507                         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D;
508                         break;
509                 case RENDERPATH_GL11:
510                 case RENDERPATH_GL13:
511                 case RENDERPATH_GLES1:
512                 case RENDERPATH_GLES2:
513                         break;
514                 }
515         }
516
517         if(R_CompileShader_CheckStaticParms())
518                 R_GLSL_Restart_f();
519 }
520
521 qboolean R_Shadow_ShadowMappingEnabled(void)
522 {
523         switch (r_shadow_shadowmode)
524         {
525         case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
526                 return true;
527         default:
528                 return false;
529         }
530 }
531
532 static void R_Shadow_FreeShadowMaps(void)
533 {
534         Mod_AllocLightmap_Free(&r_shadow_shadowmapatlas_state);
535
536         R_Shadow_SetShadowMode();
537
538         R_Mesh_DestroyFramebufferObject(r_shadow_fbo2d);
539
540         r_shadow_fbo2d = 0;
541
542         if (r_shadow_shadowmap2ddepthtexture)
543                 R_FreeTexture(r_shadow_shadowmap2ddepthtexture);
544         r_shadow_shadowmap2ddepthtexture = NULL;
545
546         if (r_shadow_shadowmap2ddepthbuffer)
547                 R_FreeTexture(r_shadow_shadowmap2ddepthbuffer);
548         r_shadow_shadowmap2ddepthbuffer = NULL;
549
550         if (r_shadow_shadowmapvsdcttexture)
551                 R_FreeTexture(r_shadow_shadowmapvsdcttexture);
552         r_shadow_shadowmapvsdcttexture = NULL;
553 }
554
555 static void r_shadow_start(void)
556 {
557         // allocate vertex processing arrays
558         memset(&r_shadow_bouncegrid_state, 0, sizeof(r_shadow_bouncegrid_state));
559         r_shadow_attenuationgradienttexture = NULL;
560         r_shadow_attenuation2dtexture = NULL;
561         r_shadow_attenuation3dtexture = NULL;
562         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_STENCIL;
563         r_shadow_shadowmap2ddepthtexture = NULL;
564         r_shadow_shadowmap2ddepthbuffer = NULL;
565         r_shadow_shadowmapvsdcttexture = NULL;
566         r_shadow_shadowmapmaxsize = 0;
567         r_shadow_shadowmaptexturesize = 0;
568         r_shadow_shadowmapfilterquality = -1;
569         r_shadow_shadowmapdepthbits = 0;
570         r_shadow_shadowmapvsdct = false;
571         r_shadow_shadowmapsampler = false;
572         r_shadow_shadowmappcf = 0;
573         r_shadow_fbo2d = 0;
574
575         R_Shadow_FreeShadowMaps();
576
577         r_shadow_texturepool = NULL;
578         r_shadow_filters_texturepool = NULL;
579         R_Shadow_ValidateCvars();
580         R_Shadow_MakeTextures();
581         r_shadow_scenemaxlights = 0;
582         r_shadow_scenenumlights = 0;
583         r_shadow_scenelightlist = NULL;
584         maxshadowtriangles = 0;
585         shadowelements = NULL;
586         maxshadowvertices = 0;
587         shadowvertex3f = NULL;
588         maxvertexupdate = 0;
589         vertexupdate = NULL;
590         vertexremap = NULL;
591         vertexupdatenum = 0;
592         maxshadowmark = 0;
593         numshadowmark = 0;
594         shadowmark = NULL;
595         shadowmarklist = NULL;
596         shadowmarkcount = 0;
597         maxshadowsides = 0;
598         numshadowsides = 0;
599         shadowsides = NULL;
600         shadowsideslist = NULL;
601         r_shadow_buffer_numleafpvsbytes = 0;
602         r_shadow_buffer_visitingleafpvs = NULL;
603         r_shadow_buffer_leafpvs = NULL;
604         r_shadow_buffer_leaflist = NULL;
605         r_shadow_buffer_numsurfacepvsbytes = 0;
606         r_shadow_buffer_surfacepvs = NULL;
607         r_shadow_buffer_surfacelist = NULL;
608         r_shadow_buffer_surfacesides = NULL;
609         r_shadow_buffer_numshadowtrispvsbytes = 0;
610         r_shadow_buffer_shadowtrispvs = NULL;
611         r_shadow_buffer_numlighttrispvsbytes = 0;
612         r_shadow_buffer_lighttrispvs = NULL;
613
614         r_shadow_usingdeferredprepass = false;
615         r_shadow_prepass_width = r_shadow_prepass_height = 0;
616
617         // determine renderpath specific capabilities, we don't need to figure
618         // these out per frame...
619         switch(vid.renderpath)
620         {
621         case RENDERPATH_GL20:
622                 r_shadow_bouncegrid_state.allowdirectionalshading = true;
623                 r_shadow_bouncegrid_state.capable = vid.support.ext_texture_3d;
624                 break;
625         case RENDERPATH_GLES2:
626                 // for performance reasons, do not use directional shading on GLES devices
627                 r_shadow_bouncegrid_state.capable = vid.support.ext_texture_3d;
628                 break;
629                 // these renderpaths do not currently have the code to display the bouncegrid, so disable it on them...
630         case RENDERPATH_GL11:
631         case RENDERPATH_GL13:
632         case RENDERPATH_GLES1:
633         case RENDERPATH_SOFT:
634         case RENDERPATH_D3D9:
635         case RENDERPATH_D3D10:
636         case RENDERPATH_D3D11:
637                 break;
638         }
639 }
640
641 static void R_Shadow_FreeDeferred(void);
642 static void r_shadow_shutdown(void)
643 {
644         CHECKGLERROR
645         R_Shadow_UncompileWorldLights();
646
647         R_Shadow_FreeShadowMaps();
648
649         r_shadow_usingdeferredprepass = false;
650         if (r_shadow_prepass_width)
651                 R_Shadow_FreeDeferred();
652         r_shadow_prepass_width = r_shadow_prepass_height = 0;
653
654         CHECKGLERROR
655         r_shadow_scenemaxlights = 0;
656         r_shadow_scenenumlights = 0;
657         if (r_shadow_scenelightlist)
658                 Mem_Free(r_shadow_scenelightlist);
659         r_shadow_scenelightlist = NULL;
660         r_shadow_bouncegrid_state.highpixels = NULL;
661         if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
662         if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
663         if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
664         if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
665         if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
666         r_shadow_bouncegrid_state.maxsplatpaths = 0;
667         memset(&r_shadow_bouncegrid_state, 0, sizeof(r_shadow_bouncegrid_state));
668         r_shadow_attenuationgradienttexture = NULL;
669         r_shadow_attenuation2dtexture = NULL;
670         r_shadow_attenuation3dtexture = NULL;
671         R_FreeTexturePool(&r_shadow_texturepool);
672         R_FreeTexturePool(&r_shadow_filters_texturepool);
673         maxshadowtriangles = 0;
674         if (shadowelements)
675                 Mem_Free(shadowelements);
676         shadowelements = NULL;
677         if (shadowvertex3f)
678                 Mem_Free(shadowvertex3f);
679         shadowvertex3f = NULL;
680         maxvertexupdate = 0;
681         if (vertexupdate)
682                 Mem_Free(vertexupdate);
683         vertexupdate = NULL;
684         if (vertexremap)
685                 Mem_Free(vertexremap);
686         vertexremap = NULL;
687         vertexupdatenum = 0;
688         maxshadowmark = 0;
689         numshadowmark = 0;
690         if (shadowmark)
691                 Mem_Free(shadowmark);
692         shadowmark = NULL;
693         if (shadowmarklist)
694                 Mem_Free(shadowmarklist);
695         shadowmarklist = NULL;
696         shadowmarkcount = 0;
697         maxshadowsides = 0;
698         numshadowsides = 0;
699         if (shadowsides)
700                 Mem_Free(shadowsides);
701         shadowsides = NULL;
702         if (shadowsideslist)
703                 Mem_Free(shadowsideslist);
704         shadowsideslist = NULL;
705         r_shadow_buffer_numleafpvsbytes = 0;
706         if (r_shadow_buffer_visitingleafpvs)
707                 Mem_Free(r_shadow_buffer_visitingleafpvs);
708         r_shadow_buffer_visitingleafpvs = NULL;
709         if (r_shadow_buffer_leafpvs)
710                 Mem_Free(r_shadow_buffer_leafpvs);
711         r_shadow_buffer_leafpvs = NULL;
712         if (r_shadow_buffer_leaflist)
713                 Mem_Free(r_shadow_buffer_leaflist);
714         r_shadow_buffer_leaflist = NULL;
715         r_shadow_buffer_numsurfacepvsbytes = 0;
716         if (r_shadow_buffer_surfacepvs)
717                 Mem_Free(r_shadow_buffer_surfacepvs);
718         r_shadow_buffer_surfacepvs = NULL;
719         if (r_shadow_buffer_surfacelist)
720                 Mem_Free(r_shadow_buffer_surfacelist);
721         r_shadow_buffer_surfacelist = NULL;
722         if (r_shadow_buffer_surfacesides)
723                 Mem_Free(r_shadow_buffer_surfacesides);
724         r_shadow_buffer_surfacesides = NULL;
725         r_shadow_buffer_numshadowtrispvsbytes = 0;
726         if (r_shadow_buffer_shadowtrispvs)
727                 Mem_Free(r_shadow_buffer_shadowtrispvs);
728         r_shadow_buffer_numlighttrispvsbytes = 0;
729         if (r_shadow_buffer_lighttrispvs)
730                 Mem_Free(r_shadow_buffer_lighttrispvs);
731 }
732
733 static void r_shadow_newmap(void)
734 {
735         r_shadow_bouncegrid_state.highpixels = NULL;
736         if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
737         if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
738         if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
739         if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
740         if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
741         r_shadow_bouncegrid_state.maxsplatpaths = 0;
742         if (r_shadow_bouncegrid_state.texture)    R_FreeTexture(r_shadow_bouncegrid_state.texture);r_shadow_bouncegrid_state.texture = NULL;
743         if (r_shadow_lightcorona)                 R_SkinFrame_MarkUsed(r_shadow_lightcorona);
744         if (r_editlights_sprcursor)               R_SkinFrame_MarkUsed(r_editlights_sprcursor);
745         if (r_editlights_sprlight)                R_SkinFrame_MarkUsed(r_editlights_sprlight);
746         if (r_editlights_sprnoshadowlight)        R_SkinFrame_MarkUsed(r_editlights_sprnoshadowlight);
747         if (r_editlights_sprcubemaplight)         R_SkinFrame_MarkUsed(r_editlights_sprcubemaplight);
748         if (r_editlights_sprcubemapnoshadowlight) R_SkinFrame_MarkUsed(r_editlights_sprcubemapnoshadowlight);
749         if (r_editlights_sprselection)            R_SkinFrame_MarkUsed(r_editlights_sprselection);
750         if (strncmp(cl.worldname, r_shadow_mapname, sizeof(r_shadow_mapname)))
751                 R_Shadow_EditLights_Reload_f();
752 }
753
754 void R_Shadow_Init(void)
755 {
756         Cvar_RegisterVariable(&r_shadow_bumpscale_basetexture);
757         Cvar_RegisterVariable(&r_shadow_bumpscale_bumpmap);
758         Cvar_RegisterVariable(&r_shadow_usebihculling);
759         Cvar_RegisterVariable(&r_shadow_usenormalmap);
760         Cvar_RegisterVariable(&r_shadow_debuglight);
761         Cvar_RegisterVariable(&r_shadow_deferred);
762         Cvar_RegisterVariable(&r_shadow_gloss);
763         Cvar_RegisterVariable(&r_shadow_gloss2intensity);
764         Cvar_RegisterVariable(&r_shadow_glossintensity);
765         Cvar_RegisterVariable(&r_shadow_glossexponent);
766         Cvar_RegisterVariable(&r_shadow_gloss2exponent);
767         Cvar_RegisterVariable(&r_shadow_glossexact);
768         Cvar_RegisterVariable(&r_shadow_lightattenuationdividebias);
769         Cvar_RegisterVariable(&r_shadow_lightattenuationlinearscale);
770         Cvar_RegisterVariable(&r_shadow_lightintensityscale);
771         Cvar_RegisterVariable(&r_shadow_lightradiusscale);
772         Cvar_RegisterVariable(&r_shadow_projectdistance);
773         Cvar_RegisterVariable(&r_shadow_frontsidecasting);
774         Cvar_RegisterVariable(&r_shadow_realtime_world_importlightentitiesfrommap);
775         Cvar_RegisterVariable(&r_shadow_realtime_dlight);
776         Cvar_RegisterVariable(&r_shadow_realtime_dlight_shadows);
777         Cvar_RegisterVariable(&r_shadow_realtime_dlight_svbspculling);
778         Cvar_RegisterVariable(&r_shadow_realtime_dlight_portalculling);
779         Cvar_RegisterVariable(&r_shadow_realtime_world);
780         Cvar_RegisterVariable(&r_shadow_realtime_world_lightmaps);
781         Cvar_RegisterVariable(&r_shadow_realtime_world_shadows);
782         Cvar_RegisterVariable(&r_shadow_realtime_world_compile);
783         Cvar_RegisterVariable(&r_shadow_realtime_world_compileshadow);
784         Cvar_RegisterVariable(&r_shadow_realtime_world_compilesvbsp);
785         Cvar_RegisterVariable(&r_shadow_realtime_world_compileportalculling);
786         Cvar_RegisterVariable(&r_shadow_scissor);
787         Cvar_RegisterVariable(&r_shadow_shadowmapping);
788         Cvar_RegisterVariable(&r_shadow_shadowmapping_vsdct);
789         Cvar_RegisterVariable(&r_shadow_shadowmapping_filterquality);
790         Cvar_RegisterVariable(&r_shadow_shadowmapping_useshadowsampler);
791         Cvar_RegisterVariable(&r_shadow_shadowmapping_depthbits);
792         Cvar_RegisterVariable(&r_shadow_shadowmapping_precision);
793         Cvar_RegisterVariable(&r_shadow_shadowmapping_maxsize);
794         Cvar_RegisterVariable(&r_shadow_shadowmapping_minsize);
795         Cvar_RegisterVariable(&r_shadow_shadowmapping_texturesize);
796 //      Cvar_RegisterVariable(&r_shadow_shadowmapping_lod_bias);
797 //      Cvar_RegisterVariable(&r_shadow_shadowmapping_lod_scale);
798         Cvar_RegisterVariable(&r_shadow_shadowmapping_bordersize);
799         Cvar_RegisterVariable(&r_shadow_shadowmapping_nearclip);
800         Cvar_RegisterVariable(&r_shadow_shadowmapping_bias);
801         Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonfactor);
802         Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonoffset);
803         Cvar_RegisterVariable(&r_shadow_sortsurfaces);
804         Cvar_RegisterVariable(&r_shadow_polygonfactor);
805         Cvar_RegisterVariable(&r_shadow_polygonoffset);
806         Cvar_RegisterVariable(&r_shadow_texture3d);
807         Cvar_RegisterVariable(&r_shadow_bouncegrid);
808         Cvar_RegisterVariable(&r_shadow_bouncegrid_blur);
809         Cvar_RegisterVariable(&r_shadow_bouncegrid_bounceanglediffuse);
810         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_bounceminimumintensity);
811         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_culllightpaths);
812         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_directionalshading);
813         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_dlightparticlemultiplier);
814         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_hitmodels);
815         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_lightradiusscale);
816         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_maxbounce);
817         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_maxphotons);
818         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_quality);
819         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_spacing);
820         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_updateinterval);
821         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_x);
822         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_y);
823         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_z);
824         Cvar_RegisterVariable(&r_shadow_bouncegrid_floatcolors);
825         Cvar_RegisterVariable(&r_shadow_bouncegrid_includedirectlighting);
826         Cvar_RegisterVariable(&r_shadow_bouncegrid_intensity);
827         Cvar_RegisterVariable(&r_shadow_bouncegrid_lightpathsize_conespread);
828         Cvar_RegisterVariable(&r_shadow_bouncegrid_lightpathsize_initial);
829         Cvar_RegisterVariable(&r_shadow_bouncegrid_normalizevectors);
830         Cvar_RegisterVariable(&r_shadow_bouncegrid_particlebounceintensity);
831         Cvar_RegisterVariable(&r_shadow_bouncegrid_particleintensity);
832         Cvar_RegisterVariable(&r_shadow_bouncegrid_rng_seed);
833         Cvar_RegisterVariable(&r_shadow_bouncegrid_rng_type);
834         Cvar_RegisterVariable(&r_shadow_bouncegrid_sortlightpaths);
835         Cvar_RegisterVariable(&r_shadow_bouncegrid_static);
836         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_bounceminimumintensity);
837         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_directionalshading);
838         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_lightradiusscale);
839         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxbounce);
840         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxphotons);
841         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_quality);
842         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_spacing);
843         Cvar_RegisterVariable(&r_coronas);
844         Cvar_RegisterVariable(&r_coronas_occlusionsizescale);
845         Cvar_RegisterVariable(&r_coronas_occlusionquery);
846         Cvar_RegisterVariable(&gl_flashblend);
847         Cvar_RegisterVariable(&gl_ext_separatestencil);
848         Cvar_RegisterVariable(&gl_ext_stenciltwoside);
849         R_Shadow_EditLights_Init();
850         Mem_ExpandableArray_NewArray(&r_shadow_worldlightsarray, r_main_mempool, sizeof(dlight_t), 128);
851         r_shadow_scenemaxlights = 0;
852         r_shadow_scenenumlights = 0;
853         r_shadow_scenelightlist = NULL;
854         maxshadowtriangles = 0;
855         shadowelements = NULL;
856         maxshadowvertices = 0;
857         shadowvertex3f = NULL;
858         maxvertexupdate = 0;
859         vertexupdate = NULL;
860         vertexremap = NULL;
861         vertexupdatenum = 0;
862         maxshadowmark = 0;
863         numshadowmark = 0;
864         shadowmark = NULL;
865         shadowmarklist = NULL;
866         shadowmarkcount = 0;
867         maxshadowsides = 0;
868         numshadowsides = 0;
869         shadowsides = NULL;
870         shadowsideslist = NULL;
871         r_shadow_buffer_numleafpvsbytes = 0;
872         r_shadow_buffer_visitingleafpvs = NULL;
873         r_shadow_buffer_leafpvs = NULL;
874         r_shadow_buffer_leaflist = NULL;
875         r_shadow_buffer_numsurfacepvsbytes = 0;
876         r_shadow_buffer_surfacepvs = NULL;
877         r_shadow_buffer_surfacelist = NULL;
878         r_shadow_buffer_surfacesides = NULL;
879         r_shadow_buffer_shadowtrispvs = NULL;
880         r_shadow_buffer_lighttrispvs = NULL;
881         R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap, NULL, NULL);
882 }
883
884 matrix4x4_t matrix_attenuationxyz =
885 {
886         {
887                 {0.5, 0.0, 0.0, 0.5},
888                 {0.0, 0.5, 0.0, 0.5},
889                 {0.0, 0.0, 0.5, 0.5},
890                 {0.0, 0.0, 0.0, 1.0}
891         }
892 };
893
894 matrix4x4_t matrix_attenuationz =
895 {
896         {
897                 {0.0, 0.0, 0.5, 0.5},
898                 {0.0, 0.0, 0.0, 0.5},
899                 {0.0, 0.0, 0.0, 0.5},
900                 {0.0, 0.0, 0.0, 1.0}
901         }
902 };
903
904 static void R_Shadow_ResizeShadowArrays(int numvertices, int numtriangles, int vertscale, int triscale)
905 {
906         numvertices = ((numvertices + 255) & ~255) * vertscale;
907         numtriangles = ((numtriangles + 255) & ~255) * triscale;
908         // make sure shadowelements is big enough for this volume
909         if (maxshadowtriangles < numtriangles)
910         {
911                 maxshadowtriangles = numtriangles;
912                 if (shadowelements)
913                         Mem_Free(shadowelements);
914                 shadowelements = (int *)Mem_Alloc(r_main_mempool, maxshadowtriangles * sizeof(int[3]));
915         }
916         // make sure shadowvertex3f is big enough for this volume
917         if (maxshadowvertices < numvertices)
918         {
919                 maxshadowvertices = numvertices;
920                 if (shadowvertex3f)
921                         Mem_Free(shadowvertex3f);
922                 shadowvertex3f = (float *)Mem_Alloc(r_main_mempool, maxshadowvertices * sizeof(float[3]));
923         }
924 }
925
926 static void R_Shadow_EnlargeLeafSurfaceTrisBuffer(int numleafs, int numsurfaces, int numshadowtriangles, int numlighttriangles)
927 {
928         int numleafpvsbytes = (((numleafs + 7) >> 3) + 255) & ~255;
929         int numsurfacepvsbytes = (((numsurfaces + 7) >> 3) + 255) & ~255;
930         int numshadowtrispvsbytes = (((numshadowtriangles + 7) >> 3) + 255) & ~255;
931         int numlighttrispvsbytes = (((numlighttriangles + 7) >> 3) + 255) & ~255;
932         if (r_shadow_buffer_numleafpvsbytes < numleafpvsbytes)
933         {
934                 if (r_shadow_buffer_visitingleafpvs)
935                         Mem_Free(r_shadow_buffer_visitingleafpvs);
936                 if (r_shadow_buffer_leafpvs)
937                         Mem_Free(r_shadow_buffer_leafpvs);
938                 if (r_shadow_buffer_leaflist)
939                         Mem_Free(r_shadow_buffer_leaflist);
940                 r_shadow_buffer_numleafpvsbytes = numleafpvsbytes;
941                 r_shadow_buffer_visitingleafpvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes);
942                 r_shadow_buffer_leafpvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes);
943                 r_shadow_buffer_leaflist = (int *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes * 8 * sizeof(*r_shadow_buffer_leaflist));
944         }
945         if (r_shadow_buffer_numsurfacepvsbytes < numsurfacepvsbytes)
946         {
947                 if (r_shadow_buffer_surfacepvs)
948                         Mem_Free(r_shadow_buffer_surfacepvs);
949                 if (r_shadow_buffer_surfacelist)
950                         Mem_Free(r_shadow_buffer_surfacelist);
951                 if (r_shadow_buffer_surfacesides)
952                         Mem_Free(r_shadow_buffer_surfacesides);
953                 r_shadow_buffer_numsurfacepvsbytes = numsurfacepvsbytes;
954                 r_shadow_buffer_surfacepvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numsurfacepvsbytes);
955                 r_shadow_buffer_surfacelist = (int *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numsurfacepvsbytes * 8 * sizeof(*r_shadow_buffer_surfacelist));
956                 r_shadow_buffer_surfacesides = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numsurfacepvsbytes * 8 * sizeof(*r_shadow_buffer_surfacelist));
957         }
958         if (r_shadow_buffer_numshadowtrispvsbytes < numshadowtrispvsbytes)
959         {
960                 if (r_shadow_buffer_shadowtrispvs)
961                         Mem_Free(r_shadow_buffer_shadowtrispvs);
962                 r_shadow_buffer_numshadowtrispvsbytes = numshadowtrispvsbytes;
963                 r_shadow_buffer_shadowtrispvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numshadowtrispvsbytes);
964         }
965         if (r_shadow_buffer_numlighttrispvsbytes < numlighttrispvsbytes)
966         {
967                 if (r_shadow_buffer_lighttrispvs)
968                         Mem_Free(r_shadow_buffer_lighttrispvs);
969                 r_shadow_buffer_numlighttrispvsbytes = numlighttrispvsbytes;
970                 r_shadow_buffer_lighttrispvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numlighttrispvsbytes);
971         }
972 }
973
974 void R_Shadow_PrepareShadowMark(int numtris)
975 {
976         // make sure shadowmark is big enough for this volume
977         if (maxshadowmark < numtris)
978         {
979                 maxshadowmark = numtris;
980                 if (shadowmark)
981                         Mem_Free(shadowmark);
982                 if (shadowmarklist)
983                         Mem_Free(shadowmarklist);
984                 shadowmark = (int *)Mem_Alloc(r_main_mempool, maxshadowmark * sizeof(*shadowmark));
985                 shadowmarklist = (int *)Mem_Alloc(r_main_mempool, maxshadowmark * sizeof(*shadowmarklist));
986                 shadowmarkcount = 0;
987         }
988         shadowmarkcount++;
989         // if shadowmarkcount wrapped we clear the array and adjust accordingly
990         if (shadowmarkcount == 0)
991         {
992                 shadowmarkcount = 1;
993                 memset(shadowmark, 0, maxshadowmark * sizeof(*shadowmark));
994         }
995         numshadowmark = 0;
996 }
997
998 void R_Shadow_PrepareShadowSides(int numtris)
999 {
1000         if (maxshadowsides < numtris)
1001         {
1002                 maxshadowsides = numtris;
1003                 if (shadowsides)
1004                         Mem_Free(shadowsides);
1005                 if (shadowsideslist)
1006                         Mem_Free(shadowsideslist);
1007                 shadowsides = (unsigned char *)Mem_Alloc(r_main_mempool, maxshadowsides * sizeof(*shadowsides));
1008                 shadowsideslist = (int *)Mem_Alloc(r_main_mempool, maxshadowsides * sizeof(*shadowsideslist));
1009         }
1010         numshadowsides = 0;
1011 }
1012
1013 static int R_Shadow_ConstructShadowVolume_ZFail(int innumvertices, int innumtris, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *projectorigin, const float *projectdirection, float projectdistance, int numshadowmarktris, const int *shadowmarktris)
1014 {
1015         int i, j;
1016         int outtriangles = 0, outvertices = 0;
1017         const int *element;
1018         const float *vertex;
1019         float ratio, direction[3], projectvector[3];
1020
1021         if (projectdirection)
1022                 VectorScale(projectdirection, projectdistance, projectvector);
1023         else
1024                 VectorClear(projectvector);
1025
1026         // create the vertices
1027         if (projectdirection)
1028         {
1029                 for (i = 0;i < numshadowmarktris;i++)
1030                 {
1031                         element = inelement3i + shadowmarktris[i] * 3;
1032                         for (j = 0;j < 3;j++)
1033                         {
1034                                 if (vertexupdate[element[j]] != vertexupdatenum)
1035                                 {
1036                                         vertexupdate[element[j]] = vertexupdatenum;
1037                                         vertexremap[element[j]] = outvertices;
1038                                         vertex = invertex3f + element[j] * 3;
1039                                         // project one copy of the vertex according to projectvector
1040                                         VectorCopy(vertex, outvertex3f);
1041                                         VectorAdd(vertex, projectvector, (outvertex3f + 3));
1042                                         outvertex3f += 6;
1043                                         outvertices += 2;
1044                                 }
1045                         }
1046                 }
1047         }
1048         else
1049         {
1050                 for (i = 0;i < numshadowmarktris;i++)
1051                 {
1052                         element = inelement3i + shadowmarktris[i] * 3;
1053                         for (j = 0;j < 3;j++)
1054                         {
1055                                 if (vertexupdate[element[j]] != vertexupdatenum)
1056                                 {
1057                                         vertexupdate[element[j]] = vertexupdatenum;
1058                                         vertexremap[element[j]] = outvertices;
1059                                         vertex = invertex3f + element[j] * 3;
1060                                         // project one copy of the vertex to the sphere radius of the light
1061                                         // (FIXME: would projecting it to the light box be better?)
1062                                         VectorSubtract(vertex, projectorigin, direction);
1063                                         ratio = projectdistance / VectorLength(direction);
1064                                         VectorCopy(vertex, outvertex3f);
1065                                         VectorMA(projectorigin, ratio, direction, (outvertex3f + 3));
1066                                         outvertex3f += 6;
1067                                         outvertices += 2;
1068                                 }
1069                         }
1070                 }
1071         }
1072
1073         if (r_shadow_frontsidecasting.integer)
1074         {
1075                 for (i = 0;i < numshadowmarktris;i++)
1076                 {
1077                         int remappedelement[3];
1078                         int markindex;
1079                         const int *neighbortriangle;
1080
1081                         markindex = shadowmarktris[i] * 3;
1082                         element = inelement3i + markindex;
1083                         neighbortriangle = inneighbor3i + markindex;
1084                         // output the front and back triangles
1085                         outelement3i[0] = vertexremap[element[0]];
1086                         outelement3i[1] = vertexremap[element[1]];
1087                         outelement3i[2] = vertexremap[element[2]];
1088                         outelement3i[3] = vertexremap[element[2]] + 1;
1089                         outelement3i[4] = vertexremap[element[1]] + 1;
1090                         outelement3i[5] = vertexremap[element[0]] + 1;
1091
1092                         outelement3i += 6;
1093                         outtriangles += 2;
1094                         // output the sides (facing outward from this triangle)
1095                         if (shadowmark[neighbortriangle[0]] != shadowmarkcount)
1096                         {
1097                                 remappedelement[0] = vertexremap[element[0]];
1098                                 remappedelement[1] = vertexremap[element[1]];
1099                                 outelement3i[0] = remappedelement[1];
1100                                 outelement3i[1] = remappedelement[0];
1101                                 outelement3i[2] = remappedelement[0] + 1;
1102                                 outelement3i[3] = remappedelement[1];
1103                                 outelement3i[4] = remappedelement[0] + 1;
1104                                 outelement3i[5] = remappedelement[1] + 1;
1105
1106                                 outelement3i += 6;
1107                                 outtriangles += 2;
1108                         }
1109                         if (shadowmark[neighbortriangle[1]] != shadowmarkcount)
1110                         {
1111                                 remappedelement[1] = vertexremap[element[1]];
1112                                 remappedelement[2] = vertexremap[element[2]];
1113                                 outelement3i[0] = remappedelement[2];
1114                                 outelement3i[1] = remappedelement[1];
1115                                 outelement3i[2] = remappedelement[1] + 1;
1116                                 outelement3i[3] = remappedelement[2];
1117                                 outelement3i[4] = remappedelement[1] + 1;
1118                                 outelement3i[5] = remappedelement[2] + 1;
1119
1120                                 outelement3i += 6;
1121                                 outtriangles += 2;
1122                         }
1123                         if (shadowmark[neighbortriangle[2]] != shadowmarkcount)
1124                         {
1125                                 remappedelement[0] = vertexremap[element[0]];
1126                                 remappedelement[2] = vertexremap[element[2]];
1127                                 outelement3i[0] = remappedelement[0];
1128                                 outelement3i[1] = remappedelement[2];
1129                                 outelement3i[2] = remappedelement[2] + 1;
1130                                 outelement3i[3] = remappedelement[0];
1131                                 outelement3i[4] = remappedelement[2] + 1;
1132                                 outelement3i[5] = remappedelement[0] + 1;
1133
1134                                 outelement3i += 6;
1135                                 outtriangles += 2;
1136                         }
1137                 }
1138         }
1139         else
1140         {
1141                 for (i = 0;i < numshadowmarktris;i++)
1142                 {
1143                         int remappedelement[3];
1144                         int markindex;
1145                         const int *neighbortriangle;
1146
1147                         markindex = shadowmarktris[i] * 3;
1148                         element = inelement3i + markindex;
1149                         neighbortriangle = inneighbor3i + markindex;
1150                         // output the front and back triangles
1151                         outelement3i[0] = vertexremap[element[2]];
1152                         outelement3i[1] = vertexremap[element[1]];
1153                         outelement3i[2] = vertexremap[element[0]];
1154                         outelement3i[3] = vertexremap[element[0]] + 1;
1155                         outelement3i[4] = vertexremap[element[1]] + 1;
1156                         outelement3i[5] = vertexremap[element[2]] + 1;
1157
1158                         outelement3i += 6;
1159                         outtriangles += 2;
1160                         // output the sides (facing outward from this triangle)
1161                         if (shadowmark[neighbortriangle[0]] != shadowmarkcount)
1162                         {
1163                                 remappedelement[0] = vertexremap[element[0]];
1164                                 remappedelement[1] = vertexremap[element[1]];
1165                                 outelement3i[0] = remappedelement[0];
1166                                 outelement3i[1] = remappedelement[1];
1167                                 outelement3i[2] = remappedelement[1] + 1;
1168                                 outelement3i[3] = remappedelement[0];
1169                                 outelement3i[4] = remappedelement[1] + 1;
1170                                 outelement3i[5] = remappedelement[0] + 1;
1171
1172                                 outelement3i += 6;
1173                                 outtriangles += 2;
1174                         }
1175                         if (shadowmark[neighbortriangle[1]] != shadowmarkcount)
1176                         {
1177                                 remappedelement[1] = vertexremap[element[1]];
1178                                 remappedelement[2] = vertexremap[element[2]];
1179                                 outelement3i[0] = remappedelement[1];
1180                                 outelement3i[1] = remappedelement[2];
1181                                 outelement3i[2] = remappedelement[2] + 1;
1182                                 outelement3i[3] = remappedelement[1];
1183                                 outelement3i[4] = remappedelement[2] + 1;
1184                                 outelement3i[5] = remappedelement[1] + 1;
1185
1186                                 outelement3i += 6;
1187                                 outtriangles += 2;
1188                         }
1189                         if (shadowmark[neighbortriangle[2]] != shadowmarkcount)
1190                         {
1191                                 remappedelement[0] = vertexremap[element[0]];
1192                                 remappedelement[2] = vertexremap[element[2]];
1193                                 outelement3i[0] = remappedelement[2];
1194                                 outelement3i[1] = remappedelement[0];
1195                                 outelement3i[2] = remappedelement[0] + 1;
1196                                 outelement3i[3] = remappedelement[2];
1197                                 outelement3i[4] = remappedelement[0] + 1;
1198                                 outelement3i[5] = remappedelement[2] + 1;
1199
1200                                 outelement3i += 6;
1201                                 outtriangles += 2;
1202                         }
1203                 }
1204         }
1205         if (outnumvertices)
1206                 *outnumvertices = outvertices;
1207         return outtriangles;
1208 }
1209
1210 static int R_Shadow_ConstructShadowVolume_ZPass(int innumvertices, int innumtris, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *projectorigin, const float *projectdirection, float projectdistance, int numshadowmarktris, const int *shadowmarktris)
1211 {
1212         int i, j, k;
1213         int outtriangles = 0, outvertices = 0;
1214         const int *element;
1215         const float *vertex;
1216         float ratio, direction[3], projectvector[3];
1217         qboolean side[4];
1218
1219         if (projectdirection)
1220                 VectorScale(projectdirection, projectdistance, projectvector);
1221         else
1222                 VectorClear(projectvector);
1223
1224         for (i = 0;i < numshadowmarktris;i++)
1225         {
1226                 int remappedelement[3];
1227                 int markindex;
1228                 const int *neighbortriangle;
1229
1230                 markindex = shadowmarktris[i] * 3;
1231                 neighbortriangle = inneighbor3i + markindex;
1232                 side[0] = shadowmark[neighbortriangle[0]] == shadowmarkcount;
1233                 side[1] = shadowmark[neighbortriangle[1]] == shadowmarkcount;
1234                 side[2] = shadowmark[neighbortriangle[2]] == shadowmarkcount;
1235                 if (side[0] + side[1] + side[2] == 0)
1236                         continue;
1237
1238                 side[3] = side[0];
1239                 element = inelement3i + markindex;
1240
1241                 // create the vertices
1242                 for (j = 0;j < 3;j++)
1243                 {
1244                         if (side[j] + side[j+1] == 0)
1245                                 continue;
1246                         k = element[j];
1247                         if (vertexupdate[k] != vertexupdatenum)
1248                         {
1249                                 vertexupdate[k] = vertexupdatenum;
1250                                 vertexremap[k] = outvertices;
1251                                 vertex = invertex3f + k * 3;
1252                                 VectorCopy(vertex, outvertex3f);
1253                                 if (projectdirection)
1254                                 {
1255                                         // project one copy of the vertex according to projectvector
1256                                         VectorAdd(vertex, projectvector, (outvertex3f + 3));
1257                                 }
1258                                 else
1259                                 {
1260                                         // project one copy of the vertex to the sphere radius of the light
1261                                         // (FIXME: would projecting it to the light box be better?)
1262                                         VectorSubtract(vertex, projectorigin, direction);
1263                                         ratio = projectdistance / VectorLength(direction);
1264                                         VectorMA(projectorigin, ratio, direction, (outvertex3f + 3));
1265                                 }
1266                                 outvertex3f += 6;
1267                                 outvertices += 2;
1268                         }
1269                 }
1270
1271                 // output the sides (facing outward from this triangle)
1272                 if (!side[0])
1273                 {
1274                         remappedelement[0] = vertexremap[element[0]];
1275                         remappedelement[1] = vertexremap[element[1]];
1276                         outelement3i[0] = remappedelement[1];
1277                         outelement3i[1] = remappedelement[0];
1278                         outelement3i[2] = remappedelement[0] + 1;
1279                         outelement3i[3] = remappedelement[1];
1280                         outelement3i[4] = remappedelement[0] + 1;
1281                         outelement3i[5] = remappedelement[1] + 1;
1282
1283                         outelement3i += 6;
1284                         outtriangles += 2;
1285                 }
1286                 if (!side[1])
1287                 {
1288                         remappedelement[1] = vertexremap[element[1]];
1289                         remappedelement[2] = vertexremap[element[2]];
1290                         outelement3i[0] = remappedelement[2];
1291                         outelement3i[1] = remappedelement[1];
1292                         outelement3i[2] = remappedelement[1] + 1;
1293                         outelement3i[3] = remappedelement[2];
1294                         outelement3i[4] = remappedelement[1] + 1;
1295                         outelement3i[5] = remappedelement[2] + 1;
1296
1297                         outelement3i += 6;
1298                         outtriangles += 2;
1299                 }
1300                 if (!side[2])
1301                 {
1302                         remappedelement[0] = vertexremap[element[0]];
1303                         remappedelement[2] = vertexremap[element[2]];
1304                         outelement3i[0] = remappedelement[0];
1305                         outelement3i[1] = remappedelement[2];
1306                         outelement3i[2] = remappedelement[2] + 1;
1307                         outelement3i[3] = remappedelement[0];
1308                         outelement3i[4] = remappedelement[2] + 1;
1309                         outelement3i[5] = remappedelement[0] + 1;
1310
1311                         outelement3i += 6;
1312                         outtriangles += 2;
1313                 }
1314         }
1315         if (outnumvertices)
1316                 *outnumvertices = outvertices;
1317         return outtriangles;
1318 }
1319
1320 void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs)
1321 {
1322         int t, tend;
1323         const int *e;
1324         const float *v[3];
1325         float normal[3];
1326         if (!BoxesOverlap(lightmins, lightmaxs, surfacemins, surfacemaxs))
1327                 return;
1328         tend = firsttriangle + numtris;
1329         if (BoxInsideBox(surfacemins, surfacemaxs, lightmins, lightmaxs))
1330         {
1331                 // surface box entirely inside light box, no box cull
1332                 if (projectdirection)
1333                 {
1334                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1335                         {
1336                                 TriangleNormal(invertex3f + e[0] * 3, invertex3f + e[1] * 3, invertex3f + e[2] * 3, normal);
1337                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0))
1338                                         shadowmarklist[numshadowmark++] = t;
1339                         }
1340                 }
1341                 else
1342                 {
1343                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1344                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, invertex3f + e[0] * 3, invertex3f + e[1] * 3, invertex3f + e[2] * 3))
1345                                         shadowmarklist[numshadowmark++] = t;
1346                 }
1347         }
1348         else
1349         {
1350                 // surface box not entirely inside light box, cull each triangle
1351                 if (projectdirection)
1352                 {
1353                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1354                         {
1355                                 v[0] = invertex3f + e[0] * 3;
1356                                 v[1] = invertex3f + e[1] * 3;
1357                                 v[2] = invertex3f + e[2] * 3;
1358                                 TriangleNormal(v[0], v[1], v[2], normal);
1359                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0)
1360                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1361                                         shadowmarklist[numshadowmark++] = t;
1362                         }
1363                 }
1364                 else
1365                 {
1366                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1367                         {
1368                                 v[0] = invertex3f + e[0] * 3;
1369                                 v[1] = invertex3f + e[1] * 3;
1370                                 v[2] = invertex3f + e[2] * 3;
1371                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2])
1372                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1373                                         shadowmarklist[numshadowmark++] = t;
1374                         }
1375                 }
1376         }
1377 }
1378
1379 static qboolean R_Shadow_UseZPass(vec3_t mins, vec3_t maxs)
1380 {
1381 #if 1
1382         return false;
1383 #else
1384         if (r_shadow_compilingrtlight || !r_shadow_frontsidecasting.integer || !r_shadow_usezpassifpossible.integer)
1385                 return false;
1386         // check if the shadow volume intersects the near plane
1387         //
1388         // a ray between the eye and light origin may intersect the caster,
1389         // indicating that the shadow may touch the eye location, however we must
1390         // test the near plane (a polygon), not merely the eye location, so it is
1391         // easiest to enlarge the caster bounding shape slightly for this.
1392         // TODO
1393         return true;
1394 #endif
1395 }
1396
1397 void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris, vec3_t trismins, vec3_t trismaxs)
1398 {
1399         int i, tris, outverts;
1400         if (projectdistance < 0.1)
1401         {
1402                 Con_Printf("R_Shadow_Volume: projectdistance %f\n", projectdistance);
1403                 return;
1404         }
1405         if (!numverts || !nummarktris)
1406                 return;
1407         // make sure shadowelements is big enough for this volume
1408         if (maxshadowtriangles < nummarktris*8 || maxshadowvertices < numverts*2)
1409                 R_Shadow_ResizeShadowArrays(numverts, nummarktris, 2, 8);
1410
1411         if (maxvertexupdate < numverts)
1412         {
1413                 maxvertexupdate = numverts;
1414                 if (vertexupdate)
1415                         Mem_Free(vertexupdate);
1416                 if (vertexremap)
1417                         Mem_Free(vertexremap);
1418                 vertexupdate = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
1419                 vertexremap = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
1420                 vertexupdatenum = 0;
1421         }
1422         vertexupdatenum++;
1423         if (vertexupdatenum == 0)
1424         {
1425                 vertexupdatenum = 1;
1426                 memset(vertexupdate, 0, maxvertexupdate * sizeof(int));
1427                 memset(vertexremap, 0, maxvertexupdate * sizeof(int));
1428         }
1429
1430         for (i = 0;i < nummarktris;i++)
1431                 shadowmark[marktris[i]] = shadowmarkcount;
1432
1433         if (r_shadow_compilingrtlight)
1434         {
1435                 // if we're compiling an rtlight, capture the mesh
1436                 //tris = R_Shadow_ConstructShadowVolume_ZPass(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1437                 //Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_zpass, NULL, NULL, NULL, shadowvertex3f, NULL, NULL, NULL, NULL, tris, shadowelements);
1438                 tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1439                 Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_zfail, NULL, NULL, NULL, shadowvertex3f, NULL, NULL, NULL, NULL, tris, shadowelements);
1440         }
1441         else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_VISIBLEVOLUMES)
1442         {
1443                 tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1444                 R_Mesh_PrepareVertices_Vertex3f(outverts, shadowvertex3f, NULL, 0);
1445                 R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1446         }
1447         else
1448         {
1449                 // decide which type of shadow to generate and set stencil mode
1450                 R_Shadow_RenderMode_StencilShadowVolumes(R_Shadow_UseZPass(trismins, trismaxs));
1451                 // generate the sides or a solid volume, depending on type
1452                 if (r_shadow_rendermode >= R_SHADOW_RENDERMODE_ZPASS_STENCIL && r_shadow_rendermode <= R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE)
1453                         tris = R_Shadow_ConstructShadowVolume_ZPass(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1454                 else
1455                         tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1456                 r_refdef.stats[r_stat_lights_dynamicshadowtriangles] += tris;
1457                 r_refdef.stats[r_stat_lights_shadowtriangles] += tris;
1458                 if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL)
1459                 {
1460                         // increment stencil if frontface is infront of depthbuffer
1461                         GL_CullFace(r_refdef.view.cullface_front);
1462                         R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_DECR, GL_ALWAYS, 128, 255);
1463                         R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1464                         // decrement stencil if backface is infront of depthbuffer
1465                         GL_CullFace(r_refdef.view.cullface_back);
1466                         R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_INCR, GL_ALWAYS, 128, 255);
1467                 }
1468                 else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZFAIL_STENCIL)
1469                 {
1470                         // decrement stencil if backface is behind depthbuffer
1471                         GL_CullFace(r_refdef.view.cullface_front);
1472                         R_SetStencil(true, 255, GL_KEEP, GL_DECR, GL_KEEP, GL_ALWAYS, 128, 255);
1473                         R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1474                         // increment stencil if frontface is behind depthbuffer
1475                         GL_CullFace(r_refdef.view.cullface_back);
1476                         R_SetStencil(true, 255, GL_KEEP, GL_INCR, GL_KEEP, GL_ALWAYS, 128, 255);
1477                 }
1478                 R_Mesh_PrepareVertices_Vertex3f(outverts, shadowvertex3f, NULL, 0);
1479                 R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1480         }
1481 }
1482
1483 int R_Shadow_CalcTriangleSideMask(const vec3_t p1, const vec3_t p2, const vec3_t p3, float bias)
1484 {
1485         // p1, p2, p3 are in the cubemap's local coordinate system
1486         // bias = border/(size - border)
1487         int mask = 0x3F;
1488
1489         float dp1 = p1[0] + p1[1], dn1 = p1[0] - p1[1], ap1 = fabs(dp1), an1 = fabs(dn1),
1490                   dp2 = p2[0] + p2[1], dn2 = p2[0] - p2[1], ap2 = fabs(dp2), an2 = fabs(dn2),
1491                   dp3 = p3[0] + p3[1], dn3 = p3[0] - p3[1], ap3 = fabs(dp3), an3 = fabs(dn3);
1492         if(ap1 > bias*an1 && ap2 > bias*an2 && ap3 > bias*an3)
1493                 mask &= (3<<4)
1494                         | (dp1 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2))
1495                         | (dp2 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2))
1496                         | (dp3 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1497         if(an1 > bias*ap1 && an2 > bias*ap2 && an3 > bias*ap3)
1498                 mask &= (3<<4)
1499                         | (dn1 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2))
1500                         | (dn2 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2))                    
1501                         | (dn3 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1502
1503         dp1 = p1[1] + p1[2], dn1 = p1[1] - p1[2], ap1 = fabs(dp1), an1 = fabs(dn1),
1504         dp2 = p2[1] + p2[2], dn2 = p2[1] - p2[2], ap2 = fabs(dp2), an2 = fabs(dn2),
1505         dp3 = p3[1] + p3[2], dn3 = p3[1] - p3[2], ap3 = fabs(dp3), an3 = fabs(dn3);
1506         if(ap1 > bias*an1 && ap2 > bias*an2 && ap3 > bias*an3)
1507                 mask &= (3<<0)
1508                         | (dp1 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4))
1509                         | (dp2 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4))                    
1510                         | (dp3 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1511         if(an1 > bias*ap1 && an2 > bias*ap2 && an3 > bias*ap3)
1512                 mask &= (3<<0)
1513                         | (dn1 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4))
1514                         | (dn2 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4))
1515                         | (dn3 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1516
1517         dp1 = p1[2] + p1[0], dn1 = p1[2] - p1[0], ap1 = fabs(dp1), an1 = fabs(dn1),
1518         dp2 = p2[2] + p2[0], dn2 = p2[2] - p2[0], ap2 = fabs(dp2), an2 = fabs(dn2),
1519         dp3 = p3[2] + p3[0], dn3 = p3[2] - p3[0], ap3 = fabs(dp3), an3 = fabs(dn3);
1520         if(ap1 > bias*an1 && ap2 > bias*an2 && ap3 > bias*an3)
1521                 mask &= (3<<2)
1522                         | (dp1 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0))
1523                         | (dp2 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0))
1524                         | (dp3 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
1525         if(an1 > bias*ap1 && an2 > bias*ap2 && an3 > bias*ap3)
1526                 mask &= (3<<2)
1527                         | (dn1 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0))
1528                         | (dn2 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0))
1529                         | (dn3 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1530
1531         return mask;
1532 }
1533
1534 static int R_Shadow_CalcBBoxSideMask(const vec3_t mins, const vec3_t maxs, const matrix4x4_t *worldtolight, const matrix4x4_t *radiustolight, float bias)
1535 {
1536         vec3_t center, radius, lightcenter, lightradius, pmin, pmax;
1537         float dp1, dn1, ap1, an1, dp2, dn2, ap2, an2;
1538         int mask = 0x3F;
1539
1540         VectorSubtract(maxs, mins, radius);
1541         VectorScale(radius, 0.5f, radius);
1542         VectorAdd(mins, radius, center);
1543         Matrix4x4_Transform(worldtolight, center, lightcenter);
1544         Matrix4x4_Transform3x3(radiustolight, radius, lightradius);
1545         VectorSubtract(lightcenter, lightradius, pmin);
1546         VectorAdd(lightcenter, lightradius, pmax);
1547
1548         dp1 = pmax[0] + pmax[1], dn1 = pmax[0] - pmin[1], ap1 = fabs(dp1), an1 = fabs(dn1),
1549         dp2 = pmin[0] + pmin[1], dn2 = pmin[0] - pmax[1], ap2 = fabs(dp2), an2 = fabs(dn2);
1550         if(ap1 > bias*an1 && ap2 > bias*an2)
1551                 mask &= (3<<4)
1552                         | (dp1 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2))
1553                         | (dp2 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1554         if(an1 > bias*ap1 && an2 > bias*ap2)
1555                 mask &= (3<<4)
1556                         | (dn1 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2))
1557                         | (dn2 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1558
1559         dp1 = pmax[1] + pmax[2], dn1 = pmax[1] - pmin[2], ap1 = fabs(dp1), an1 = fabs(dn1),
1560         dp2 = pmin[1] + pmin[2], dn2 = pmin[1] - pmax[2], ap2 = fabs(dp2), an2 = fabs(dn2);
1561         if(ap1 > bias*an1 && ap2 > bias*an2)
1562                 mask &= (3<<0)
1563                         | (dp1 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4))
1564                         | (dp2 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1565         if(an1 > bias*ap1 && an2 > bias*ap2)
1566                 mask &= (3<<0)
1567                         | (dn1 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4))
1568                         | (dn2 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1569
1570         dp1 = pmax[2] + pmax[0], dn1 = pmax[2] - pmin[0], ap1 = fabs(dp1), an1 = fabs(dn1),
1571         dp2 = pmin[2] + pmin[0], dn2 = pmin[2] - pmax[0], ap2 = fabs(dp2), an2 = fabs(dn2);
1572         if(ap1 > bias*an1 && ap2 > bias*an2)
1573                 mask &= (3<<2)
1574                         | (dp1 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0))
1575                         | (dp2 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
1576         if(an1 > bias*ap1 && an2 > bias*ap2)
1577                 mask &= (3<<2)
1578                         | (dn1 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0))
1579                         | (dn2 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1580
1581         return mask;
1582 }
1583
1584 #define R_Shadow_CalcEntitySideMask(ent, worldtolight, radiustolight, bias) R_Shadow_CalcBBoxSideMask((ent)->mins, (ent)->maxs, worldtolight, radiustolight, bias)
1585
1586 int R_Shadow_CalcSphereSideMask(const vec3_t p, float radius, float bias)
1587 {
1588         // p is in the cubemap's local coordinate system
1589         // bias = border/(size - border)
1590         float dxyp = p[0] + p[1], dxyn = p[0] - p[1], axyp = fabs(dxyp), axyn = fabs(dxyn);
1591         float dyzp = p[1] + p[2], dyzn = p[1] - p[2], ayzp = fabs(dyzp), ayzn = fabs(dyzn);
1592         float dzxp = p[2] + p[0], dzxn = p[2] - p[0], azxp = fabs(dzxp), azxn = fabs(dzxn);
1593         int mask = 0x3F;
1594         if(axyp > bias*axyn + radius) mask &= dxyp < 0 ? ~((1<<0)|(1<<2)) : ~((2<<0)|(2<<2));
1595         if(axyn > bias*axyp + radius) mask &= dxyn < 0 ? ~((1<<0)|(2<<2)) : ~((2<<0)|(1<<2));
1596         if(ayzp > bias*ayzn + radius) mask &= dyzp < 0 ? ~((1<<2)|(1<<4)) : ~((2<<2)|(2<<4));
1597         if(ayzn > bias*ayzp + radius) mask &= dyzn < 0 ? ~((1<<2)|(2<<4)) : ~((2<<2)|(1<<4));
1598         if(azxp > bias*azxn + radius) mask &= dzxp < 0 ? ~((1<<4)|(1<<0)) : ~((2<<4)|(2<<0));
1599         if(azxn > bias*azxp + radius) mask &= dzxn < 0 ? ~((1<<4)|(2<<0)) : ~((2<<4)|(1<<0));
1600         return mask;
1601 }
1602
1603 static int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border)
1604 {
1605         int i;
1606         vec3_t o, p, n;
1607         int sides = 0x3F, masks[6] = { 3<<4, 3<<4, 3<<0, 3<<0, 3<<2, 3<<2 };
1608         float scale = (size - 2*border)/size, len;
1609         float bias = border / (float)(size - border), dp, dn, ap, an;
1610         // check if cone enclosing side would cross frustum plane
1611         scale = 2 / (scale*scale + 2);
1612         Matrix4x4_OriginFromMatrix(&rtlight->matrix_lighttoworld, o);
1613         for (i = 0;i < 5;i++)
1614         {
1615                 if (PlaneDiff(o, &r_refdef.view.frustum[i]) > -0.03125)
1616                         continue;
1617                 Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[i].normal, n);
1618                 len = scale*VectorLength2(n);
1619                 if(n[0]*n[0] > len) sides &= n[0] < 0 ? ~(1<<0) : ~(2 << 0);
1620                 if(n[1]*n[1] > len) sides &= n[1] < 0 ? ~(1<<2) : ~(2 << 2);
1621                 if(n[2]*n[2] > len) sides &= n[2] < 0 ? ~(1<<4) : ~(2 << 4);
1622         }
1623         if (PlaneDiff(o, &r_refdef.view.frustum[4]) >= r_refdef.farclip - r_refdef.nearclip + 0.03125)
1624         {
1625                 Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[4].normal, n);
1626                 len = scale*VectorLength2(n);
1627                 if(n[0]*n[0] > len) sides &= n[0] >= 0 ? ~(1<<0) : ~(2 << 0);
1628                 if(n[1]*n[1] > len) sides &= n[1] >= 0 ? ~(1<<2) : ~(2 << 2);
1629                 if(n[2]*n[2] > len) sides &= n[2] >= 0 ? ~(1<<4) : ~(2 << 4);
1630         }
1631         // this next test usually clips off more sides than the former, but occasionally clips fewer/different ones, so do both and combine results
1632         // check if frustum corners/origin cross plane sides
1633 #if 1
1634         // infinite version, assumes frustum corners merely give direction and extend to infinite distance
1635         Matrix4x4_Transform(&rtlight->matrix_worldtolight, r_refdef.view.origin, p);
1636         dp = p[0] + p[1], dn = p[0] - p[1], ap = fabs(dp), an = fabs(dn);
1637         masks[0] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1638         masks[1] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1639         dp = p[1] + p[2], dn = p[1] - p[2], ap = fabs(dp), an = fabs(dn);
1640         masks[2] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1641         masks[3] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1642         dp = p[2] + p[0], dn = p[2] - p[0], ap = fabs(dp), an = fabs(dn);
1643         masks[4] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
1644         masks[5] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1645         for (i = 0;i < 4;i++)
1646         {
1647                 Matrix4x4_Transform(&rtlight->matrix_worldtolight, r_refdef.view.frustumcorner[i], n);
1648                 VectorSubtract(n, p, n);
1649                 dp = n[0] + n[1], dn = n[0] - n[1], ap = fabs(dp), an = fabs(dn);
1650                 if(ap > 0) masks[0] |= dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2);
1651                 if(an > 0) masks[1] |= dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2);
1652                 dp = n[1] + n[2], dn = n[1] - n[2], ap = fabs(dp), an = fabs(dn);
1653                 if(ap > 0) masks[2] |= dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4);
1654                 if(an > 0) masks[3] |= dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4);
1655                 dp = n[2] + n[0], dn = n[2] - n[0], ap = fabs(dp), an = fabs(dn);
1656                 if(ap > 0) masks[4] |= dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0);
1657                 if(an > 0) masks[5] |= dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0);
1658         }
1659 #else
1660         // finite version, assumes corners are a finite distance from origin dependent on far plane
1661         for (i = 0;i < 5;i++)
1662         {
1663                 Matrix4x4_Transform(&rtlight->matrix_worldtolight, !i ? r_refdef.view.origin : r_refdef.view.frustumcorner[i-1], p);
1664                 dp = p[0] + p[1], dn = p[0] - p[1], ap = fabs(dp), an = fabs(dn);
1665                 masks[0] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1666                 masks[1] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1667                 dp = p[1] + p[2], dn = p[1] - p[2], ap = fabs(dp), an = fabs(dn);
1668                 masks[2] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1669                 masks[3] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1670                 dp = p[2] + p[0], dn = p[2] - p[0], ap = fabs(dp), an = fabs(dn);
1671                 masks[4] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
1672                 masks[5] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1673         }
1674 #endif
1675         return sides & masks[0] & masks[1] & masks[2] & masks[3] & masks[4] & masks[5];
1676 }
1677
1678 int R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const matrix4x4_t *worldtolight, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs, int *totals)
1679 {
1680         int t, tend;
1681         const int *e;
1682         const float *v[3];
1683         float normal[3];
1684         vec3_t p[3];
1685         float bias;
1686         int mask, surfacemask = 0;
1687         if (!BoxesOverlap(lightmins, lightmaxs, surfacemins, surfacemaxs))
1688                 return 0;
1689         bias = r_shadow_shadowmapborder / (float)(r_shadow_shadowmapmaxsize - r_shadow_shadowmapborder);
1690         tend = firsttriangle + numtris;
1691         if (BoxInsideBox(surfacemins, surfacemaxs, lightmins, lightmaxs))
1692         {
1693                 // surface box entirely inside light box, no box cull
1694                 if (projectdirection)
1695                 {
1696                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1697                         {
1698                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3, v[2] = invertex3f + e[2] * 3;
1699                                 TriangleNormal(v[0], v[1], v[2], normal);
1700                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0))
1701                                 {
1702                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1703                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1704                                         surfacemask |= mask;
1705                                         if(totals)
1706                                         {
1707                                                 totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5;
1708                                                 shadowsides[numshadowsides] = mask;
1709                                                 shadowsideslist[numshadowsides++] = t;
1710                                         }
1711                                 }
1712                         }
1713                 }
1714                 else
1715                 {
1716                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1717                         {
1718                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3,     v[2] = invertex3f + e[2] * 3;
1719                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2]))
1720                                 {
1721                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1722                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1723                                         surfacemask |= mask;
1724                                         if(totals)
1725                                         {
1726                                                 totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5;
1727                                                 shadowsides[numshadowsides] = mask;
1728                                                 shadowsideslist[numshadowsides++] = t;
1729                                         }
1730                                 }
1731                         }
1732                 }
1733         }
1734         else
1735         {
1736                 // surface box not entirely inside light box, cull each triangle
1737                 if (projectdirection)
1738                 {
1739                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1740                         {
1741                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3,     v[2] = invertex3f + e[2] * 3;
1742                                 TriangleNormal(v[0], v[1], v[2], normal);
1743                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0)
1744                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1745                                 {
1746                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1747                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1748                                         surfacemask |= mask;
1749                                         if(totals)
1750                                         {
1751                                                 totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5;
1752                                                 shadowsides[numshadowsides] = mask;
1753                                                 shadowsideslist[numshadowsides++] = t;
1754                                         }
1755                                 }
1756                         }
1757                 }
1758                 else
1759                 {
1760                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1761                         {
1762                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3, v[2] = invertex3f + e[2] * 3;
1763                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2])
1764                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1765                                 {
1766                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1767                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1768                                         surfacemask |= mask;
1769                                         if(totals)
1770                                         {
1771                                                 totals[0] += mask&1, totals[1] += (mask>>1)&1, totals[2] += (mask>>2)&1, totals[3] += (mask>>3)&1, totals[4] += (mask>>4)&1, totals[5] += mask>>5;
1772                                                 shadowsides[numshadowsides] = mask;
1773                                                 shadowsideslist[numshadowsides++] = t;
1774                                         }
1775                                 }
1776                         }
1777                 }
1778         }
1779         return surfacemask;
1780 }
1781
1782 void R_Shadow_ShadowMapFromList(int numverts, int numtris, const float *vertex3f, const int *elements, int numsidetris, const int *sidetotals, const unsigned char *sides, const int *sidetris)
1783 {
1784         int i, j, outtriangles = 0;
1785         int *outelement3i[6];
1786         if (!numverts || !numsidetris || !r_shadow_compilingrtlight)
1787                 return;
1788         outtriangles = sidetotals[0] + sidetotals[1] + sidetotals[2] + sidetotals[3] + sidetotals[4] + sidetotals[5];
1789         // make sure shadowelements is big enough for this mesh
1790         if (maxshadowtriangles < outtriangles)
1791                 R_Shadow_ResizeShadowArrays(0, outtriangles, 0, 1);
1792
1793         // compute the offset and size of the separate index lists for each cubemap side
1794         outtriangles = 0;
1795         for (i = 0;i < 6;i++)
1796         {
1797                 outelement3i[i] = shadowelements + outtriangles * 3;
1798                 r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap->sideoffsets[i] = outtriangles;
1799                 r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap->sidetotals[i] = sidetotals[i];
1800                 outtriangles += sidetotals[i];
1801         }
1802
1803         // gather up the (sparse) triangles into separate index lists for each cubemap side
1804         for (i = 0;i < numsidetris;i++)
1805         {
1806                 const int *element = elements + sidetris[i] * 3;
1807                 for (j = 0;j < 6;j++)
1808                 {
1809                         if (sides[i] & (1 << j))
1810                         {
1811                                 outelement3i[j][0] = element[0];
1812                                 outelement3i[j][1] = element[1];
1813                                 outelement3i[j][2] = element[2];
1814                                 outelement3i[j] += 3;
1815                         }
1816                 }
1817         }
1818                         
1819         Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap, NULL, NULL, NULL, vertex3f, NULL, NULL, NULL, NULL, outtriangles, shadowelements);
1820 }
1821
1822 static void R_Shadow_MakeTextures_MakeCorona(void)
1823 {
1824         float dx, dy;
1825         int x, y, a;
1826         unsigned char pixels[32][32][4];
1827         for (y = 0;y < 32;y++)
1828         {
1829                 dy = (y - 15.5f) * (1.0f / 16.0f);
1830                 for (x = 0;x < 32;x++)
1831                 {
1832                         dx = (x - 15.5f) * (1.0f / 16.0f);
1833                         a = (int)(((1.0f / (dx * dx + dy * dy + 0.2f)) - (1.0f / (1.0f + 0.2))) * 32.0f / (1.0f / (1.0f + 0.2)));
1834                         a = bound(0, a, 255);
1835                         pixels[y][x][0] = a;
1836                         pixels[y][x][1] = a;
1837                         pixels[y][x][2] = a;
1838                         pixels[y][x][3] = 255;
1839                 }
1840         }
1841         r_shadow_lightcorona = R_SkinFrame_LoadInternalBGRA("lightcorona", TEXF_FORCELINEAR, &pixels[0][0][0], 32, 32, false);
1842 }
1843
1844 static unsigned int R_Shadow_MakeTextures_SamplePoint(float x, float y, float z)
1845 {
1846         float dist = sqrt(x*x+y*y+z*z);
1847         float intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
1848         // note this code could suffer byte order issues except that it is multiplying by an integer that reads the same both ways
1849         return (unsigned char)bound(0, intensity * 256.0f, 255) * 0x01010101;
1850 }
1851
1852 static void R_Shadow_MakeTextures(void)
1853 {
1854         int x, y, z;
1855         float intensity, dist;
1856         unsigned int *data;
1857         R_Shadow_FreeShadowMaps();
1858         R_FreeTexturePool(&r_shadow_texturepool);
1859         r_shadow_texturepool = R_AllocTexturePool();
1860         r_shadow_attenlinearscale = r_shadow_lightattenuationlinearscale.value;
1861         r_shadow_attendividebias = r_shadow_lightattenuationdividebias.value;
1862         data = (unsigned int *)Mem_Alloc(tempmempool, max(max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE, ATTEN2DSIZE*ATTEN2DSIZE), ATTEN1DSIZE) * 4);
1863         // the table includes one additional value to avoid the need to clamp indexing due to minor math errors
1864         for (x = 0;x <= ATTENTABLESIZE;x++)
1865         {
1866                 dist = (x + 0.5f) * (1.0f / ATTENTABLESIZE) * (1.0f / 0.9375);
1867                 intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
1868                 r_shadow_attentable[x] = bound(0, intensity, 1);
1869         }
1870         // 1D gradient texture
1871         for (x = 0;x < ATTEN1DSIZE;x++)
1872                 data[x] = R_Shadow_MakeTextures_SamplePoint((x + 0.5f) * (1.0f / ATTEN1DSIZE) * (1.0f / 0.9375), 0, 0);
1873         r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
1874         // 2D circle texture
1875         for (y = 0;y < ATTEN2DSIZE;y++)
1876                 for (x = 0;x < ATTEN2DSIZE;x++)
1877                         data[y*ATTEN2DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), 0);
1878         r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
1879         // 3D sphere texture
1880         if (r_shadow_texture3d.integer && vid.support.ext_texture_3d)
1881         {
1882                 for (z = 0;z < ATTEN3DSIZE;z++)
1883                         for (y = 0;y < ATTEN3DSIZE;y++)
1884                                 for (x = 0;x < ATTEN3DSIZE;x++)
1885                                         data[(z*ATTEN3DSIZE+y)*ATTEN3DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((z + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375));
1886                 r_shadow_attenuation3dtexture = R_LoadTexture3D(r_shadow_texturepool, "attenuation3d", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
1887         }
1888         else
1889                 r_shadow_attenuation3dtexture = NULL;
1890         Mem_Free(data);
1891
1892         R_Shadow_MakeTextures_MakeCorona();
1893
1894         // Editor light sprites
1895         r_editlights_sprcursor = R_SkinFrame_LoadInternal8bit("gfx/editlights/cursor", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1896         "................"
1897         ".3............3."
1898         "..5...2332...5.."
1899         "...7.3....3.7..."
1900         "....7......7...."
1901         "...3.7....7.3..."
1902         "..2...7..7...2.."
1903         "..3..........3.."
1904         "..3..........3.."
1905         "..2...7..7...2.."
1906         "...3.7....7.3..."
1907         "....7......7...."
1908         "...7.3....3.7..."
1909         "..5...2332...5.."
1910         ".3............3."
1911         "................"
1912         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1913         r_editlights_sprlight = R_SkinFrame_LoadInternal8bit("gfx/editlights/light", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1914         "................"
1915         "................"
1916         "......1111......"
1917         "....11233211...."
1918         "...1234554321..."
1919         "...1356776531..."
1920         "..124677776421.."
1921         "..135777777531.."
1922         "..135777777531.."
1923         "..124677776421.."
1924         "...1356776531..."
1925         "...1234554321..."
1926         "....11233211...."
1927         "......1111......"
1928         "................"
1929         "................"
1930         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1931         r_editlights_sprnoshadowlight = R_SkinFrame_LoadInternal8bit("gfx/editlights/noshadow", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1932         "................"
1933         "................"
1934         "......1111......"
1935         "....11233211...."
1936         "...1234554321..."
1937         "...1356226531..."
1938         "..12462..26421.."
1939         "..1352....2531.."
1940         "..1352....2531.."
1941         "..12462..26421.."
1942         "...1356226531..."
1943         "...1234554321..."
1944         "....11233211...."
1945         "......1111......"
1946         "................"
1947         "................"
1948         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1949         r_editlights_sprcubemaplight = R_SkinFrame_LoadInternal8bit("gfx/editlights/cubemaplight", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1950         "................"
1951         "................"
1952         "......2772......"
1953         "....27755772...."
1954         "..277533335772.."
1955         "..753333333357.."
1956         "..777533335777.."
1957         "..735775577537.."
1958         "..733357753337.."
1959         "..733337733337.."
1960         "..753337733357.."
1961         "..277537735772.."
1962         "....27777772...."
1963         "......2772......"
1964         "................"
1965         "................"
1966         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1967         r_editlights_sprcubemapnoshadowlight = R_SkinFrame_LoadInternal8bit("gfx/editlights/cubemapnoshadowlight", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1968         "................"
1969         "................"
1970         "......2772......"
1971         "....27722772...."
1972         "..2772....2772.."
1973         "..72........27.."
1974         "..7772....2777.."
1975         "..7.27722772.7.."
1976         "..7...2772...7.."
1977         "..7....77....7.."
1978         "..72...77...27.."
1979         "..2772.77.2772.."
1980         "....27777772...."
1981         "......2772......"
1982         "................"
1983         "................"
1984         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1985         r_editlights_sprselection = R_SkinFrame_LoadInternal8bit("gfx/editlights/selection", TEXF_ALPHA | TEXF_CLAMP, (unsigned char *)
1986         "................"
1987         ".777752..257777."
1988         ".742........247."
1989         ".72..........27."
1990         ".7............7."
1991         ".5............5."
1992         ".2............2."
1993         "................"
1994         "................"
1995         ".2............2."
1996         ".5............5."
1997         ".7............7."
1998         ".72..........27."
1999         ".742........247."
2000         ".777752..257777."
2001         "................"
2002         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
2003 }
2004
2005 void R_Shadow_ValidateCvars(void)
2006 {
2007         if (r_shadow_texture3d.integer && !vid.support.ext_texture_3d)
2008                 Cvar_SetValueQuick(&r_shadow_texture3d, 0);
2009         if (gl_ext_separatestencil.integer && !vid.support.ati_separate_stencil)
2010                 Cvar_SetValueQuick(&gl_ext_separatestencil, 0);
2011         if (gl_ext_stenciltwoside.integer && !vid.support.ext_stencil_two_side)
2012                 Cvar_SetValueQuick(&gl_ext_stenciltwoside, 0);
2013 }
2014
2015 void R_Shadow_RenderMode_Begin(void)
2016 {
2017 #if 0
2018         GLint drawbuffer;
2019         GLint readbuffer;
2020 #endif
2021         R_Shadow_ValidateCvars();
2022
2023         if (!r_shadow_attenuation2dtexture
2024          || (!r_shadow_attenuation3dtexture && r_shadow_texture3d.integer)
2025          || r_shadow_lightattenuationdividebias.value != r_shadow_attendividebias
2026          || r_shadow_lightattenuationlinearscale.value != r_shadow_attenlinearscale)
2027                 R_Shadow_MakeTextures();
2028
2029         CHECKGLERROR
2030         R_Mesh_ResetTextureState();
2031         GL_BlendFunc(GL_ONE, GL_ZERO);
2032         GL_DepthRange(0, 1);
2033         GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
2034         GL_DepthTest(true);
2035         GL_DepthMask(false);
2036         GL_Color(0, 0, 0, 1);
2037         GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
2038         
2039         r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
2040
2041         if (gl_ext_separatestencil.integer && vid.support.ati_separate_stencil)
2042         {
2043                 r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_SEPARATESTENCIL;
2044                 r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_SEPARATESTENCIL;
2045         }
2046         else if (gl_ext_stenciltwoside.integer && vid.support.ext_stencil_two_side)
2047         {
2048                 r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE;
2049                 r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_STENCILTWOSIDE;
2050         }
2051         else
2052         {
2053                 r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_STENCIL;
2054                 r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_STENCIL;
2055         }
2056
2057         switch(vid.renderpath)
2058         {
2059         case RENDERPATH_GL20:
2060         case RENDERPATH_D3D9:
2061         case RENDERPATH_D3D10:
2062         case RENDERPATH_D3D11:
2063         case RENDERPATH_SOFT:
2064         case RENDERPATH_GLES2:
2065                 r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_GLSL;
2066                 break;
2067         case RENDERPATH_GL11:
2068         case RENDERPATH_GL13:
2069         case RENDERPATH_GLES1:
2070                 if (r_textureunits.integer >= 2 && vid.texunits >= 2 && r_shadow_texture3d.integer && r_shadow_attenuation3dtexture)
2071                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN;
2072                 else if (r_textureunits.integer >= 3 && vid.texunits >= 3)
2073                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN;
2074                 else if (r_textureunits.integer >= 2 && vid.texunits >= 2)
2075                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN;
2076                 else
2077                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX;
2078                 break;
2079         }
2080
2081         CHECKGLERROR
2082 #if 0
2083         qglGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);CHECKGLERROR
2084         qglGetIntegerv(GL_READ_BUFFER, &readbuffer);CHECKGLERROR
2085         r_shadow_drawbuffer = drawbuffer;
2086         r_shadow_readbuffer = readbuffer;
2087 #endif
2088         r_shadow_cullface_front = r_refdef.view.cullface_front;
2089         r_shadow_cullface_back = r_refdef.view.cullface_back;
2090 }
2091
2092 void R_Shadow_RenderMode_ActiveLight(const rtlight_t *rtlight)
2093 {
2094         rsurface.rtlight = rtlight;
2095 }
2096
2097 void R_Shadow_RenderMode_Reset(void)
2098 {
2099         R_Mesh_ResetTextureState();
2100         R_Mesh_SetRenderTargets(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture, NULL, NULL, NULL);
2101         R_SetViewport(&r_refdef.view.viewport);
2102         GL_Scissor(r_shadow_lightscissor[0], r_shadow_lightscissor[1], r_shadow_lightscissor[2], r_shadow_lightscissor[3]);
2103         GL_DepthRange(0, 1);
2104         GL_DepthTest(true);
2105         GL_DepthMask(false);
2106         GL_DepthFunc(GL_LEQUAL);
2107         GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
2108         r_refdef.view.cullface_front = r_shadow_cullface_front;
2109         r_refdef.view.cullface_back = r_shadow_cullface_back;
2110         GL_CullFace(r_refdef.view.cullface_back);
2111         GL_Color(1, 1, 1, 1);
2112         GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
2113         GL_BlendFunc(GL_ONE, GL_ZERO);
2114         R_SetupShader_Generic_NoTexture(false, false);
2115         r_shadow_usingshadowmap2d = false;
2116         R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
2117 }
2118
2119 void R_Shadow_ClearStencil(void)
2120 {
2121         GL_Clear(GL_STENCIL_BUFFER_BIT, NULL, 1.0f, 128);
2122         r_refdef.stats[r_stat_lights_clears]++;
2123 }
2124
2125 void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass)
2126 {
2127         r_shadow_rendermode_t mode = zpass ? r_shadow_shadowingrendermode_zpass : r_shadow_shadowingrendermode_zfail;
2128         if (r_shadow_rendermode == mode)
2129                 return;
2130         R_Shadow_RenderMode_Reset();
2131         GL_DepthFunc(GL_LESS);
2132         GL_ColorMask(0, 0, 0, 0);
2133         GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR
2134         GL_CullFace(GL_NONE);
2135         R_SetupShader_DepthOrShadow(false, false, false); // FIXME test if we have a skeletal model?
2136         r_shadow_rendermode = mode;
2137         switch(mode)
2138         {
2139         default:
2140                 break;
2141         case R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE:
2142         case R_SHADOW_RENDERMODE_ZPASS_SEPARATESTENCIL:
2143                 R_SetStencilSeparate(true, 255, GL_KEEP, GL_KEEP, GL_INCR, GL_KEEP, GL_KEEP, GL_DECR, GL_ALWAYS, GL_ALWAYS, 128, 255);
2144                 break;
2145         case R_SHADOW_RENDERMODE_ZFAIL_STENCILTWOSIDE:
2146         case R_SHADOW_RENDERMODE_ZFAIL_SEPARATESTENCIL:
2147                 R_SetStencilSeparate(true, 255, GL_KEEP, GL_INCR, GL_KEEP, GL_KEEP, GL_DECR, GL_KEEP, GL_ALWAYS, GL_ALWAYS, 128, 255);
2148                 break;
2149         }
2150 }
2151
2152 static void R_Shadow_MakeVSDCT(void)
2153 {
2154         // maps to a 2x3 texture rectangle with normalized coordinates
2155         // +-
2156         // XX
2157         // YY
2158         // ZZ
2159         // stores abs(dir.xy), offset.xy/2.5
2160         unsigned char data[4*6] =
2161         {
2162                 255, 0, 0x33, 0x33, // +X: <1, 0>, <0.5, 0.5>
2163                 255, 0, 0x99, 0x33, // -X: <1, 0>, <1.5, 0.5>
2164                 0, 255, 0x33, 0x99, // +Y: <0, 1>, <0.5, 1.5>
2165                 0, 255, 0x99, 0x99, // -Y: <0, 1>, <1.5, 1.5>
2166                 0,   0, 0x33, 0xFF, // +Z: <0, 0>, <0.5, 2.5>
2167                 0,   0, 0x99, 0xFF, // -Z: <0, 0>, <1.5, 2.5>
2168         };
2169         r_shadow_shadowmapvsdcttexture = R_LoadTextureCubeMap(r_shadow_texturepool, "shadowmapvsdct", 1, data, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL);
2170 }
2171
2172 static void R_Shadow_MakeShadowMap(int texturesize)
2173 {
2174         switch (r_shadow_shadowmode)
2175         {
2176         case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
2177                 if (r_shadow_shadowmap2ddepthtexture) return;
2178                 if (r_fb.usedepthtextures)
2179                 {
2180                         r_shadow_shadowmap2ddepthtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", texturesize, texturesize, r_shadow_shadowmapdepthbits >= 24 ? (r_shadow_shadowmapsampler ? TEXTYPE_SHADOWMAP24_COMP : TEXTYPE_SHADOWMAP24_RAW) : (r_shadow_shadowmapsampler ? TEXTYPE_SHADOWMAP16_COMP : TEXTYPE_SHADOWMAP16_RAW), r_shadow_shadowmapsampler);
2181                         r_shadow_shadowmap2ddepthbuffer = NULL;
2182                         r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL);
2183                 }
2184                 else
2185                 {
2186                         r_shadow_shadowmap2ddepthtexture = R_LoadTexture2D(r_shadow_texturepool, "shadowmaprendertarget", texturesize, texturesize, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL);
2187                         r_shadow_shadowmap2ddepthbuffer = R_LoadTextureRenderBuffer(r_shadow_texturepool, "shadowmap", texturesize, texturesize, r_shadow_shadowmapdepthbits >= 24 ? TEXTYPE_DEPTHBUFFER24 : TEXTYPE_DEPTHBUFFER16);
2188                         r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL);
2189                 }
2190                 break;
2191         default:
2192                 return;
2193         }
2194 }
2195
2196 void R_Shadow_ClearShadowMapTexture(void)
2197 {
2198         r_viewport_t viewport;
2199         float clearcolor[4];
2200
2201         // if they don't exist, create our textures now
2202         if (!r_shadow_shadowmap2ddepthtexture)
2203                 R_Shadow_MakeShadowMap(r_shadow_shadowmaptexturesize);
2204         if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapvsdcttexture)
2205                 R_Shadow_MakeVSDCT();
2206
2207         // we're setting up to render shadowmaps, so change rendermode
2208         r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D;
2209
2210         R_Mesh_ResetTextureState();
2211         R_Shadow_RenderMode_Reset();
2212         if (r_shadow_shadowmap2ddepthbuffer)
2213                 R_Mesh_SetRenderTargets(r_shadow_fbo2d, r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL);
2214         else
2215                 R_Mesh_SetRenderTargets(r_shadow_fbo2d, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL);
2216         R_SetupShader_DepthOrShadow(true, r_shadow_shadowmap2ddepthbuffer != NULL, false); // FIXME test if we have a skeletal model?
2217         GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value);
2218         GL_DepthMask(true);
2219         GL_DepthTest(true);
2220
2221         // we have to set a viewport to clear anything in some renderpaths (D3D)
2222         R_Viewport_InitOrtho(&viewport, &identitymatrix, 0, 0, r_shadow_shadowmaptexturesize, r_shadow_shadowmaptexturesize, 0, 0, 1.0, 1.0, 0.001f, 1.0f, NULL);
2223         R_SetViewport(&viewport);
2224         GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
2225         if (r_shadow_shadowmap2ddepthbuffer)
2226                 GL_ColorMask(1, 1, 1, 1);
2227         else
2228                 GL_ColorMask(0, 0, 0, 0);
2229         switch (vid.renderpath)
2230         {
2231         case RENDERPATH_GL11:
2232         case RENDERPATH_GL13:
2233         case RENDERPATH_GL20:
2234         case RENDERPATH_SOFT:
2235         case RENDERPATH_GLES1:
2236         case RENDERPATH_GLES2:
2237                 GL_CullFace(r_refdef.view.cullface_back);
2238                 break;
2239         case RENDERPATH_D3D9:
2240         case RENDERPATH_D3D10:
2241         case RENDERPATH_D3D11:
2242                 // we invert the cull mode because we flip the projection matrix
2243                 // NOTE: this actually does nothing because the DrawShadowMap code sets it to doublesided...
2244                 GL_CullFace(r_refdef.view.cullface_front);
2245                 break;
2246         }
2247         Vector4Set(clearcolor, 1, 1, 1, 1);
2248         if (r_shadow_shadowmap2ddepthbuffer)
2249                 GL_Clear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0);
2250         else
2251                 GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0);
2252 }
2253
2254 static void R_Shadow_SetShadowmapParametersForLight(qboolean noselfshadowpass)
2255 {
2256         int size = rsurface.rtlight->shadowmapatlassidesize;
2257         float nearclip = r_shadow_shadowmapping_nearclip.value / rsurface.rtlight->radius;
2258         float farclip = 1.0f;
2259         float bias = r_shadow_shadowmapping_bias.value * nearclip * (1024.0f / size);// * rsurface.rtlight->radius;
2260         r_shadow_lightshadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2ddepthtexture);
2261         r_shadow_lightshadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2ddepthtexture);
2262         r_shadow_lightshadowmap_texturescale[2] = rsurface.rtlight->shadowmapatlasposition[0] + (noselfshadowpass ? size * 2 : 0);
2263         r_shadow_lightshadowmap_texturescale[3] = rsurface.rtlight->shadowmapatlasposition[1];
2264         r_shadow_lightshadowmap_parameters[0] = 0.5f * (size - r_shadow_shadowmapborder);
2265         r_shadow_lightshadowmap_parameters[1] = -nearclip * farclip / (farclip - nearclip) - 0.5f * bias;
2266         r_shadow_lightshadowmap_parameters[2] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
2267         r_shadow_lightshadowmap_parameters[3] = 0.5f + 0.5f * (farclip + nearclip) / (farclip - nearclip);
2268         if (r_shadow_shadowmap2ddepthbuffer)
2269         {
2270                 // completely different meaning than in depthtexture approach
2271                 r_shadow_lightshadowmap_parameters[1] = 0;
2272                 r_shadow_lightshadowmap_parameters[3] = -bias;
2273         }
2274 }
2275
2276 static void R_Shadow_RenderMode_ShadowMap(int side, int size, int x, int y)
2277 {
2278         float nearclip, farclip, bias;
2279         r_viewport_t viewport;
2280         int flipped;
2281         float clearcolor[4];
2282
2283         if (r_shadow_rendermode != R_SHADOW_RENDERMODE_SHADOWMAP2D)
2284         {
2285                 r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D;
2286
2287                 R_Mesh_ResetTextureState();
2288                 R_Shadow_RenderMode_Reset();
2289                 if (r_shadow_shadowmap2ddepthbuffer)
2290                         R_Mesh_SetRenderTargets(r_shadow_fbo2d, r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL);
2291                 else
2292                         R_Mesh_SetRenderTargets(r_shadow_fbo2d, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL);
2293                 R_SetupShader_DepthOrShadow(true, r_shadow_shadowmap2ddepthbuffer != NULL, false); // FIXME test if we have a skeletal model?
2294                 GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value);
2295                 GL_DepthMask(true);
2296                 GL_DepthTest(true);
2297         }
2298
2299         nearclip = r_shadow_shadowmapping_nearclip.value / rsurface.rtlight->radius;
2300         farclip = 1.0f;
2301         bias = r_shadow_shadowmapping_bias.value * nearclip * (1024.0f / size);// * rsurface.rtlight->radius;
2302
2303         R_Viewport_InitRectSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, r_shadow_shadowmapborder, nearclip, farclip, NULL, x, y);
2304         R_SetViewport(&viewport);
2305         GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
2306         flipped = (side & 1) ^ (side >> 2);
2307         r_refdef.view.cullface_front = flipped ? r_shadow_cullface_back : r_shadow_cullface_front;
2308         r_refdef.view.cullface_back = flipped ? r_shadow_cullface_front : r_shadow_cullface_back;
2309
2310         Vector4Set(clearcolor, 1,1,1,1);
2311         if (r_shadow_shadowmap2ddepthbuffer)
2312                 GL_ColorMask(1,1,1,1);
2313         else
2314                 GL_ColorMask(0,0,0,0);
2315         switch(vid.renderpath)
2316         {
2317         case RENDERPATH_GL11:
2318         case RENDERPATH_GL13:
2319         case RENDERPATH_GL20:
2320         case RENDERPATH_SOFT:
2321         case RENDERPATH_GLES1:
2322         case RENDERPATH_GLES2:
2323                 GL_CullFace(r_refdef.view.cullface_back);
2324                 break;
2325         case RENDERPATH_D3D9:
2326         case RENDERPATH_D3D10:
2327         case RENDERPATH_D3D11:
2328                 // we invert the cull mode because we flip the projection matrix
2329                 // NOTE: this actually does nothing because the DrawShadowMap code sets it to doublesided...
2330                 GL_CullFace(r_refdef.view.cullface_front);
2331                 break;
2332         }
2333
2334         // used in R_Q1BSP_DrawShadowMap code to check surfacesides[]
2335         r_shadow_shadowmapside = side;
2336 }
2337
2338 void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qboolean shadowmapping, qboolean noselfshadowpass)
2339 {
2340         R_Mesh_ResetTextureState();
2341         if (transparent)
2342         {
2343                 r_shadow_lightscissor[0] = r_refdef.view.viewport.x;
2344                 r_shadow_lightscissor[1] = r_refdef.view.viewport.y;
2345                 r_shadow_lightscissor[2] = r_refdef.view.viewport.width;
2346                 r_shadow_lightscissor[3] = r_refdef.view.viewport.height;
2347         }
2348         if (shadowmapping)
2349                 R_Shadow_SetShadowmapParametersForLight(noselfshadowpass);
2350         R_Shadow_RenderMode_Reset();
2351         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2352         if (!transparent)
2353                 GL_DepthFunc(GL_EQUAL);
2354         // do global setup needed for the chosen lighting mode
2355         if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
2356                 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 0);
2357         r_shadow_usingshadowmap2d = shadowmapping;
2358         r_shadow_rendermode = r_shadow_lightingrendermode;
2359         // only draw light where this geometry was already rendered AND the
2360         // stencil is 128 (values other than this mean shadow)
2361         if (stenciltest)
2362                 R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255);
2363         else
2364                 R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
2365 }
2366
2367 static const unsigned short bboxelements[36] =
2368 {
2369         5, 1, 3, 5, 3, 7,
2370         6, 2, 0, 6, 0, 4,
2371         7, 3, 2, 7, 2, 6,
2372         4, 0, 1, 4, 1, 5,
2373         4, 5, 7, 4, 7, 6,
2374         1, 0, 2, 1, 2, 3,
2375 };
2376
2377 static const float bboxpoints[8][3] =
2378 {
2379         {-1,-1,-1},
2380         { 1,-1,-1},
2381         {-1, 1,-1},
2382         { 1, 1,-1},
2383         {-1,-1, 1},
2384         { 1,-1, 1},
2385         {-1, 1, 1},
2386         { 1, 1, 1},
2387 };
2388
2389 void R_Shadow_RenderMode_DrawDeferredLight(qboolean shadowmapping)
2390 {
2391         int i;
2392         float vertex3f[8*3];
2393         const matrix4x4_t *matrix = &rsurface.rtlight->matrix_lighttoworld;
2394 // do global setup needed for the chosen lighting mode
2395         R_Shadow_RenderMode_Reset();
2396         r_shadow_rendermode = r_shadow_lightingrendermode;
2397         R_EntityMatrix(&identitymatrix);
2398         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2399         R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255);
2400         if (rsurface.rtlight->specularscale > 0 && r_shadow_gloss.integer > 0)
2401                 R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL);
2402         else
2403                 R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL);
2404
2405         r_shadow_usingshadowmap2d = shadowmapping;
2406
2407         // render the lighting
2408         R_SetupShader_DeferredLight(rsurface.rtlight);
2409         for (i = 0;i < 8;i++)
2410                 Matrix4x4_Transform(matrix, bboxpoints[i], vertex3f + i*3);
2411         GL_ColorMask(1,1,1,1);
2412         GL_DepthMask(false);
2413         GL_DepthRange(0, 1);
2414         GL_PolygonOffset(0, 0);
2415         GL_DepthTest(true);
2416         GL_DepthFunc(GL_GREATER);
2417         GL_CullFace(r_refdef.view.cullface_back);
2418         R_Mesh_PrepareVertices_Vertex3f(8, vertex3f, NULL, 0);
2419         R_Mesh_Draw(0, 8, 0, 12, NULL, NULL, 0, bboxelements, NULL, 0);
2420 }
2421
2422 #define MAXBOUNCEGRIDSPLATSIZE 7
2423 #define MAXBOUNCEGRIDSPLATSIZE1 (MAXBOUNCEGRIDSPLATSIZE+1)
2424
2425 // these are temporary data per-frame, sorted and performed in a more
2426 // cache-friendly order than the original photons
2427 typedef struct r_shadow_bouncegrid_splatpath_s
2428 {
2429         vec3_t point;
2430         vec3_t step;
2431         vec3_t splatcolor;
2432         vec3_t splatdir;
2433         vec_t splatintensity;
2434         vec_t splatsize_current;
2435         vec_t splatsize_perstep;
2436         int remainingsplats;
2437 }
2438 r_shadow_bouncegrid_splatpath_t;
2439
2440 static void R_Shadow_BounceGrid_AddSplatPath(vec3_t originalstart, vec3_t originalend, vec3_t color, vec_t distancetraveled)
2441 {
2442         int bestaxis;
2443         int numsplats;
2444         float len;
2445         float ilen;
2446         vec3_t start;
2447         vec3_t end;
2448         vec3_t diff;
2449         vec3_t originaldir;
2450         r_shadow_bouncegrid_splatpath_t *path;
2451
2452         // cull paths that fail R_CullBox in dynamic mode
2453         if (!r_shadow_bouncegrid_state.settings.staticmode
2454          && r_shadow_bouncegrid_dynamic_culllightpaths.integer)
2455         {
2456                 vec3_t cullmins, cullmaxs;
2457                 cullmins[0] = min(originalstart[0], originalend[0]) - r_shadow_bouncegrid_state.settings.spacing[0];
2458                 cullmins[1] = min(originalstart[1], originalend[1]) - r_shadow_bouncegrid_state.settings.spacing[1];
2459                 cullmins[2] = min(originalstart[2], originalend[2]) - r_shadow_bouncegrid_state.settings.spacing[2];
2460                 cullmaxs[0] = max(originalstart[0], originalend[0]) + r_shadow_bouncegrid_state.settings.spacing[0];
2461                 cullmaxs[1] = max(originalstart[1], originalend[1]) + r_shadow_bouncegrid_state.settings.spacing[1];
2462                 cullmaxs[2] = max(originalstart[2], originalend[2]) + r_shadow_bouncegrid_state.settings.spacing[2];
2463                 if (R_CullBox(cullmins, cullmaxs))
2464                         return;
2465         }
2466
2467         // if the light path is going upward, reverse it - we always draw down.
2468         if (originalend[2] < originalstart[2])
2469         {
2470                 VectorCopy(originalend, start);
2471                 VectorCopy(originalstart, end);
2472         }
2473         else
2474         {
2475                 VectorCopy(originalstart, start);
2476                 VectorCopy(originalend, end);
2477         }
2478
2479         // transform to texture pixels
2480         start[0] = (start[0] - r_shadow_bouncegrid_state.mins[0]) * r_shadow_bouncegrid_state.ispacing[0];
2481         start[1] = (start[1] - r_shadow_bouncegrid_state.mins[1]) * r_shadow_bouncegrid_state.ispacing[1];
2482         start[2] = (start[2] - r_shadow_bouncegrid_state.mins[2]) * r_shadow_bouncegrid_state.ispacing[2];
2483         end[0] = (end[0] - r_shadow_bouncegrid_state.mins[0]) * r_shadow_bouncegrid_state.ispacing[0];
2484         end[1] = (end[1] - r_shadow_bouncegrid_state.mins[1]) * r_shadow_bouncegrid_state.ispacing[1];
2485         end[2] = (end[2] - r_shadow_bouncegrid_state.mins[2]) * r_shadow_bouncegrid_state.ispacing[2];
2486
2487         // check if we need to grow the splatpaths array
2488         if (r_shadow_bouncegrid_state.maxsplatpaths <= r_shadow_bouncegrid_state.numsplatpaths)
2489         {
2490                 // double the limit, this will persist from frame to frame so we don't
2491                 // make the same mistake each time
2492                 r_shadow_bouncegrid_state.maxsplatpaths *= 2;
2493                 if (r_shadow_bouncegrid_state.maxsplatpaths < 16384)
2494                         r_shadow_bouncegrid_state.maxsplatpaths = 16384;
2495                 r_shadow_bouncegrid_state.splatpaths = (r_shadow_bouncegrid_splatpath_t *)Mem_Realloc(r_main_mempool, r_shadow_bouncegrid_state.splatpaths, sizeof(r_shadow_bouncegrid_splatpath_t) * r_shadow_bouncegrid_state.maxsplatpaths);
2496         }
2497
2498         // divide a series of splats along the length using the maximum axis
2499         VectorSubtract(end, start, diff);
2500         // pick the best axis to trace along
2501         bestaxis = 0;
2502         if (diff[1]*diff[1] > diff[bestaxis]*diff[bestaxis])
2503                 bestaxis = 1;
2504         if (diff[2]*diff[2] > diff[bestaxis]*diff[bestaxis])
2505                 bestaxis = 2;
2506         len = fabs(diff[bestaxis]);
2507         ilen = 1.0f / len;
2508         numsplats = (int)(floor(len + 0.5f));
2509         // sanity limits
2510         numsplats = bound(0, numsplats, 1024);
2511
2512         VectorSubtract(originalstart, originalend, originaldir);
2513         VectorNormalize(originaldir);
2514
2515         path = r_shadow_bouncegrid_state.splatpaths + r_shadow_bouncegrid_state.numsplatpaths++;
2516         VectorCopy(start, path->point);
2517         VectorScale(diff, ilen, path->step);
2518         VectorCopy(color, path->splatcolor);
2519         VectorCopy(originaldir, path->splatdir);
2520         path->splatsize_current = r_shadow_bouncegrid_state.settings.lightpathsize_initial + r_shadow_bouncegrid_state.settings.lightpathsize_conespread * distancetraveled * r_shadow_bouncegrid_state.ispacing[0];
2521         path->splatsize_perstep = r_shadow_bouncegrid_state.settings.lightpathsize_conespread;
2522         path->splatintensity = VectorLength(color);
2523         path->remainingsplats = numsplats;
2524 }
2525
2526 static qboolean R_Shadow_BounceGrid_CheckEnable(int flag)
2527 {
2528         qboolean enable = r_shadow_bouncegrid_state.capable && r_shadow_bouncegrid.integer != 0 && r_refdef.scene.worldmodel;
2529         int lightindex;
2530         int range;
2531         dlight_t *light;
2532         rtlight_t *rtlight;
2533         vec3_t lightcolor;
2534
2535         // see if there are really any lights to render...
2536         if (enable && r_shadow_bouncegrid_static.integer)
2537         {
2538                 enable = false;
2539                 range = (unsigned int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
2540                 for (lightindex = 0;lightindex < range;lightindex++)
2541                 {
2542                         light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
2543                         if (!light || !(light->flags & flag))
2544                                 continue;
2545                         rtlight = &light->rtlight;
2546                         // when static, we skip styled lights because they tend to change...
2547                         if (rtlight->style > 0)
2548                                 continue;
2549                         VectorScale(rtlight->color, (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale), lightcolor);
2550                         if (!VectorLength2(lightcolor))
2551                                 continue;
2552                         enable = true;
2553                         break;
2554                 }
2555         }
2556
2557         return enable;
2558 }
2559
2560 static void R_Shadow_BounceGrid_GenerateSettings(r_shadow_bouncegrid_settings_t *settings)
2561 {
2562         qboolean s = r_shadow_bouncegrid_static.integer != 0;
2563         float spacing = bound(1.0f, s ? r_shadow_bouncegrid_static_spacing.value : r_shadow_bouncegrid_dynamic_spacing.value, 1024.0f);
2564         float quality = bound(0.0001f, (s ? r_shadow_bouncegrid_static_quality.value : r_shadow_bouncegrid_dynamic_quality.value), 1024.0f);
2565         float bounceminimumintensity = s ? r_shadow_bouncegrid_static_bounceminimumintensity.value : r_shadow_bouncegrid_dynamic_bounceminimumintensity.value;
2566
2567         // prevent any garbage in alignment padded areas as we'll be using memcmp
2568         memset(settings, 0, sizeof(*settings));
2569
2570         // build up a complete collection of the desired settings, so that memcmp can be used to compare parameters
2571         settings->staticmode                    = s;
2572         settings->blur                          = r_shadow_bouncegrid_blur.integer != 0;
2573         settings->floatcolors                   = bound(0, r_shadow_bouncegrid_floatcolors.integer, 2);
2574         settings->lightpathsize_initial         = bound(0.0f, r_shadow_bouncegrid_lightpathsize_initial.value, 1024.0f);
2575         settings->lightpathsize_conespread      = bound(0.0f, r_shadow_bouncegrid_lightpathsize_conespread.value, 1024.0f);
2576         settings->bounceanglediffuse            = r_shadow_bouncegrid_bounceanglediffuse.integer != 0;
2577         settings->directionalshading            = (s ? r_shadow_bouncegrid_static_directionalshading.integer != 0 : r_shadow_bouncegrid_dynamic_directionalshading.integer != 0) && r_shadow_bouncegrid_state.allowdirectionalshading;
2578         settings->dlightparticlemultiplier      = s ? 0 : r_shadow_bouncegrid_dynamic_dlightparticlemultiplier.value;
2579         settings->hitmodels                     = s ? false : r_shadow_bouncegrid_dynamic_hitmodels.integer != 0;
2580         settings->includedirectlighting         = r_shadow_bouncegrid_includedirectlighting.integer != 0 || r_shadow_bouncegrid.integer == 2;
2581         settings->lightradiusscale              = (s ? r_shadow_bouncegrid_static_lightradiusscale.value : r_shadow_bouncegrid_dynamic_lightradiusscale.value);
2582         settings->maxbounce                     = (s ? r_shadow_bouncegrid_static_maxbounce.integer : r_shadow_bouncegrid_dynamic_maxbounce.integer);
2583         settings->particlebounceintensity       = r_shadow_bouncegrid_particlebounceintensity.value;
2584         settings->particleintensity             = r_shadow_bouncegrid_particleintensity.value * (settings->directionalshading ? 4.0f : 1.0f) * 16384 / (spacing * spacing) / 262144.0f;
2585         settings->maxphotons                    = s ? r_shadow_bouncegrid_static_maxphotons.integer : r_shadow_bouncegrid_dynamic_maxphotons.integer;
2586         settings->energyperphoton               = spacing * spacing / quality;
2587         settings->spacing[0]                    = spacing;
2588         settings->spacing[1]                    = spacing;
2589         settings->spacing[2]                    = spacing;
2590         settings->rng_type                      = r_shadow_bouncegrid_rng_type.integer;
2591         settings->rng_seed                      = r_shadow_bouncegrid_rng_seed.integer;
2592         settings->bounceminimumintensity2       = bounceminimumintensity * bounceminimumintensity;
2593         settings->bounceminimumintensity2       = bounceminimumintensity * bounceminimumintensity;
2594         settings->normalizevectors              = r_shadow_bouncegrid_normalizevectors.integer != 0;
2595
2596         // bound the values for sanity
2597         settings->maxphotons = bound(1, settings->maxphotons, 25000000);
2598         settings->lightradiusscale = bound(0.0001f, settings->lightradiusscale, 1024.0f);
2599         settings->maxbounce = bound(0, settings->maxbounce, 16);
2600         settings->spacing[0] = bound(1, settings->spacing[0], 512);
2601         settings->spacing[1] = bound(1, settings->spacing[1], 512);
2602         settings->spacing[2] = bound(1, settings->spacing[2], 512);
2603 }
2604
2605 static void R_Shadow_BounceGrid_UpdateSpacing(void)
2606 {
2607         float m[16];
2608         int c[4];
2609         int resolution[3];
2610         int numpixels;
2611         vec3_t ispacing;
2612         vec3_t maxs;
2613         vec3_t mins;
2614         vec3_t size;
2615         vec3_t spacing;
2616         r_shadow_bouncegrid_settings_t *settings = &r_shadow_bouncegrid_state.settings;
2617
2618         // get the spacing values
2619         spacing[0] = settings->spacing[0];
2620         spacing[1] = settings->spacing[1];
2621         spacing[2] = settings->spacing[2];
2622         ispacing[0] = 1.0f / spacing[0];
2623         ispacing[1] = 1.0f / spacing[1];
2624         ispacing[2] = 1.0f / spacing[2];
2625
2626         // calculate texture size enclosing entire world bounds at the spacing
2627         if (r_refdef.scene.worldmodel)
2628         {
2629                 int lightindex;
2630                 int range;
2631                 qboolean bounds_set = false;
2632                 dlight_t *light;
2633                 rtlight_t *rtlight;
2634
2635                 // calculate bounds enclosing world lights as they should be noticably tighter 
2636                 // than the world bounds on maps with unlit monster containers (see e1m7 etc)
2637                 range = (unsigned int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
2638                 for (lightindex = 0;lightindex < range;lightindex++)
2639                 {
2640                         const vec_t *rtlmins, *rtlmaxs;
2641
2642                         light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
2643                         if (!light)
2644                                 continue;
2645
2646                         rtlight = &light->rtlight;
2647                         rtlmins = rtlight->cullmins;
2648                         rtlmaxs = rtlight->cullmaxs;
2649
2650                         if (!bounds_set)
2651                         {
2652                                 VectorCopy(rtlmins, mins);
2653                                 VectorCopy(rtlmaxs, maxs);
2654                                 bounds_set = true;
2655                         }
2656                         else
2657                         {
2658                                 mins[0] = min(mins[0], rtlmins[0]);
2659                                 mins[1] = min(mins[1], rtlmins[1]);
2660                                 mins[2] = min(mins[2], rtlmins[2]);
2661                                 maxs[0] = max(maxs[0], rtlmaxs[0]);
2662                                 maxs[1] = max(maxs[1], rtlmaxs[1]);
2663                                 maxs[2] = max(maxs[2], rtlmaxs[2]);
2664                         }
2665                 }
2666
2667                 // limit to no larger than the world bounds
2668                 mins[0] = max(mins[0], r_refdef.scene.worldmodel->normalmins[0]);
2669                 mins[1] = max(mins[1], r_refdef.scene.worldmodel->normalmins[1]);
2670                 mins[2] = max(mins[2], r_refdef.scene.worldmodel->normalmins[2]);
2671                 maxs[0] = min(maxs[0], r_refdef.scene.worldmodel->normalmaxs[0]);
2672                 maxs[1] = min(maxs[1], r_refdef.scene.worldmodel->normalmaxs[1]);
2673                 maxs[2] = min(maxs[2], r_refdef.scene.worldmodel->normalmaxs[2]);
2674
2675                 VectorMA(mins, -2.0f, spacing, mins);
2676                 VectorMA(maxs, 2.0f, spacing, maxs);
2677         }
2678         else
2679         {
2680                 VectorSet(mins, -1048576.0f, -1048576.0f, -1048576.0f);
2681                 VectorSet(maxs,  1048576.0f,  1048576.0f,  1048576.0f);
2682         }
2683         VectorSubtract(maxs, mins, size);
2684         // now we can calculate the resolution we want
2685         c[0] = (int)floor(size[0] / spacing[0] + 0.5f);
2686         c[1] = (int)floor(size[1] / spacing[1] + 0.5f);
2687         c[2] = (int)floor(size[2] / spacing[2] + 0.5f);
2688         // figure out the exact texture size (honoring power of 2 if required)
2689         c[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
2690         c[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
2691         c[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
2692         if (vid.support.arb_texture_non_power_of_two)
2693         {
2694                 resolution[0] = c[0];
2695                 resolution[1] = c[1];
2696                 resolution[2] = c[2];
2697         }
2698         else
2699         {
2700                 for (resolution[0] = 4;resolution[0] < c[0];resolution[0]*=2) ;
2701                 for (resolution[1] = 4;resolution[1] < c[1];resolution[1]*=2) ;
2702                 for (resolution[2] = 4;resolution[2] < c[2];resolution[2]*=2) ;
2703         }
2704         size[0] = spacing[0] * resolution[0];
2705         size[1] = spacing[1] * resolution[1];
2706         size[2] = spacing[2] * resolution[2];
2707
2708         // if dynamic we may or may not want to use the world bounds
2709         // if the dynamic size is smaller than the world bounds, use it instead
2710         if (!settings->staticmode && (r_shadow_bouncegrid_dynamic_x.integer * r_shadow_bouncegrid_dynamic_y.integer * r_shadow_bouncegrid_dynamic_z.integer < resolution[0] * resolution[1] * resolution[2]))
2711         {
2712                 // we know the resolution we want
2713                 c[0] = r_shadow_bouncegrid_dynamic_x.integer;
2714                 c[1] = r_shadow_bouncegrid_dynamic_y.integer;
2715                 c[2] = r_shadow_bouncegrid_dynamic_z.integer;
2716                 // now we can calculate the texture size (power of 2 if required)
2717                 c[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
2718                 c[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
2719                 c[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
2720                 if (vid.support.arb_texture_non_power_of_two)
2721                 {
2722                         resolution[0] = c[0];
2723                         resolution[1] = c[1];
2724                         resolution[2] = c[2];
2725                 }
2726                 else
2727                 {
2728                         for (resolution[0] = 4;resolution[0] < c[0];resolution[0]*=2) ;
2729                         for (resolution[1] = 4;resolution[1] < c[1];resolution[1]*=2) ;
2730                         for (resolution[2] = 4;resolution[2] < c[2];resolution[2]*=2) ;
2731                 }
2732                 size[0] = spacing[0] * resolution[0];
2733                 size[1] = spacing[1] * resolution[1];
2734                 size[2] = spacing[2] * resolution[2];
2735                 // center the rendering on the view
2736                 mins[0] = floor(r_refdef.view.origin[0] * ispacing[0] + 0.5f) * spacing[0] - 0.5f * size[0];
2737                 mins[1] = floor(r_refdef.view.origin[1] * ispacing[1] + 0.5f) * spacing[1] - 0.5f * size[1];
2738                 mins[2] = floor(r_refdef.view.origin[2] * ispacing[2] + 0.5f) * spacing[2] - 0.5f * size[2];
2739         }
2740
2741         // recalculate the maxs in case the resolution was not satisfactory
2742         VectorAdd(mins, size, maxs);
2743
2744         // check if this changed the texture size
2745         r_shadow_bouncegrid_state.createtexture = !(r_shadow_bouncegrid_state.texture && r_shadow_bouncegrid_state.resolution[0] == resolution[0] && r_shadow_bouncegrid_state.resolution[1] == resolution[1] && r_shadow_bouncegrid_state.resolution[2] == resolution[2] && r_shadow_bouncegrid_state.directional == r_shadow_bouncegrid_state.settings.directionalshading);
2746         r_shadow_bouncegrid_state.directional = r_shadow_bouncegrid_state.settings.directionalshading;
2747         VectorCopy(mins, r_shadow_bouncegrid_state.mins);
2748         VectorCopy(maxs, r_shadow_bouncegrid_state.maxs);
2749         VectorCopy(size, r_shadow_bouncegrid_state.size);
2750         VectorCopy(spacing, r_shadow_bouncegrid_state.spacing);
2751         VectorCopy(ispacing, r_shadow_bouncegrid_state.ispacing);
2752         VectorCopy(resolution, r_shadow_bouncegrid_state.resolution);
2753
2754         // reallocate pixels for this update if needed...
2755         r_shadow_bouncegrid_state.pixelbands = settings->directionalshading ? 8 : 1;
2756         r_shadow_bouncegrid_state.pixelsperband = resolution[0]*resolution[1]*resolution[2];
2757         r_shadow_bouncegrid_state.bytesperband = r_shadow_bouncegrid_state.pixelsperband*4;
2758         numpixels = r_shadow_bouncegrid_state.pixelsperband*r_shadow_bouncegrid_state.pixelbands;
2759         if (r_shadow_bouncegrid_state.numpixels != numpixels)
2760         {
2761                 if (r_shadow_bouncegrid_state.texture) R_FreeTexture(r_shadow_bouncegrid_state.texture);r_shadow_bouncegrid_state.texture = NULL;
2762                 r_shadow_bouncegrid_state.highpixels = NULL;
2763                 if (r_shadow_bouncegrid_state.blurpixels[0]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[0]); r_shadow_bouncegrid_state.blurpixels[0] = NULL;
2764                 if (r_shadow_bouncegrid_state.blurpixels[1]) Mem_Free(r_shadow_bouncegrid_state.blurpixels[1]); r_shadow_bouncegrid_state.blurpixels[1] = NULL;
2765                 if (r_shadow_bouncegrid_state.u8pixels) Mem_Free(r_shadow_bouncegrid_state.u8pixels); r_shadow_bouncegrid_state.u8pixels = NULL;
2766                 if (r_shadow_bouncegrid_state.fp16pixels) Mem_Free(r_shadow_bouncegrid_state.fp16pixels); r_shadow_bouncegrid_state.fp16pixels = NULL;
2767                 if (r_shadow_bouncegrid_state.splatpaths) Mem_Free(r_shadow_bouncegrid_state.splatpaths); r_shadow_bouncegrid_state.splatpaths = NULL;
2768                 r_shadow_bouncegrid_state.maxsplatpaths = 0;
2769                 r_shadow_bouncegrid_state.numpixels = numpixels;
2770         }
2771
2772         // update the bouncegrid matrix to put it in the world properly
2773         memset(m, 0, sizeof(m));
2774         m[0] = 1.0f / r_shadow_bouncegrid_state.size[0];
2775         m[3] = -r_shadow_bouncegrid_state.mins[0] * m[0];
2776         m[5] = 1.0f / r_shadow_bouncegrid_state.size[1];
2777         m[7] = -r_shadow_bouncegrid_state.mins[1] * m[5];
2778         m[10] = 1.0f / r_shadow_bouncegrid_state.size[2];
2779         m[11] = -r_shadow_bouncegrid_state.mins[2] * m[10];
2780         m[15] = 1.0f;
2781         Matrix4x4_FromArrayFloatD3D(&r_shadow_bouncegrid_state.matrix, m);
2782 }
2783
2784 // enumerate world rtlights and sum the overall amount of light in the world,
2785 // from that we can calculate a scaling factor to fairly distribute photons
2786 // to all the lights
2787 //
2788 // this modifies rtlight->photoncolor and rtlight->photons
2789 static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *settings, unsigned int range, unsigned int range1, unsigned int range2, int flag)
2790 {
2791         float normalphotonscaling;
2792         float photonscaling;
2793         float photonintensity;
2794         float photoncount = 0.0f;
2795         float lightintensity;
2796         float radius;
2797         float s;
2798         float w;
2799         vec3_t cullmins;
2800         vec3_t cullmaxs;
2801         unsigned int lightindex;
2802         dlight_t *light;
2803         rtlight_t *rtlight;
2804         normalphotonscaling = 1.0f / max(0.0001f, settings->energyperphoton);
2805         for (lightindex = 0;lightindex < range2;lightindex++)
2806         {
2807                 if (lightindex < range)
2808                 {
2809                         light = (dlight_t *)Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
2810                         if (!light)
2811                                 continue;
2812                         rtlight = &light->rtlight;
2813                         VectorClear(rtlight->bouncegrid_photoncolor);
2814                         rtlight->bouncegrid_photons = 0;
2815                         rtlight->bouncegrid_hits = 0;
2816                         rtlight->bouncegrid_traces = 0;
2817                         rtlight->bouncegrid_effectiveradius = 0;
2818                         if (!(light->flags & flag))
2819                                 continue;
2820                         if (settings->staticmode)
2821                         {
2822                                 // when static, we skip styled lights because they tend to change...
2823                                 if (rtlight->style > 0 && r_shadow_bouncegrid.integer != 2)
2824                                         continue;
2825                         }
2826                         else if (r_shadow_debuglight.integer >= 0 && (int)lightindex != r_shadow_debuglight.integer)
2827                                 continue;
2828                 }
2829                 else
2830                 {
2831                         rtlight = r_refdef.scene.lights[lightindex - range];
2832                         VectorClear(rtlight->bouncegrid_photoncolor);
2833                         rtlight->bouncegrid_photons = 0;
2834                         rtlight->bouncegrid_hits = 0;
2835                         rtlight->bouncegrid_traces = 0;
2836                         rtlight->bouncegrid_effectiveradius = 0;
2837                 }
2838                 // draw only visible lights (major speedup)
2839                 radius = rtlight->radius * settings->lightradiusscale;
2840                 cullmins[0] = rtlight->shadoworigin[0] - radius;
2841                 cullmins[1] = rtlight->shadoworigin[1] - radius;
2842                 cullmins[2] = rtlight->shadoworigin[2] - radius;
2843                 cullmaxs[0] = rtlight->shadoworigin[0] + radius;
2844                 cullmaxs[1] = rtlight->shadoworigin[1] + radius;
2845                 cullmaxs[2] = rtlight->shadoworigin[2] + radius;
2846                 w = r_shadow_lightintensityscale.value * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
2847                 if (!settings->staticmode)
2848                 {
2849                         if (R_CullBox(cullmins, cullmaxs))
2850                                 continue;
2851                         if (r_refdef.scene.worldmodel
2852                          && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs
2853                          && !r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, cullmins, cullmaxs))
2854                                 continue;
2855                         if (w * VectorLength2(rtlight->color) == 0.0f)
2856                                 continue;
2857                 }
2858                 // a light that does not emit any light before style is applied, can be
2859                 // skipped entirely (it may just be a corona)
2860                 if (rtlight->radius == 0.0f || VectorLength2(rtlight->color) == 0.0f)
2861                         continue;
2862                 w *= ((rtlight->style >= 0 && rtlight->style < MAX_LIGHTSTYLES) ? r_refdef.scene.rtlightstylevalue[rtlight->style] : 1);
2863                 VectorScale(rtlight->color, w, rtlight->bouncegrid_photoncolor);
2864                 // skip lights that will emit no photons
2865                 if (!VectorLength2(rtlight->bouncegrid_photoncolor))
2866                         continue;
2867                 // shoot particles from this light
2868                 // use a calculation for the number of particles that will not
2869                 // vary with lightstyle, otherwise we get randomized particle
2870                 // distribution, the seeded random is only consistent for a
2871                 // consistent number of particles on this light...
2872                 s = rtlight->radius;
2873                 lightintensity = VectorLength(rtlight->color) * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
2874                 if (lightindex >= range)
2875                         lightintensity *= settings->dlightparticlemultiplier;
2876                 rtlight->bouncegrid_photons = lightintensity * s * s * normalphotonscaling;
2877                 photoncount += rtlight->bouncegrid_photons;
2878                 VectorScale(rtlight->bouncegrid_photoncolor, settings->particleintensity * settings->energyperphoton, rtlight->bouncegrid_photoncolor);
2879                 // if the lightstyle happens to be off right now, we can skip actually
2880                 // firing the photons, but we did have to count them in the total.
2881                 //if (VectorLength2(rtlight->photoncolor) == 0.0f)
2882                 //      rtlight->bouncegrid_photons = 0;
2883         }
2884         // the user provided an energyperphoton value which we try to use
2885         // if that results in too many photons to shoot this frame, then we cap it
2886         // which causes photons to appear/disappear from frame to frame, so we don't
2887         // like doing that in the typical case
2888         photonscaling = 1.0f;
2889         photonintensity = 1.0f;
2890         if (photoncount > settings->maxphotons)
2891         {
2892                 photonscaling = settings->maxphotons / photoncount;
2893                 photonintensity = 1.0f / photonscaling;
2894         }
2895
2896         // modify the lights to reflect our computed scaling
2897         for (lightindex = 0; lightindex < range2; lightindex++)
2898         {
2899                 if (lightindex < range)
2900                 {
2901                         light = (dlight_t *)Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
2902                         if (!light)
2903                                 continue;
2904                         rtlight = &light->rtlight;
2905                 }
2906                 else
2907                         rtlight = r_refdef.scene.lights[lightindex - range];
2908                 rtlight->bouncegrid_photons *= photonscaling;
2909                 VectorScale(rtlight->bouncegrid_photoncolor, photonintensity, rtlight->bouncegrid_photoncolor);
2910         }
2911 }
2912
2913 static int R_Shadow_BounceGrid_SplatPathCompare(const void *pa, const void *pb)
2914 {
2915         r_shadow_bouncegrid_splatpath_t *a = (r_shadow_bouncegrid_splatpath_t *)pa;
2916         r_shadow_bouncegrid_splatpath_t *b = (r_shadow_bouncegrid_splatpath_t *)pb;
2917         // we only really care about sorting by Z
2918         if (a->point[2] < b->point[2])
2919                 return -1;
2920         if (a->point[2] > b->point[2])
2921                 return 1;
2922         return 0;
2923 }
2924
2925 static void R_Shadow_BounceGrid_ClearPixels(void)
2926 {
2927         // clear the highpixels array we'll be accumulating into
2928         if (r_shadow_bouncegrid_state.blurpixels[0] == NULL)
2929                 r_shadow_bouncegrid_state.blurpixels[0] = (float *)Mem_Alloc(r_main_mempool, r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
2930         if (r_shadow_bouncegrid_state.settings.blur && r_shadow_bouncegrid_state.blurpixels[1] == NULL)
2931                 r_shadow_bouncegrid_state.blurpixels[1] = (float *)Mem_Alloc(r_main_mempool, r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
2932         r_shadow_bouncegrid_state.highpixels_index = 0;
2933         r_shadow_bouncegrid_state.highpixels = r_shadow_bouncegrid_state.blurpixels[r_shadow_bouncegrid_state.highpixels_index];
2934         memset(r_shadow_bouncegrid_state.highpixels, 0, r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
2935 }
2936
2937 static void R_Shadow_BounceGrid_PerformSplats(void)
2938 {
2939         r_shadow_bouncegrid_splatpath_t *splatpaths = r_shadow_bouncegrid_state.splatpaths;
2940         r_shadow_bouncegrid_splatpath_t *splatpath;
2941         float *highpixels = r_shadow_bouncegrid_state.highpixels;
2942         int numsplatpaths = r_shadow_bouncegrid_state.numsplatpaths;
2943         int splatindex;
2944         vec3_t steppos;
2945         vec3_t stepdelta;
2946         vec3_t dir;
2947         vec_t lightpathsize_current;
2948         vec_t lightpathsize_perstep;
2949         float splatcolor[32];
2950         int resolution[3];
2951         int pixelsperband = r_shadow_bouncegrid_state.pixelsperband;
2952         int pixelbands = r_shadow_bouncegrid_state.pixelbands;
2953         int numsteps;
2954         int step;
2955
2956         // hush warnings about uninitialized data - pixelbands doesn't change but...
2957         memset(splatcolor, 0, sizeof(splatcolor));
2958
2959         // we use this a lot, so get a local copy
2960         VectorCopy(r_shadow_bouncegrid_state.resolution, resolution);
2961
2962         // sort the splats before we execute them, to reduce cache misses
2963         if (r_shadow_bouncegrid_sortlightpaths.integer)
2964                 qsort(splatpaths, numsplatpaths, sizeof(*splatpaths), R_Shadow_BounceGrid_SplatPathCompare);
2965
2966         splatpath = splatpaths;
2967         for (splatindex = 0;splatindex < numsplatpaths;splatindex++, splatpath++)
2968         {
2969                 // calculate second order spherical harmonics values (average, slopeX, slopeY, slopeZ)
2970                 // accumulate average shotcolor
2971                 VectorCopy(splatpath->splatdir, dir);
2972                 splatcolor[ 0] = splatpath->splatcolor[0];
2973                 splatcolor[ 1] = splatpath->splatcolor[1];
2974                 splatcolor[ 2] = splatpath->splatcolor[2];
2975                 splatcolor[ 3] = 0.0f;
2976                 if (pixelbands > 1)
2977                 {
2978                         // store bentnormal in case the shader has a use for it,
2979                         // bentnormal is an intensity-weighted average of the directions,
2980                         // and will be normalized on conversion to texture pixels.
2981                         splatcolor[ 4] = dir[0] * splatpath->splatintensity;
2982                         splatcolor[ 5] = dir[1] * splatpath->splatintensity;
2983                         splatcolor[ 6] = dir[2] * splatpath->splatintensity;
2984                         splatcolor[ 7] = splatpath->splatintensity;
2985                         // for each color component (R, G, B) calculate the amount that a
2986                         // direction contributes
2987                         splatcolor[ 8] = splatcolor[0] * max(0.0f, dir[0]);
2988                         splatcolor[ 9] = splatcolor[0] * max(0.0f, dir[1]);
2989                         splatcolor[10] = splatcolor[0] * max(0.0f, dir[2]);
2990                         splatcolor[11] = 0.0f;
2991                         splatcolor[12] = splatcolor[1] * max(0.0f, dir[0]);
2992                         splatcolor[13] = splatcolor[1] * max(0.0f, dir[1]);
2993                         splatcolor[14] = splatcolor[1] * max(0.0f, dir[2]);
2994                         splatcolor[15] = 0.0f;
2995                         splatcolor[16] = splatcolor[2] * max(0.0f, dir[0]);
2996                         splatcolor[17] = splatcolor[2] * max(0.0f, dir[1]);
2997                         splatcolor[18] = splatcolor[2] * max(0.0f, dir[2]);
2998                         splatcolor[19] = 0.0f;
2999                         // and do the same for negative directions
3000                         splatcolor[20] = splatcolor[0] * max(0.0f, -dir[0]);
3001                         splatcolor[21] = splatcolor[0] * max(0.0f, -dir[1]);
3002                         splatcolor[22] = splatcolor[0] * max(0.0f, -dir[2]);
3003                         splatcolor[23] = 0.0f;
3004                         splatcolor[24] = splatcolor[1] * max(0.0f, -dir[0]);
3005                         splatcolor[25] = splatcolor[1] * max(0.0f, -dir[1]);
3006                         splatcolor[26] = splatcolor[1] * max(0.0f, -dir[2]);
3007                         splatcolor[27] = 0.0f;
3008                         splatcolor[28] = splatcolor[2] * max(0.0f, -dir[0]);
3009                         splatcolor[29] = splatcolor[2] * max(0.0f, -dir[1]);
3010                         splatcolor[30] = splatcolor[2] * max(0.0f, -dir[2]);
3011                         splatcolor[31] = 0.0f;
3012                 }
3013                 // calculate the number of steps we need to traverse this distance
3014                 VectorCopy(splatpath->point, steppos);
3015                 VectorCopy(splatpath->step, stepdelta);
3016                 numsteps = splatpath->remainingsplats;
3017                 lightpathsize_current = splatpath->splatsize_current + 1.0f; // add 1.0 for the gradient fade around the sphere
3018                 lightpathsize_perstep = splatpath->splatsize_perstep;
3019                 for (step = 0;step < numsteps;step++)
3020                 {
3021                         // the middle row/column/layer of each splat are full intensity
3022                         float splatmins[3];
3023                         float splatmaxs[3];
3024                         if (lightpathsize_current > MAXBOUNCEGRIDSPLATSIZE)
3025                                 lightpathsize_current = MAXBOUNCEGRIDSPLATSIZE;
3026                         splatmins[0] = max(1.0f, steppos[0] - lightpathsize_current * 0.5f);
3027                         splatmins[1] = max(1.0f, steppos[1] - lightpathsize_current * 0.5f);
3028                         splatmins[2] = max(1.0f, steppos[2] - lightpathsize_current * 0.5f);
3029                         splatmaxs[0] = min(steppos[0] + lightpathsize_current * 0.5f, resolution[0] - 1.0f);
3030                         splatmaxs[1] = min(steppos[1] + lightpathsize_current * 0.5f, resolution[1] - 1.0f);
3031                         splatmaxs[2] = min(steppos[2] + lightpathsize_current * 0.5f, resolution[2] - 1.0f);
3032                         if (splatmaxs[0] > splatmins[0] && splatmaxs[1] > splatmins[1] && splatmaxs[2] > splatmins[2])
3033                         {
3034                                 // it is within bounds...  do the real work now
3035                                 int xi, yi, zi, band, row;
3036                                 float pixelpos[3];
3037                                 float w;
3038                                 float *p;
3039                                 float colorscale = 1.0f / lightpathsize_current;
3040                                 r_refdef.stats[r_stat_bouncegrid_splats]++;
3041                                 // accumulate light onto the pixels
3042                                 for (zi = (int)floor(splatmins[2]);zi < splatmaxs[2];zi++)
3043                                 {
3044                                         pixelpos[2] = zi + 0.5f;
3045                                         for (yi = (int)floor(splatmins[1]); yi < splatmaxs[1]; yi++)
3046                                         {
3047                                                 pixelpos[1] = yi + 0.5f;
3048                                                 row = (zi*resolution[1] + yi)*resolution[0];
3049                                                 for (xi = (int)floor(splatmins[0]); xi < splatmaxs[0]; xi++)
3050                                                 {
3051                                                         pixelpos[0] = xi + 0.5f;
3052                                                         // simple radial antialiased sphere - linear gradient fade over 1 pixel from the edge
3053                                                         w = lightpathsize_current - VectorDistance(pixelpos, steppos);
3054                                                         if (w > 0.0f)
3055                                                         {
3056                                                                 if (w > 1.0f)
3057                                                                         w = 1.0f;
3058                                                                 w *= colorscale;
3059                                                                 p = highpixels + 4 * (row + xi);
3060                                                                 for (band = 0; band < pixelbands; band++, p +