a5e9922585124fce072e32ddbcc5e01a709237a8
[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 qboolean r_shadow_usingshadowmap2d;
183 qboolean r_shadow_usingshadowmaportho;
184 int r_shadow_shadowmapside;
185 float r_shadow_shadowmap_texturescale[2];
186 float r_shadow_shadowmap_parameters[4];
187 #if 0
188 int r_shadow_drawbuffer;
189 int r_shadow_readbuffer;
190 #endif
191 int r_shadow_cullface_front, r_shadow_cullface_back;
192 GLuint r_shadow_fbo2d;
193 r_shadow_shadowmode_t r_shadow_shadowmode;
194 int r_shadow_shadowmapfilterquality;
195 int r_shadow_shadowmapdepthbits;
196 int r_shadow_shadowmapmaxsize;
197 qboolean r_shadow_shadowmapvsdct;
198 qboolean r_shadow_shadowmapsampler;
199 qboolean r_shadow_shadowmapshadowsampler;
200 int r_shadow_shadowmappcf;
201 int r_shadow_shadowmapborder;
202 matrix4x4_t r_shadow_shadowmapmatrix;
203 int r_shadow_lightscissor[4];
204 qboolean r_shadow_usingdeferredprepass;
205 qboolean r_shadow_shadowmapdepthtexture;
206 int maxshadowtriangles;
207 int *shadowelements;
208
209 int maxshadowvertices;
210 float *shadowvertex3f;
211
212 int maxshadowmark;
213 int numshadowmark;
214 int *shadowmark;
215 int *shadowmarklist;
216 int shadowmarkcount;
217
218 int maxshadowsides;
219 int numshadowsides;
220 unsigned char *shadowsides;
221 int *shadowsideslist;
222
223 int maxvertexupdate;
224 int *vertexupdate;
225 int *vertexremap;
226 int vertexupdatenum;
227
228 int r_shadow_buffer_numleafpvsbytes;
229 unsigned char *r_shadow_buffer_visitingleafpvs;
230 unsigned char *r_shadow_buffer_leafpvs;
231 int *r_shadow_buffer_leaflist;
232
233 int r_shadow_buffer_numsurfacepvsbytes;
234 unsigned char *r_shadow_buffer_surfacepvs;
235 int *r_shadow_buffer_surfacelist;
236 unsigned char *r_shadow_buffer_surfacesides;
237
238 int r_shadow_buffer_numshadowtrispvsbytes;
239 unsigned char *r_shadow_buffer_shadowtrispvs;
240 int r_shadow_buffer_numlighttrispvsbytes;
241 unsigned char *r_shadow_buffer_lighttrispvs;
242
243 rtexturepool_t *r_shadow_texturepool;
244 rtexture_t *r_shadow_attenuationgradienttexture;
245 rtexture_t *r_shadow_attenuation2dtexture;
246 rtexture_t *r_shadow_attenuation3dtexture;
247 skinframe_t *r_shadow_lightcorona;
248 rtexture_t *r_shadow_shadowmap2ddepthbuffer;
249 rtexture_t *r_shadow_shadowmap2ddepthtexture;
250 rtexture_t *r_shadow_shadowmapvsdcttexture;
251 int r_shadow_shadowmapsize; // changes for each light based on distance
252 int r_shadow_shadowmaplod; // changes for each light based on distance
253
254 GLuint r_shadow_prepassgeometryfbo;
255 GLuint r_shadow_prepasslightingdiffusespecularfbo;
256 GLuint r_shadow_prepasslightingdiffusefbo;
257 int r_shadow_prepass_width;
258 int r_shadow_prepass_height;
259 rtexture_t *r_shadow_prepassgeometrydepthbuffer;
260 rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
261 rtexture_t *r_shadow_prepasslightingdiffusetexture;
262 rtexture_t *r_shadow_prepasslightingspeculartexture;
263
264 // keep track of the provided framebuffer info
265 static int r_shadow_fb_fbo;
266 static rtexture_t *r_shadow_fb_depthtexture;
267 static rtexture_t *r_shadow_fb_colortexture;
268
269 // lights are reloaded when this changes
270 char r_shadow_mapname[MAX_QPATH];
271
272 // buffer for doing corona fading
273 unsigned int r_shadow_occlusion_buf = 0;
274
275 // used only for light filters (cubemaps)
276 rtexturepool_t *r_shadow_filters_texturepool;
277
278 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"};
279 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"};
280 cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1", "renders only one light, for level design purposes or debugging"};
281 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"};
282 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)"};
283 cvar_t r_shadow_usenormalmap = {CVAR_SAVE, "r_shadow_usenormalmap", "1", "enables use of directional shading on lights"};
284 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)"};
285 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"};
286 cvar_t r_shadow_glossintensity = {0, "r_shadow_glossintensity", "1", "how bright textured glossmaps should look if r_shadow_gloss is 1 or 2"};
287 cvar_t r_shadow_glossexponent = {0, "r_shadow_glossexponent", "32", "how 'sharp' the gloss should appear (specular power)"};
288 cvar_t r_shadow_gloss2exponent = {0, "r_shadow_gloss2exponent", "32", "same as r_shadow_glossexponent but for forced gloss (gloss 2) surfaces"};
289 cvar_t r_shadow_glossexact = {0, "r_shadow_glossexact", "0", "use exact reflection math for gloss (slightly slower, but should look a tad better)"};
290 cvar_t r_shadow_lightattenuationdividebias = {0, "r_shadow_lightattenuationdividebias", "1", "changes attenuation texture generation"};
291 cvar_t r_shadow_lightattenuationlinearscale = {0, "r_shadow_lightattenuationlinearscale", "2", "changes attenuation texture generation"};
292 cvar_t r_shadow_lightintensityscale = {0, "r_shadow_lightintensityscale", "1", "renders all world lights brighter or darker"};
293 cvar_t r_shadow_lightradiusscale = {0, "r_shadow_lightradiusscale", "1", "renders all world lights larger or smaller"};
294 cvar_t r_shadow_projectdistance = {0, "r_shadow_projectdistance", "0", "how far to cast shadows"};
295 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)"};
296 cvar_t r_shadow_realtime_dlight = {CVAR_SAVE, "r_shadow_realtime_dlight", "1", "enables rendering of dynamic lights such as explosions and rocket light"};
297 cvar_t r_shadow_realtime_dlight_shadows = {CVAR_SAVE, "r_shadow_realtime_dlight_shadows", "1", "enables rendering of shadows from dynamic lights"};
298 cvar_t r_shadow_realtime_dlight_svbspculling = {0, "r_shadow_realtime_dlight_svbspculling", "0", "enables svbsp optimization on dynamic lights (very slow!)"};
299 cvar_t r_shadow_realtime_dlight_portalculling = {0, "r_shadow_realtime_dlight_portalculling", "0", "enables portal optimization on dynamic lights (slow!)"};
300 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)"};
301 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)"};
302 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"};
303 cvar_t r_shadow_realtime_world_shadows = {CVAR_SAVE, "r_shadow_realtime_world_shadows", "1", "enables rendering of shadows from world lights"};
304 cvar_t r_shadow_realtime_world_compile = {0, "r_shadow_realtime_world_compile", "1", "enables compilation of world lights for higher performance rendering"};
305 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"};
306 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)"};
307 cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "1", "enables portal-based culling optimization during compilation (overrides compilesvbsp)"};
308 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)"};
309 cvar_t r_shadow_shadowmapping = {CVAR_SAVE, "r_shadow_shadowmapping", "1", "enables use of shadowmapping (depth texture sampling) instead of stencil shadow volumes, requires gl_fbo 1"};
310 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)"};
311 cvar_t r_shadow_shadowmapping_useshadowsampler = {CVAR_SAVE, "r_shadow_shadowmapping_useshadowsampler", "1", "whether to use sampler2DShadow if available"};
312 cvar_t r_shadow_shadowmapping_depthbits = {CVAR_SAVE, "r_shadow_shadowmapping_depthbits", "24", "requested minimum shadowmap texture depth bits"};
313 cvar_t r_shadow_shadowmapping_vsdct = {CVAR_SAVE, "r_shadow_shadowmapping_vsdct", "1", "enables use of virtual shadow depth cube texture"};
314 cvar_t r_shadow_shadowmapping_minsize = {CVAR_SAVE, "r_shadow_shadowmapping_minsize", "32", "shadowmap size limit"};
315 cvar_t r_shadow_shadowmapping_maxsize = {CVAR_SAVE, "r_shadow_shadowmapping_maxsize", "512", "shadowmap size limit"};
316 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"};
317 //cvar_t r_shadow_shadowmapping_lod_bias = {CVAR_SAVE, "r_shadow_shadowmapping_lod_bias", "16", "shadowmap size bias"};
318 //cvar_t r_shadow_shadowmapping_lod_scale = {CVAR_SAVE, "r_shadow_shadowmapping_lod_scale", "128", "shadowmap size scaling parameter"};
319 cvar_t r_shadow_shadowmapping_bordersize = {CVAR_SAVE, "r_shadow_shadowmapping_bordersize", "4", "shadowmap size bias for filtering"};
320 cvar_t r_shadow_shadowmapping_nearclip = {CVAR_SAVE, "r_shadow_shadowmapping_nearclip", "1", "shadowmap nearclip in world units"};
321 cvar_t r_shadow_shadowmapping_bias = {CVAR_SAVE, "r_shadow_shadowmapping_bias", "0.03", "shadowmap bias parameter (this is multiplied by nearclip * 1024 / lodsize)"};
322 cvar_t r_shadow_shadowmapping_polygonfactor = {CVAR_SAVE, "r_shadow_shadowmapping_polygonfactor", "2", "slope-dependent shadowmapping bias"};
323 cvar_t r_shadow_shadowmapping_polygonoffset = {CVAR_SAVE, "r_shadow_shadowmapping_polygonoffset", "0", "constant shadowmapping bias"};
324 cvar_t r_shadow_sortsurfaces = {0, "r_shadow_sortsurfaces", "1", "improve performance by sorting illuminated surfaces by texture"};
325 cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"};
326 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)"};
327 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)"};
328 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)"};
329 cvar_t r_shadow_bouncegrid_blur = {CVAR_SAVE, "r_shadow_bouncegrid_blur", "1", "apply a 1-radius blur on bouncegrid to denoise it and deal with boundary issues with surfaces"};
330 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"};
331 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)"};
332 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"};
333 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"};
334 cvar_t r_shadow_bouncegrid_dynamic_hitmodels = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_hitmodels", "0", "enables hitting character model geometry (SLOW)"};
335 cvar_t r_shadow_bouncegrid_dynamic_energyperphoton = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_energyperphoton", "10000", "amount of light that one photon should represent"};
336 cvar_t r_shadow_bouncegrid_dynamic_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_lightradiusscale", "4", "particles stop at this fraction of light radius (can be more than 1)"};
337 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)"};
338 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"};
339 cvar_t r_shadow_bouncegrid_dynamic_spacing = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_spacing", "64", "unit size of bouncegrid pixel"};
340 cvar_t r_shadow_bouncegrid_dynamic_stablerandom = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_stablerandom", "1", "make particle distribution consistent from frame to frame"};
341 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"};
342 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)"};
343 cvar_t r_shadow_bouncegrid_intensity = {CVAR_SAVE, "r_shadow_bouncegrid_intensity", "4", "overall brightness of bouncegrid texture"};
344 cvar_t r_shadow_bouncegrid_particlebounceintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particlebounceintensity", "1", "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"};
345 cvar_t r_shadow_bouncegrid_particleintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particleintensity", "1", "brightness of particles contributing to bouncegrid texture"};
346 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"};
347 cvar_t r_shadow_bouncegrid_static = {CVAR_SAVE, "r_shadow_bouncegrid_static", "1", "use static radiosity solution (high quality) rather than dynamic (splotchy)"};
348 cvar_t r_shadow_bouncegrid_static_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_static_directionalshading", "1", "whether to use directionalshading when in static mode"};
349 cvar_t r_shadow_bouncegrid_static_energyperphoton = {CVAR_SAVE, "r_shadow_bouncegrid_static_energyperphoton", "1000", "amount of light that one photon should represent in static mode"};
350 cvar_t r_shadow_bouncegrid_static_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_static_lightradiusscale", "10", "particles stop at this fraction of light radius (can be more than 1) when in static mode"};
351 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"};
352 cvar_t r_shadow_bouncegrid_static_maxphotons = {CVAR_SAVE, "r_shadow_bouncegrid_static_maxphotons", "250000", "upper bound on photons in static mode"};
353 cvar_t r_shadow_bouncegrid_static_spacing = {CVAR_SAVE, "r_shadow_bouncegrid_static_spacing", "32", "unit size of bouncegrid pixel when in static mode"};
354 cvar_t r_shadow_bouncegrid_x = {CVAR_SAVE, "r_shadow_bouncegrid_x", "64", "maximum texture size of bouncegrid on X axis"};
355 cvar_t r_shadow_bouncegrid_y = {CVAR_SAVE, "r_shadow_bouncegrid_y", "64", "maximum texture size of bouncegrid on Y axis"};
356 cvar_t r_shadow_bouncegrid_z = {CVAR_SAVE, "r_shadow_bouncegrid_z", "32", "maximum texture size of bouncegrid on Z axis"};
357 cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "0", "brightness of corona flare effects around certain lights, 0 disables corona effects"};
358 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"};
359 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!"};
360 cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"};
361 cvar_t gl_ext_separatestencil = {0, "gl_ext_separatestencil", "1", "make use of OpenGL 2.0 glStencilOpSeparate or GL_ATI_separate_stencil extension"};
362 cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1", "make use of GL_EXT_stenciltwoside extension (NVIDIA only)"};
363 cvar_t r_editlights = {0, "r_editlights", "0", "enables .rtlights file editing mode"};
364 cvar_t r_editlights_cursordistance = {0, "r_editlights_cursordistance", "1024", "maximum distance of cursor from eye"};
365 cvar_t r_editlights_cursorpushback = {0, "r_editlights_cursorpushback", "0", "how far to pull the cursor back toward the eye"};
366 cvar_t r_editlights_cursorpushoff = {0, "r_editlights_cursorpushoff", "4", "how far to push the cursor off the impacted surface"};
367 cvar_t r_editlights_cursorgrid = {0, "r_editlights_cursorgrid", "4", "snaps cursor to this grid size"};
368 cvar_t r_editlights_quakelightsizescale = {CVAR_SAVE, "r_editlights_quakelightsizescale", "1", "changes size of light entities loaded from a map"};
369 cvar_t r_editlights_drawproperties = {0, "r_editlights_drawproperties", "1", "draw properties of currently selected light"};
370 cvar_t r_editlights_current_origin = {0, "r_editlights_current_origin", "0 0 0", "origin of selected light"};
371 cvar_t r_editlights_current_angles = {0, "r_editlights_current_angles", "0 0 0", "angles of selected light"};
372 cvar_t r_editlights_current_color = {0, "r_editlights_current_color", "1 1 1", "color of selected light"};
373 cvar_t r_editlights_current_radius = {0, "r_editlights_current_radius", "0", "radius of selected light"};
374 cvar_t r_editlights_current_corona = {0, "r_editlights_current_corona", "0", "corona intensity of selected light"};
375 cvar_t r_editlights_current_coronasize = {0, "r_editlights_current_coronasize", "0", "corona size of selected light"};
376 cvar_t r_editlights_current_style = {0, "r_editlights_current_style", "0", "style of selected light"};
377 cvar_t r_editlights_current_shadows = {0, "r_editlights_current_shadows", "0", "shadows flag of selected light"};
378 cvar_t r_editlights_current_cubemap = {0, "r_editlights_current_cubemap", "0", "cubemap of selected light"};
379 cvar_t r_editlights_current_ambient = {0, "r_editlights_current_ambient", "0", "ambient intensity of selected light"};
380 cvar_t r_editlights_current_diffuse = {0, "r_editlights_current_diffuse", "1", "diffuse intensity of selected light"};
381 cvar_t r_editlights_current_specular = {0, "r_editlights_current_specular", "1", "specular intensity of selected light"};
382 cvar_t r_editlights_current_normalmode = {0, "r_editlights_current_normalmode", "0", "normalmode flag of selected light"};
383 cvar_t r_editlights_current_realtimemode = {0, "r_editlights_current_realtimemode", "0", "realtimemode flag of selected light"};
384
385 r_shadow_bouncegrid_state_t r_shadow_bouncegrid_state;
386
387 // note the table actually includes one more value, just to avoid the need to clamp the distance index due to minor math error
388 #define ATTENTABLESIZE 256
389 // 1D gradient, 2D circle and 3D sphere attenuation textures
390 #define ATTEN1DSIZE 32
391 #define ATTEN2DSIZE 64
392 #define ATTEN3DSIZE 32
393
394 static float r_shadow_attendividebias; // r_shadow_lightattenuationdividebias
395 static float r_shadow_attenlinearscale; // r_shadow_lightattenuationlinearscale
396 static float r_shadow_attentable[ATTENTABLESIZE+1];
397
398 rtlight_t *r_shadow_compilingrtlight;
399 static memexpandablearray_t r_shadow_worldlightsarray;
400 dlight_t *r_shadow_selectedlight;
401 dlight_t r_shadow_bufferlight;
402 vec3_t r_editlights_cursorlocation;
403 qboolean r_editlights_lockcursor;
404
405 extern int con_vislines;
406
407 void R_Shadow_UncompileWorldLights(void);
408 void R_Shadow_ClearWorldLights(void);
409 void R_Shadow_SaveWorldLights(void);
410 void R_Shadow_LoadWorldLights(void);
411 void R_Shadow_LoadLightsFile(void);
412 void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void);
413 void R_Shadow_EditLights_Reload_f(void);
414 void R_Shadow_ValidateCvars(void);
415 static void R_Shadow_MakeTextures(void);
416
417 #define EDLIGHTSPRSIZE                  8
418 skinframe_t *r_editlights_sprcursor;
419 skinframe_t *r_editlights_sprlight;
420 skinframe_t *r_editlights_sprnoshadowlight;
421 skinframe_t *r_editlights_sprcubemaplight;
422 skinframe_t *r_editlights_sprcubemapnoshadowlight;
423 skinframe_t *r_editlights_sprselection;
424
425 static void R_Shadow_SetShadowMode(void)
426 {
427         r_shadow_shadowmapmaxsize = bound(1, r_shadow_shadowmapping_maxsize.integer, (int)vid.maxtexturesize_2d / 4);
428         r_shadow_shadowmapvsdct = r_shadow_shadowmapping_vsdct.integer != 0 && vid.renderpath == RENDERPATH_GL20;
429         r_shadow_shadowmapfilterquality = r_shadow_shadowmapping_filterquality.integer;
430         r_shadow_shadowmapshadowsampler = r_shadow_shadowmapping_useshadowsampler.integer != 0;
431         r_shadow_shadowmapdepthbits = r_shadow_shadowmapping_depthbits.integer;
432         r_shadow_shadowmapborder = bound(0, r_shadow_shadowmapping_bordersize.integer, 16);
433         r_shadow_shadowmaplod = -1;
434         r_shadow_shadowmapsize = 0;
435         r_shadow_shadowmapsampler = false;
436         r_shadow_shadowmappcf = 0;
437         r_shadow_shadowmapdepthtexture = r_fb.usedepthtextures;
438         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_STENCIL;
439         if ((r_shadow_shadowmapping.integer || r_shadow_deferred.integer) && vid.support.ext_framebuffer_object)
440         {
441                 switch(vid.renderpath)
442                 {
443                 case RENDERPATH_GL20:
444                         if(r_shadow_shadowmapfilterquality < 0)
445                         {
446                                 if (!r_fb.usedepthtextures)
447                                         r_shadow_shadowmappcf = 1;
448                                 else if((strstr(gl_vendor, "NVIDIA") || strstr(gl_renderer, "Radeon HD")) && vid.support.arb_shadow && r_shadow_shadowmapshadowsampler) 
449                                 {
450                                         r_shadow_shadowmapsampler = true;
451                                         r_shadow_shadowmappcf = 1;
452                                 }
453                                 else if(vid.support.amd_texture_texture4 || vid.support.arb_texture_gather)
454                                         r_shadow_shadowmappcf = 1;
455                                 else if((strstr(gl_vendor, "ATI") || strstr(gl_vendor, "Advanced Micro Devices")) && !strstr(gl_renderer, "Mesa") && !strstr(gl_version, "Mesa")) 
456                                         r_shadow_shadowmappcf = 1;
457                                 else 
458                                         r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler;
459                         }
460                         else 
461                         {
462                 r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler;
463                                 switch (r_shadow_shadowmapfilterquality)
464                                 {
465                                 case 1:
466                                         break;
467                                 case 2:
468                                         r_shadow_shadowmappcf = 1;
469                                         break;
470                                 case 3:
471                                         r_shadow_shadowmappcf = 1;
472                                         break;
473                                 case 4:
474                                         r_shadow_shadowmappcf = 2;
475                                         break;
476                                 }
477                         }
478                         if (!r_fb.usedepthtextures)
479                                 r_shadow_shadowmapsampler = false;
480                         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D;
481                         break;
482                 case RENDERPATH_D3D9:
483                 case RENDERPATH_D3D10:
484                 case RENDERPATH_D3D11:
485                 case RENDERPATH_SOFT:
486                         r_shadow_shadowmapsampler = false;
487                         r_shadow_shadowmappcf = 1;
488                         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D;
489                         break;
490                 case RENDERPATH_GL11:
491                 case RENDERPATH_GL13:
492                 case RENDERPATH_GLES1:
493                 case RENDERPATH_GLES2:
494                         break;
495                 }
496         }
497
498         if(R_CompileShader_CheckStaticParms())
499                 R_GLSL_Restart_f();
500 }
501
502 qboolean R_Shadow_ShadowMappingEnabled(void)
503 {
504         switch (r_shadow_shadowmode)
505         {
506         case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
507                 return true;
508         default:
509                 return false;
510         }
511 }
512
513 static void R_Shadow_FreeShadowMaps(void)
514 {
515         R_Shadow_SetShadowMode();
516
517         R_Mesh_DestroyFramebufferObject(r_shadow_fbo2d);
518
519         r_shadow_fbo2d = 0;
520
521         if (r_shadow_shadowmap2ddepthtexture)
522                 R_FreeTexture(r_shadow_shadowmap2ddepthtexture);
523         r_shadow_shadowmap2ddepthtexture = NULL;
524
525         if (r_shadow_shadowmap2ddepthbuffer)
526                 R_FreeTexture(r_shadow_shadowmap2ddepthbuffer);
527         r_shadow_shadowmap2ddepthbuffer = NULL;
528
529         if (r_shadow_shadowmapvsdcttexture)
530                 R_FreeTexture(r_shadow_shadowmapvsdcttexture);
531         r_shadow_shadowmapvsdcttexture = NULL;
532 }
533
534 static void r_shadow_start(void)
535 {
536         // allocate vertex processing arrays
537         memset(&r_shadow_bouncegrid_state, 0, sizeof(r_shadow_bouncegrid_state));
538         r_shadow_bouncegrid_state.maxsplatpaths = 16384;
539         r_shadow_attenuationgradienttexture = NULL;
540         r_shadow_attenuation2dtexture = NULL;
541         r_shadow_attenuation3dtexture = NULL;
542         r_shadow_shadowmode = R_SHADOW_SHADOWMODE_STENCIL;
543         r_shadow_shadowmap2ddepthtexture = NULL;
544         r_shadow_shadowmap2ddepthbuffer = NULL;
545         r_shadow_shadowmapvsdcttexture = NULL;
546         r_shadow_shadowmapmaxsize = 0;
547         r_shadow_shadowmapsize = 0;
548         r_shadow_shadowmaplod = 0;
549         r_shadow_shadowmapfilterquality = -1;
550         r_shadow_shadowmapdepthbits = 0;
551         r_shadow_shadowmapvsdct = false;
552         r_shadow_shadowmapsampler = false;
553         r_shadow_shadowmappcf = 0;
554         r_shadow_fbo2d = 0;
555
556         R_Shadow_FreeShadowMaps();
557
558         r_shadow_texturepool = NULL;
559         r_shadow_filters_texturepool = NULL;
560         R_Shadow_ValidateCvars();
561         R_Shadow_MakeTextures();
562         maxshadowtriangles = 0;
563         shadowelements = NULL;
564         maxshadowvertices = 0;
565         shadowvertex3f = NULL;
566         maxvertexupdate = 0;
567         vertexupdate = NULL;
568         vertexremap = NULL;
569         vertexupdatenum = 0;
570         maxshadowmark = 0;
571         numshadowmark = 0;
572         shadowmark = NULL;
573         shadowmarklist = NULL;
574         shadowmarkcount = 0;
575         maxshadowsides = 0;
576         numshadowsides = 0;
577         shadowsides = NULL;
578         shadowsideslist = NULL;
579         r_shadow_buffer_numleafpvsbytes = 0;
580         r_shadow_buffer_visitingleafpvs = NULL;
581         r_shadow_buffer_leafpvs = NULL;
582         r_shadow_buffer_leaflist = NULL;
583         r_shadow_buffer_numsurfacepvsbytes = 0;
584         r_shadow_buffer_surfacepvs = NULL;
585         r_shadow_buffer_surfacelist = NULL;
586         r_shadow_buffer_surfacesides = NULL;
587         r_shadow_buffer_numshadowtrispvsbytes = 0;
588         r_shadow_buffer_shadowtrispvs = NULL;
589         r_shadow_buffer_numlighttrispvsbytes = 0;
590         r_shadow_buffer_lighttrispvs = NULL;
591
592         r_shadow_usingdeferredprepass = false;
593         r_shadow_prepass_width = r_shadow_prepass_height = 0;
594
595         // determine renderpath specific capabilities, we don't need to figure
596         // these out per frame...
597         switch(vid.renderpath)
598         {
599         case RENDERPATH_GL20:
600                 r_shadow_bouncegrid_state.allowdirectionalshading = true;
601                 r_shadow_bouncegrid_state.capable = vid.support.ext_texture_3d;
602                 break;
603         case RENDERPATH_GLES2:
604                 // for performance reasons, do not use directional shading on GLES devices
605                 r_shadow_bouncegrid_state.capable = vid.support.ext_texture_3d;
606                 break;
607                 // these renderpaths do not currently have the code to display the bouncegrid, so disable it on them...
608         case RENDERPATH_GL11:
609         case RENDERPATH_GL13:
610         case RENDERPATH_GLES1:
611         case RENDERPATH_SOFT:
612         case RENDERPATH_D3D9:
613         case RENDERPATH_D3D10:
614         case RENDERPATH_D3D11:
615                 break;
616         }
617 }
618
619 static void R_Shadow_FreeDeferred(void);
620 static void r_shadow_shutdown(void)
621 {
622         CHECKGLERROR
623         R_Shadow_UncompileWorldLights();
624
625         R_Shadow_FreeShadowMaps();
626
627         r_shadow_usingdeferredprepass = false;
628         if (r_shadow_prepass_width)
629                 R_Shadow_FreeDeferred();
630         r_shadow_prepass_width = r_shadow_prepass_height = 0;
631
632         CHECKGLERROR
633         memset(&r_shadow_bouncegrid_state, 0, sizeof(r_shadow_bouncegrid_state));
634         r_shadow_attenuationgradienttexture = NULL;
635         r_shadow_attenuation2dtexture = NULL;
636         r_shadow_attenuation3dtexture = NULL;
637         R_FreeTexturePool(&r_shadow_texturepool);
638         R_FreeTexturePool(&r_shadow_filters_texturepool);
639         maxshadowtriangles = 0;
640         if (shadowelements)
641                 Mem_Free(shadowelements);
642         shadowelements = NULL;
643         if (shadowvertex3f)
644                 Mem_Free(shadowvertex3f);
645         shadowvertex3f = NULL;
646         maxvertexupdate = 0;
647         if (vertexupdate)
648                 Mem_Free(vertexupdate);
649         vertexupdate = NULL;
650         if (vertexremap)
651                 Mem_Free(vertexremap);
652         vertexremap = NULL;
653         vertexupdatenum = 0;
654         maxshadowmark = 0;
655         numshadowmark = 0;
656         if (shadowmark)
657                 Mem_Free(shadowmark);
658         shadowmark = NULL;
659         if (shadowmarklist)
660                 Mem_Free(shadowmarklist);
661         shadowmarklist = NULL;
662         shadowmarkcount = 0;
663         maxshadowsides = 0;
664         numshadowsides = 0;
665         if (shadowsides)
666                 Mem_Free(shadowsides);
667         shadowsides = NULL;
668         if (shadowsideslist)
669                 Mem_Free(shadowsideslist);
670         shadowsideslist = NULL;
671         r_shadow_buffer_numleafpvsbytes = 0;
672         if (r_shadow_buffer_visitingleafpvs)
673                 Mem_Free(r_shadow_buffer_visitingleafpvs);
674         r_shadow_buffer_visitingleafpvs = NULL;
675         if (r_shadow_buffer_leafpvs)
676                 Mem_Free(r_shadow_buffer_leafpvs);
677         r_shadow_buffer_leafpvs = NULL;
678         if (r_shadow_buffer_leaflist)
679                 Mem_Free(r_shadow_buffer_leaflist);
680         r_shadow_buffer_leaflist = NULL;
681         r_shadow_buffer_numsurfacepvsbytes = 0;
682         if (r_shadow_buffer_surfacepvs)
683                 Mem_Free(r_shadow_buffer_surfacepvs);
684         r_shadow_buffer_surfacepvs = NULL;
685         if (r_shadow_buffer_surfacelist)
686                 Mem_Free(r_shadow_buffer_surfacelist);
687         r_shadow_buffer_surfacelist = NULL;
688         if (r_shadow_buffer_surfacesides)
689                 Mem_Free(r_shadow_buffer_surfacesides);
690         r_shadow_buffer_surfacesides = NULL;
691         r_shadow_buffer_numshadowtrispvsbytes = 0;
692         if (r_shadow_buffer_shadowtrispvs)
693                 Mem_Free(r_shadow_buffer_shadowtrispvs);
694         r_shadow_buffer_numlighttrispvsbytes = 0;
695         if (r_shadow_buffer_lighttrispvs)
696                 Mem_Free(r_shadow_buffer_lighttrispvs);
697 }
698
699 static void r_shadow_newmap(void)
700 {
701         if (r_shadow_bouncegrid_state.texture)    R_FreeTexture(r_shadow_bouncegrid_state.texture);r_shadow_bouncegrid_state.texture = NULL;
702         if (r_shadow_lightcorona)                 R_SkinFrame_MarkUsed(r_shadow_lightcorona);
703         if (r_editlights_sprcursor)               R_SkinFrame_MarkUsed(r_editlights_sprcursor);
704         if (r_editlights_sprlight)                R_SkinFrame_MarkUsed(r_editlights_sprlight);
705         if (r_editlights_sprnoshadowlight)        R_SkinFrame_MarkUsed(r_editlights_sprnoshadowlight);
706         if (r_editlights_sprcubemaplight)         R_SkinFrame_MarkUsed(r_editlights_sprcubemaplight);
707         if (r_editlights_sprcubemapnoshadowlight) R_SkinFrame_MarkUsed(r_editlights_sprcubemapnoshadowlight);
708         if (r_editlights_sprselection)            R_SkinFrame_MarkUsed(r_editlights_sprselection);
709         if (strncmp(cl.worldname, r_shadow_mapname, sizeof(r_shadow_mapname)))
710                 R_Shadow_EditLights_Reload_f();
711 }
712
713 void R_Shadow_Init(void)
714 {
715         Cvar_RegisterVariable(&r_shadow_bumpscale_basetexture);
716         Cvar_RegisterVariable(&r_shadow_bumpscale_bumpmap);
717         Cvar_RegisterVariable(&r_shadow_usebihculling);
718         Cvar_RegisterVariable(&r_shadow_usenormalmap);
719         Cvar_RegisterVariable(&r_shadow_debuglight);
720         Cvar_RegisterVariable(&r_shadow_deferred);
721         Cvar_RegisterVariable(&r_shadow_gloss);
722         Cvar_RegisterVariable(&r_shadow_gloss2intensity);
723         Cvar_RegisterVariable(&r_shadow_glossintensity);
724         Cvar_RegisterVariable(&r_shadow_glossexponent);
725         Cvar_RegisterVariable(&r_shadow_gloss2exponent);
726         Cvar_RegisterVariable(&r_shadow_glossexact);
727         Cvar_RegisterVariable(&r_shadow_lightattenuationdividebias);
728         Cvar_RegisterVariable(&r_shadow_lightattenuationlinearscale);
729         Cvar_RegisterVariable(&r_shadow_lightintensityscale);
730         Cvar_RegisterVariable(&r_shadow_lightradiusscale);
731         Cvar_RegisterVariable(&r_shadow_projectdistance);
732         Cvar_RegisterVariable(&r_shadow_frontsidecasting);
733         Cvar_RegisterVariable(&r_shadow_realtime_world_importlightentitiesfrommap);
734         Cvar_RegisterVariable(&r_shadow_realtime_dlight);
735         Cvar_RegisterVariable(&r_shadow_realtime_dlight_shadows);
736         Cvar_RegisterVariable(&r_shadow_realtime_dlight_svbspculling);
737         Cvar_RegisterVariable(&r_shadow_realtime_dlight_portalculling);
738         Cvar_RegisterVariable(&r_shadow_realtime_world);
739         Cvar_RegisterVariable(&r_shadow_realtime_world_lightmaps);
740         Cvar_RegisterVariable(&r_shadow_realtime_world_shadows);
741         Cvar_RegisterVariable(&r_shadow_realtime_world_compile);
742         Cvar_RegisterVariable(&r_shadow_realtime_world_compileshadow);
743         Cvar_RegisterVariable(&r_shadow_realtime_world_compilesvbsp);
744         Cvar_RegisterVariable(&r_shadow_realtime_world_compileportalculling);
745         Cvar_RegisterVariable(&r_shadow_scissor);
746         Cvar_RegisterVariable(&r_shadow_shadowmapping);
747         Cvar_RegisterVariable(&r_shadow_shadowmapping_vsdct);
748         Cvar_RegisterVariable(&r_shadow_shadowmapping_filterquality);
749         Cvar_RegisterVariable(&r_shadow_shadowmapping_useshadowsampler);
750         Cvar_RegisterVariable(&r_shadow_shadowmapping_depthbits);
751         Cvar_RegisterVariable(&r_shadow_shadowmapping_precision);
752         Cvar_RegisterVariable(&r_shadow_shadowmapping_maxsize);
753         Cvar_RegisterVariable(&r_shadow_shadowmapping_minsize);
754 //      Cvar_RegisterVariable(&r_shadow_shadowmapping_lod_bias);
755 //      Cvar_RegisterVariable(&r_shadow_shadowmapping_lod_scale);
756         Cvar_RegisterVariable(&r_shadow_shadowmapping_bordersize);
757         Cvar_RegisterVariable(&r_shadow_shadowmapping_nearclip);
758         Cvar_RegisterVariable(&r_shadow_shadowmapping_bias);
759         Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonfactor);
760         Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonoffset);
761         Cvar_RegisterVariable(&r_shadow_sortsurfaces);
762         Cvar_RegisterVariable(&r_shadow_polygonfactor);
763         Cvar_RegisterVariable(&r_shadow_polygonoffset);
764         Cvar_RegisterVariable(&r_shadow_texture3d);
765         Cvar_RegisterVariable(&r_shadow_bouncegrid);
766         Cvar_RegisterVariable(&r_shadow_bouncegrid_blur);
767         Cvar_RegisterVariable(&r_shadow_bouncegrid_bounceanglediffuse);
768         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_culllightpaths);
769         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_directionalshading);
770         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_dlightparticlemultiplier);
771         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_hitmodels);
772         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_energyperphoton);
773         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_lightradiusscale);
774         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_maxbounce);
775         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_maxphotons);
776         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_spacing);
777         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_stablerandom);
778         Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_updateinterval);
779         Cvar_RegisterVariable(&r_shadow_bouncegrid_includedirectlighting);
780         Cvar_RegisterVariable(&r_shadow_bouncegrid_intensity);
781         Cvar_RegisterVariable(&r_shadow_bouncegrid_particlebounceintensity);
782         Cvar_RegisterVariable(&r_shadow_bouncegrid_particleintensity);
783         Cvar_RegisterVariable(&r_shadow_bouncegrid_sortlightpaths);
784         Cvar_RegisterVariable(&r_shadow_bouncegrid_static);
785         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_spacing);
786         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_directionalshading);
787         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_lightradiusscale);
788         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxbounce);
789         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxphotons);
790         Cvar_RegisterVariable(&r_shadow_bouncegrid_static_energyperphoton);
791         Cvar_RegisterVariable(&r_shadow_bouncegrid_x);
792         Cvar_RegisterVariable(&r_shadow_bouncegrid_y);
793         Cvar_RegisterVariable(&r_shadow_bouncegrid_z);
794         Cvar_RegisterVariable(&r_coronas);
795         Cvar_RegisterVariable(&r_coronas_occlusionsizescale);
796         Cvar_RegisterVariable(&r_coronas_occlusionquery);
797         Cvar_RegisterVariable(&gl_flashblend);
798         Cvar_RegisterVariable(&gl_ext_separatestencil);
799         Cvar_RegisterVariable(&gl_ext_stenciltwoside);
800         R_Shadow_EditLights_Init();
801         Mem_ExpandableArray_NewArray(&r_shadow_worldlightsarray, r_main_mempool, sizeof(dlight_t), 128);
802         maxshadowtriangles = 0;
803         shadowelements = NULL;
804         maxshadowvertices = 0;
805         shadowvertex3f = NULL;
806         maxvertexupdate = 0;
807         vertexupdate = NULL;
808         vertexremap = NULL;
809         vertexupdatenum = 0;
810         maxshadowmark = 0;
811         numshadowmark = 0;
812         shadowmark = NULL;
813         shadowmarklist = NULL;
814         shadowmarkcount = 0;
815         maxshadowsides = 0;
816         numshadowsides = 0;
817         shadowsides = NULL;
818         shadowsideslist = NULL;
819         r_shadow_buffer_numleafpvsbytes = 0;
820         r_shadow_buffer_visitingleafpvs = NULL;
821         r_shadow_buffer_leafpvs = NULL;
822         r_shadow_buffer_leaflist = NULL;
823         r_shadow_buffer_numsurfacepvsbytes = 0;
824         r_shadow_buffer_surfacepvs = NULL;
825         r_shadow_buffer_surfacelist = NULL;
826         r_shadow_buffer_surfacesides = NULL;
827         r_shadow_buffer_shadowtrispvs = NULL;
828         r_shadow_buffer_lighttrispvs = NULL;
829         R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap, NULL, NULL);
830 }
831
832 matrix4x4_t matrix_attenuationxyz =
833 {
834         {
835                 {0.5, 0.0, 0.0, 0.5},
836                 {0.0, 0.5, 0.0, 0.5},
837                 {0.0, 0.0, 0.5, 0.5},
838                 {0.0, 0.0, 0.0, 1.0}
839         }
840 };
841
842 matrix4x4_t matrix_attenuationz =
843 {
844         {
845                 {0.0, 0.0, 0.5, 0.5},
846                 {0.0, 0.0, 0.0, 0.5},
847                 {0.0, 0.0, 0.0, 0.5},
848                 {0.0, 0.0, 0.0, 1.0}
849         }
850 };
851
852 static void R_Shadow_ResizeShadowArrays(int numvertices, int numtriangles, int vertscale, int triscale)
853 {
854         numvertices = ((numvertices + 255) & ~255) * vertscale;
855         numtriangles = ((numtriangles + 255) & ~255) * triscale;
856         // make sure shadowelements is big enough for this volume
857         if (maxshadowtriangles < numtriangles)
858         {
859                 maxshadowtriangles = numtriangles;
860                 if (shadowelements)
861                         Mem_Free(shadowelements);
862                 shadowelements = (int *)Mem_Alloc(r_main_mempool, maxshadowtriangles * sizeof(int[3]));
863         }
864         // make sure shadowvertex3f is big enough for this volume
865         if (maxshadowvertices < numvertices)
866         {
867                 maxshadowvertices = numvertices;
868                 if (shadowvertex3f)
869                         Mem_Free(shadowvertex3f);
870                 shadowvertex3f = (float *)Mem_Alloc(r_main_mempool, maxshadowvertices * sizeof(float[3]));
871         }
872 }
873
874 static void R_Shadow_EnlargeLeafSurfaceTrisBuffer(int numleafs, int numsurfaces, int numshadowtriangles, int numlighttriangles)
875 {
876         int numleafpvsbytes = (((numleafs + 7) >> 3) + 255) & ~255;
877         int numsurfacepvsbytes = (((numsurfaces + 7) >> 3) + 255) & ~255;
878         int numshadowtrispvsbytes = (((numshadowtriangles + 7) >> 3) + 255) & ~255;
879         int numlighttrispvsbytes = (((numlighttriangles + 7) >> 3) + 255) & ~255;
880         if (r_shadow_buffer_numleafpvsbytes < numleafpvsbytes)
881         {
882                 if (r_shadow_buffer_visitingleafpvs)
883                         Mem_Free(r_shadow_buffer_visitingleafpvs);
884                 if (r_shadow_buffer_leafpvs)
885                         Mem_Free(r_shadow_buffer_leafpvs);
886                 if (r_shadow_buffer_leaflist)
887                         Mem_Free(r_shadow_buffer_leaflist);
888                 r_shadow_buffer_numleafpvsbytes = numleafpvsbytes;
889                 r_shadow_buffer_visitingleafpvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes);
890                 r_shadow_buffer_leafpvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes);
891                 r_shadow_buffer_leaflist = (int *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numleafpvsbytes * 8 * sizeof(*r_shadow_buffer_leaflist));
892         }
893         if (r_shadow_buffer_numsurfacepvsbytes < numsurfacepvsbytes)
894         {
895                 if (r_shadow_buffer_surfacepvs)
896                         Mem_Free(r_shadow_buffer_surfacepvs);
897                 if (r_shadow_buffer_surfacelist)
898                         Mem_Free(r_shadow_buffer_surfacelist);
899                 if (r_shadow_buffer_surfacesides)
900                         Mem_Free(r_shadow_buffer_surfacesides);
901                 r_shadow_buffer_numsurfacepvsbytes = numsurfacepvsbytes;
902                 r_shadow_buffer_surfacepvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numsurfacepvsbytes);
903                 r_shadow_buffer_surfacelist = (int *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numsurfacepvsbytes * 8 * sizeof(*r_shadow_buffer_surfacelist));
904                 r_shadow_buffer_surfacesides = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numsurfacepvsbytes * 8 * sizeof(*r_shadow_buffer_surfacelist));
905         }
906         if (r_shadow_buffer_numshadowtrispvsbytes < numshadowtrispvsbytes)
907         {
908                 if (r_shadow_buffer_shadowtrispvs)
909                         Mem_Free(r_shadow_buffer_shadowtrispvs);
910                 r_shadow_buffer_numshadowtrispvsbytes = numshadowtrispvsbytes;
911                 r_shadow_buffer_shadowtrispvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numshadowtrispvsbytes);
912         }
913         if (r_shadow_buffer_numlighttrispvsbytes < numlighttrispvsbytes)
914         {
915                 if (r_shadow_buffer_lighttrispvs)
916                         Mem_Free(r_shadow_buffer_lighttrispvs);
917                 r_shadow_buffer_numlighttrispvsbytes = numlighttrispvsbytes;
918                 r_shadow_buffer_lighttrispvs = (unsigned char *)Mem_Alloc(r_main_mempool, r_shadow_buffer_numlighttrispvsbytes);
919         }
920 }
921
922 void R_Shadow_PrepareShadowMark(int numtris)
923 {
924         // make sure shadowmark is big enough for this volume
925         if (maxshadowmark < numtris)
926         {
927                 maxshadowmark = numtris;
928                 if (shadowmark)
929                         Mem_Free(shadowmark);
930                 if (shadowmarklist)
931                         Mem_Free(shadowmarklist);
932                 shadowmark = (int *)Mem_Alloc(r_main_mempool, maxshadowmark * sizeof(*shadowmark));
933                 shadowmarklist = (int *)Mem_Alloc(r_main_mempool, maxshadowmark * sizeof(*shadowmarklist));
934                 shadowmarkcount = 0;
935         }
936         shadowmarkcount++;
937         // if shadowmarkcount wrapped we clear the array and adjust accordingly
938         if (shadowmarkcount == 0)
939         {
940                 shadowmarkcount = 1;
941                 memset(shadowmark, 0, maxshadowmark * sizeof(*shadowmark));
942         }
943         numshadowmark = 0;
944 }
945
946 void R_Shadow_PrepareShadowSides(int numtris)
947 {
948         if (maxshadowsides < numtris)
949         {
950                 maxshadowsides = numtris;
951                 if (shadowsides)
952                         Mem_Free(shadowsides);
953                 if (shadowsideslist)
954                         Mem_Free(shadowsideslist);
955                 shadowsides = (unsigned char *)Mem_Alloc(r_main_mempool, maxshadowsides * sizeof(*shadowsides));
956                 shadowsideslist = (int *)Mem_Alloc(r_main_mempool, maxshadowsides * sizeof(*shadowsideslist));
957         }
958         numshadowsides = 0;
959 }
960
961 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)
962 {
963         int i, j;
964         int outtriangles = 0, outvertices = 0;
965         const int *element;
966         const float *vertex;
967         float ratio, direction[3], projectvector[3];
968
969         if (projectdirection)
970                 VectorScale(projectdirection, projectdistance, projectvector);
971         else
972                 VectorClear(projectvector);
973
974         // create the vertices
975         if (projectdirection)
976         {
977                 for (i = 0;i < numshadowmarktris;i++)
978                 {
979                         element = inelement3i + shadowmarktris[i] * 3;
980                         for (j = 0;j < 3;j++)
981                         {
982                                 if (vertexupdate[element[j]] != vertexupdatenum)
983                                 {
984                                         vertexupdate[element[j]] = vertexupdatenum;
985                                         vertexremap[element[j]] = outvertices;
986                                         vertex = invertex3f + element[j] * 3;
987                                         // project one copy of the vertex according to projectvector
988                                         VectorCopy(vertex, outvertex3f);
989                                         VectorAdd(vertex, projectvector, (outvertex3f + 3));
990                                         outvertex3f += 6;
991                                         outvertices += 2;
992                                 }
993                         }
994                 }
995         }
996         else
997         {
998                 for (i = 0;i < numshadowmarktris;i++)
999                 {
1000                         element = inelement3i + shadowmarktris[i] * 3;
1001                         for (j = 0;j < 3;j++)
1002                         {
1003                                 if (vertexupdate[element[j]] != vertexupdatenum)
1004                                 {
1005                                         vertexupdate[element[j]] = vertexupdatenum;
1006                                         vertexremap[element[j]] = outvertices;
1007                                         vertex = invertex3f + element[j] * 3;
1008                                         // project one copy of the vertex to the sphere radius of the light
1009                                         // (FIXME: would projecting it to the light box be better?)
1010                                         VectorSubtract(vertex, projectorigin, direction);
1011                                         ratio = projectdistance / VectorLength(direction);
1012                                         VectorCopy(vertex, outvertex3f);
1013                                         VectorMA(projectorigin, ratio, direction, (outvertex3f + 3));
1014                                         outvertex3f += 6;
1015                                         outvertices += 2;
1016                                 }
1017                         }
1018                 }
1019         }
1020
1021         if (r_shadow_frontsidecasting.integer)
1022         {
1023                 for (i = 0;i < numshadowmarktris;i++)
1024                 {
1025                         int remappedelement[3];
1026                         int markindex;
1027                         const int *neighbortriangle;
1028
1029                         markindex = shadowmarktris[i] * 3;
1030                         element = inelement3i + markindex;
1031                         neighbortriangle = inneighbor3i + markindex;
1032                         // output the front and back triangles
1033                         outelement3i[0] = vertexremap[element[0]];
1034                         outelement3i[1] = vertexremap[element[1]];
1035                         outelement3i[2] = vertexremap[element[2]];
1036                         outelement3i[3] = vertexremap[element[2]] + 1;
1037                         outelement3i[4] = vertexremap[element[1]] + 1;
1038                         outelement3i[5] = vertexremap[element[0]] + 1;
1039
1040                         outelement3i += 6;
1041                         outtriangles += 2;
1042                         // output the sides (facing outward from this triangle)
1043                         if (shadowmark[neighbortriangle[0]] != shadowmarkcount)
1044                         {
1045                                 remappedelement[0] = vertexremap[element[0]];
1046                                 remappedelement[1] = vertexremap[element[1]];
1047                                 outelement3i[0] = remappedelement[1];
1048                                 outelement3i[1] = remappedelement[0];
1049                                 outelement3i[2] = remappedelement[0] + 1;
1050                                 outelement3i[3] = remappedelement[1];
1051                                 outelement3i[4] = remappedelement[0] + 1;
1052                                 outelement3i[5] = remappedelement[1] + 1;
1053
1054                                 outelement3i += 6;
1055                                 outtriangles += 2;
1056                         }
1057                         if (shadowmark[neighbortriangle[1]] != shadowmarkcount)
1058                         {
1059                                 remappedelement[1] = vertexremap[element[1]];
1060                                 remappedelement[2] = vertexremap[element[2]];
1061                                 outelement3i[0] = remappedelement[2];
1062                                 outelement3i[1] = remappedelement[1];
1063                                 outelement3i[2] = remappedelement[1] + 1;
1064                                 outelement3i[3] = remappedelement[2];
1065                                 outelement3i[4] = remappedelement[1] + 1;
1066                                 outelement3i[5] = remappedelement[2] + 1;
1067
1068                                 outelement3i += 6;
1069                                 outtriangles += 2;
1070                         }
1071                         if (shadowmark[neighbortriangle[2]] != shadowmarkcount)
1072                         {
1073                                 remappedelement[0] = vertexremap[element[0]];
1074                                 remappedelement[2] = vertexremap[element[2]];
1075                                 outelement3i[0] = remappedelement[0];
1076                                 outelement3i[1] = remappedelement[2];
1077                                 outelement3i[2] = remappedelement[2] + 1;
1078                                 outelement3i[3] = remappedelement[0];
1079                                 outelement3i[4] = remappedelement[2] + 1;
1080                                 outelement3i[5] = remappedelement[0] + 1;
1081
1082                                 outelement3i += 6;
1083                                 outtriangles += 2;
1084                         }
1085                 }
1086         }
1087         else
1088         {
1089                 for (i = 0;i < numshadowmarktris;i++)
1090                 {
1091                         int remappedelement[3];
1092                         int markindex;
1093                         const int *neighbortriangle;
1094
1095                         markindex = shadowmarktris[i] * 3;
1096                         element = inelement3i + markindex;
1097                         neighbortriangle = inneighbor3i + markindex;
1098                         // output the front and back triangles
1099                         outelement3i[0] = vertexremap[element[2]];
1100                         outelement3i[1] = vertexremap[element[1]];
1101                         outelement3i[2] = vertexremap[element[0]];
1102                         outelement3i[3] = vertexremap[element[0]] + 1;
1103                         outelement3i[4] = vertexremap[element[1]] + 1;
1104                         outelement3i[5] = vertexremap[element[2]] + 1;
1105
1106                         outelement3i += 6;
1107                         outtriangles += 2;
1108                         // output the sides (facing outward from this triangle)
1109                         if (shadowmark[neighbortriangle[0]] != shadowmarkcount)
1110                         {
1111                                 remappedelement[0] = vertexremap[element[0]];
1112                                 remappedelement[1] = vertexremap[element[1]];
1113                                 outelement3i[0] = remappedelement[0];
1114                                 outelement3i[1] = remappedelement[1];
1115                                 outelement3i[2] = remappedelement[1] + 1;
1116                                 outelement3i[3] = remappedelement[0];
1117                                 outelement3i[4] = remappedelement[1] + 1;
1118                                 outelement3i[5] = remappedelement[0] + 1;
1119
1120                                 outelement3i += 6;
1121                                 outtriangles += 2;
1122                         }
1123                         if (shadowmark[neighbortriangle[1]] != shadowmarkcount)
1124                         {
1125                                 remappedelement[1] = vertexremap[element[1]];
1126                                 remappedelement[2] = vertexremap[element[2]];
1127                                 outelement3i[0] = remappedelement[1];
1128                                 outelement3i[1] = remappedelement[2];
1129                                 outelement3i[2] = remappedelement[2] + 1;
1130                                 outelement3i[3] = remappedelement[1];
1131                                 outelement3i[4] = remappedelement[2] + 1;
1132                                 outelement3i[5] = remappedelement[1] + 1;
1133
1134                                 outelement3i += 6;
1135                                 outtriangles += 2;
1136                         }
1137                         if (shadowmark[neighbortriangle[2]] != shadowmarkcount)
1138                         {
1139                                 remappedelement[0] = vertexremap[element[0]];
1140                                 remappedelement[2] = vertexremap[element[2]];
1141                                 outelement3i[0] = remappedelement[2];
1142                                 outelement3i[1] = remappedelement[0];
1143                                 outelement3i[2] = remappedelement[0] + 1;
1144                                 outelement3i[3] = remappedelement[2];
1145                                 outelement3i[4] = remappedelement[0] + 1;
1146                                 outelement3i[5] = remappedelement[2] + 1;
1147
1148                                 outelement3i += 6;
1149                                 outtriangles += 2;
1150                         }
1151                 }
1152         }
1153         if (outnumvertices)
1154                 *outnumvertices = outvertices;
1155         return outtriangles;
1156 }
1157
1158 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)
1159 {
1160         int i, j, k;
1161         int outtriangles = 0, outvertices = 0;
1162         const int *element;
1163         const float *vertex;
1164         float ratio, direction[3], projectvector[3];
1165         qboolean side[4];
1166
1167         if (projectdirection)
1168                 VectorScale(projectdirection, projectdistance, projectvector);
1169         else
1170                 VectorClear(projectvector);
1171
1172         for (i = 0;i < numshadowmarktris;i++)
1173         {
1174                 int remappedelement[3];
1175                 int markindex;
1176                 const int *neighbortriangle;
1177
1178                 markindex = shadowmarktris[i] * 3;
1179                 neighbortriangle = inneighbor3i + markindex;
1180                 side[0] = shadowmark[neighbortriangle[0]] == shadowmarkcount;
1181                 side[1] = shadowmark[neighbortriangle[1]] == shadowmarkcount;
1182                 side[2] = shadowmark[neighbortriangle[2]] == shadowmarkcount;
1183                 if (side[0] + side[1] + side[2] == 0)
1184                         continue;
1185
1186                 side[3] = side[0];
1187                 element = inelement3i + markindex;
1188
1189                 // create the vertices
1190                 for (j = 0;j < 3;j++)
1191                 {
1192                         if (side[j] + side[j+1] == 0)
1193                                 continue;
1194                         k = element[j];
1195                         if (vertexupdate[k] != vertexupdatenum)
1196                         {
1197                                 vertexupdate[k] = vertexupdatenum;
1198                                 vertexremap[k] = outvertices;
1199                                 vertex = invertex3f + k * 3;
1200                                 VectorCopy(vertex, outvertex3f);
1201                                 if (projectdirection)
1202                                 {
1203                                         // project one copy of the vertex according to projectvector
1204                                         VectorAdd(vertex, projectvector, (outvertex3f + 3));
1205                                 }
1206                                 else
1207                                 {
1208                                         // project one copy of the vertex to the sphere radius of the light
1209                                         // (FIXME: would projecting it to the light box be better?)
1210                                         VectorSubtract(vertex, projectorigin, direction);
1211                                         ratio = projectdistance / VectorLength(direction);
1212                                         VectorMA(projectorigin, ratio, direction, (outvertex3f + 3));
1213                                 }
1214                                 outvertex3f += 6;
1215                                 outvertices += 2;
1216                         }
1217                 }
1218
1219                 // output the sides (facing outward from this triangle)
1220                 if (!side[0])
1221                 {
1222                         remappedelement[0] = vertexremap[element[0]];
1223                         remappedelement[1] = vertexremap[element[1]];
1224                         outelement3i[0] = remappedelement[1];
1225                         outelement3i[1] = remappedelement[0];
1226                         outelement3i[2] = remappedelement[0] + 1;
1227                         outelement3i[3] = remappedelement[1];
1228                         outelement3i[4] = remappedelement[0] + 1;
1229                         outelement3i[5] = remappedelement[1] + 1;
1230
1231                         outelement3i += 6;
1232                         outtriangles += 2;
1233                 }
1234                 if (!side[1])
1235                 {
1236                         remappedelement[1] = vertexremap[element[1]];
1237                         remappedelement[2] = vertexremap[element[2]];
1238                         outelement3i[0] = remappedelement[2];
1239                         outelement3i[1] = remappedelement[1];
1240                         outelement3i[2] = remappedelement[1] + 1;
1241                         outelement3i[3] = remappedelement[2];
1242                         outelement3i[4] = remappedelement[1] + 1;
1243                         outelement3i[5] = remappedelement[2] + 1;
1244
1245                         outelement3i += 6;
1246                         outtriangles += 2;
1247                 }
1248                 if (!side[2])
1249                 {
1250                         remappedelement[0] = vertexremap[element[0]];
1251                         remappedelement[2] = vertexremap[element[2]];
1252                         outelement3i[0] = remappedelement[0];
1253                         outelement3i[1] = remappedelement[2];
1254                         outelement3i[2] = remappedelement[2] + 1;
1255                         outelement3i[3] = remappedelement[0];
1256                         outelement3i[4] = remappedelement[2] + 1;
1257                         outelement3i[5] = remappedelement[0] + 1;
1258
1259                         outelement3i += 6;
1260                         outtriangles += 2;
1261                 }
1262         }
1263         if (outnumvertices)
1264                 *outnumvertices = outvertices;
1265         return outtriangles;
1266 }
1267
1268 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)
1269 {
1270         int t, tend;
1271         const int *e;
1272         const float *v[3];
1273         float normal[3];
1274         if (!BoxesOverlap(lightmins, lightmaxs, surfacemins, surfacemaxs))
1275                 return;
1276         tend = firsttriangle + numtris;
1277         if (BoxInsideBox(surfacemins, surfacemaxs, lightmins, lightmaxs))
1278         {
1279                 // surface box entirely inside light box, no box cull
1280                 if (projectdirection)
1281                 {
1282                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1283                         {
1284                                 TriangleNormal(invertex3f + e[0] * 3, invertex3f + e[1] * 3, invertex3f + e[2] * 3, normal);
1285                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0))
1286                                         shadowmarklist[numshadowmark++] = t;
1287                         }
1288                 }
1289                 else
1290                 {
1291                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1292                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, invertex3f + e[0] * 3, invertex3f + e[1] * 3, invertex3f + e[2] * 3))
1293                                         shadowmarklist[numshadowmark++] = t;
1294                 }
1295         }
1296         else
1297         {
1298                 // surface box not entirely inside light box, cull each triangle
1299                 if (projectdirection)
1300                 {
1301                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1302                         {
1303                                 v[0] = invertex3f + e[0] * 3;
1304                                 v[1] = invertex3f + e[1] * 3;
1305                                 v[2] = invertex3f + e[2] * 3;
1306                                 TriangleNormal(v[0], v[1], v[2], normal);
1307                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0)
1308                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1309                                         shadowmarklist[numshadowmark++] = t;
1310                         }
1311                 }
1312                 else
1313                 {
1314                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1315                         {
1316                                 v[0] = invertex3f + e[0] * 3;
1317                                 v[1] = invertex3f + e[1] * 3;
1318                                 v[2] = invertex3f + e[2] * 3;
1319                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2])
1320                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1321                                         shadowmarklist[numshadowmark++] = t;
1322                         }
1323                 }
1324         }
1325 }
1326
1327 static qboolean R_Shadow_UseZPass(vec3_t mins, vec3_t maxs)
1328 {
1329 #if 1
1330         return false;
1331 #else
1332         if (r_shadow_compilingrtlight || !r_shadow_frontsidecasting.integer || !r_shadow_usezpassifpossible.integer)
1333                 return false;
1334         // check if the shadow volume intersects the near plane
1335         //
1336         // a ray between the eye and light origin may intersect the caster,
1337         // indicating that the shadow may touch the eye location, however we must
1338         // test the near plane (a polygon), not merely the eye location, so it is
1339         // easiest to enlarge the caster bounding shape slightly for this.
1340         // TODO
1341         return true;
1342 #endif
1343 }
1344
1345 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)
1346 {
1347         int i, tris, outverts;
1348         if (projectdistance < 0.1)
1349         {
1350                 Con_Printf("R_Shadow_Volume: projectdistance %f\n", projectdistance);
1351                 return;
1352         }
1353         if (!numverts || !nummarktris)
1354                 return;
1355         // make sure shadowelements is big enough for this volume
1356         if (maxshadowtriangles < nummarktris*8 || maxshadowvertices < numverts*2)
1357                 R_Shadow_ResizeShadowArrays(numverts, nummarktris, 2, 8);
1358
1359         if (maxvertexupdate < numverts)
1360         {
1361                 maxvertexupdate = numverts;
1362                 if (vertexupdate)
1363                         Mem_Free(vertexupdate);
1364                 if (vertexremap)
1365                         Mem_Free(vertexremap);
1366                 vertexupdate = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
1367                 vertexremap = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int));
1368                 vertexupdatenum = 0;
1369         }
1370         vertexupdatenum++;
1371         if (vertexupdatenum == 0)
1372         {
1373                 vertexupdatenum = 1;
1374                 memset(vertexupdate, 0, maxvertexupdate * sizeof(int));
1375                 memset(vertexremap, 0, maxvertexupdate * sizeof(int));
1376         }
1377
1378         for (i = 0;i < nummarktris;i++)
1379                 shadowmark[marktris[i]] = shadowmarkcount;
1380
1381         if (r_shadow_compilingrtlight)
1382         {
1383                 // if we're compiling an rtlight, capture the mesh
1384                 //tris = R_Shadow_ConstructShadowVolume_ZPass(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1385                 //Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_zpass, NULL, NULL, NULL, shadowvertex3f, NULL, NULL, NULL, NULL, tris, shadowelements);
1386                 tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1387                 Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_zfail, NULL, NULL, NULL, shadowvertex3f, NULL, NULL, NULL, NULL, tris, shadowelements);
1388         }
1389         else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_VISIBLEVOLUMES)
1390         {
1391                 tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1392                 R_Mesh_PrepareVertices_Vertex3f(outverts, shadowvertex3f, NULL, 0);
1393                 R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1394         }
1395         else
1396         {
1397                 // decide which type of shadow to generate and set stencil mode
1398                 R_Shadow_RenderMode_StencilShadowVolumes(R_Shadow_UseZPass(trismins, trismaxs));
1399                 // generate the sides or a solid volume, depending on type
1400                 if (r_shadow_rendermode >= R_SHADOW_RENDERMODE_ZPASS_STENCIL && r_shadow_rendermode <= R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE)
1401                         tris = R_Shadow_ConstructShadowVolume_ZPass(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1402                 else
1403                         tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
1404                 r_refdef.stats[r_stat_lights_dynamicshadowtriangles] += tris;
1405                 r_refdef.stats[r_stat_lights_shadowtriangles] += tris;
1406                 if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL)
1407                 {
1408                         // increment stencil if frontface is infront of depthbuffer
1409                         GL_CullFace(r_refdef.view.cullface_front);
1410                         R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_DECR, GL_ALWAYS, 128, 255);
1411                         R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1412                         // decrement stencil if backface is infront of depthbuffer
1413                         GL_CullFace(r_refdef.view.cullface_back);
1414                         R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_INCR, GL_ALWAYS, 128, 255);
1415                 }
1416                 else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZFAIL_STENCIL)
1417                 {
1418                         // decrement stencil if backface is behind depthbuffer
1419                         GL_CullFace(r_refdef.view.cullface_front);
1420                         R_SetStencil(true, 255, GL_KEEP, GL_DECR, GL_KEEP, GL_ALWAYS, 128, 255);
1421                         R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1422                         // increment stencil if frontface is behind depthbuffer
1423                         GL_CullFace(r_refdef.view.cullface_back);
1424                         R_SetStencil(true, 255, GL_KEEP, GL_INCR, GL_KEEP, GL_ALWAYS, 128, 255);
1425                 }
1426                 R_Mesh_PrepareVertices_Vertex3f(outverts, shadowvertex3f, NULL, 0);
1427                 R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0);
1428         }
1429 }
1430
1431 int R_Shadow_CalcTriangleSideMask(const vec3_t p1, const vec3_t p2, const vec3_t p3, float bias)
1432 {
1433         // p1, p2, p3 are in the cubemap's local coordinate system
1434         // bias = border/(size - border)
1435         int mask = 0x3F;
1436
1437         float dp1 = p1[0] + p1[1], dn1 = p1[0] - p1[1], ap1 = fabs(dp1), an1 = fabs(dn1),
1438                   dp2 = p2[0] + p2[1], dn2 = p2[0] - p2[1], ap2 = fabs(dp2), an2 = fabs(dn2),
1439                   dp3 = p3[0] + p3[1], dn3 = p3[0] - p3[1], ap3 = fabs(dp3), an3 = fabs(dn3);
1440         if(ap1 > bias*an1 && ap2 > bias*an2 && ap3 > bias*an3)
1441                 mask &= (3<<4)
1442                         | (dp1 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2))
1443                         | (dp2 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2))
1444                         | (dp3 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1445         if(an1 > bias*ap1 && an2 > bias*ap2 && an3 > bias*ap3)
1446                 mask &= (3<<4)
1447                         | (dn1 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2))
1448                         | (dn2 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2))                    
1449                         | (dn3 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1450
1451         dp1 = p1[1] + p1[2], dn1 = p1[1] - p1[2], ap1 = fabs(dp1), an1 = fabs(dn1),
1452         dp2 = p2[1] + p2[2], dn2 = p2[1] - p2[2], ap2 = fabs(dp2), an2 = fabs(dn2),
1453         dp3 = p3[1] + p3[2], dn3 = p3[1] - p3[2], ap3 = fabs(dp3), an3 = fabs(dn3);
1454         if(ap1 > bias*an1 && ap2 > bias*an2 && ap3 > bias*an3)
1455                 mask &= (3<<0)
1456                         | (dp1 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4))
1457                         | (dp2 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4))                    
1458                         | (dp3 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1459         if(an1 > bias*ap1 && an2 > bias*ap2 && an3 > bias*ap3)
1460                 mask &= (3<<0)
1461                         | (dn1 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4))
1462                         | (dn2 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4))
1463                         | (dn3 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1464
1465         dp1 = p1[2] + p1[0], dn1 = p1[2] - p1[0], ap1 = fabs(dp1), an1 = fabs(dn1),
1466         dp2 = p2[2] + p2[0], dn2 = p2[2] - p2[0], ap2 = fabs(dp2), an2 = fabs(dn2),
1467         dp3 = p3[2] + p3[0], dn3 = p3[2] - p3[0], ap3 = fabs(dp3), an3 = fabs(dn3);
1468         if(ap1 > bias*an1 && ap2 > bias*an2 && ap3 > bias*an3)
1469                 mask &= (3<<2)
1470                         | (dp1 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0))
1471                         | (dp2 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0))
1472                         | (dp3 >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
1473         if(an1 > bias*ap1 && an2 > bias*ap2 && an3 > bias*ap3)
1474                 mask &= (3<<2)
1475                         | (dn1 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0))
1476                         | (dn2 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0))
1477                         | (dn3 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1478
1479         return mask;
1480 }
1481
1482 static int R_Shadow_CalcBBoxSideMask(const vec3_t mins, const vec3_t maxs, const matrix4x4_t *worldtolight, const matrix4x4_t *radiustolight, float bias)
1483 {
1484         vec3_t center, radius, lightcenter, lightradius, pmin, pmax;
1485         float dp1, dn1, ap1, an1, dp2, dn2, ap2, an2;
1486         int mask = 0x3F;
1487
1488         VectorSubtract(maxs, mins, radius);
1489         VectorScale(radius, 0.5f, radius);
1490         VectorAdd(mins, radius, center);
1491         Matrix4x4_Transform(worldtolight, center, lightcenter);
1492         Matrix4x4_Transform3x3(radiustolight, radius, lightradius);
1493         VectorSubtract(lightcenter, lightradius, pmin);
1494         VectorAdd(lightcenter, lightradius, pmax);
1495
1496         dp1 = pmax[0] + pmax[1], dn1 = pmax[0] - pmin[1], ap1 = fabs(dp1), an1 = fabs(dn1),
1497         dp2 = pmin[0] + pmin[1], dn2 = pmin[0] - pmax[1], ap2 = fabs(dp2), an2 = fabs(dn2);
1498         if(ap1 > bias*an1 && ap2 > bias*an2)
1499                 mask &= (3<<4)
1500                         | (dp1 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2))
1501                         | (dp2 >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1502         if(an1 > bias*ap1 && an2 > bias*ap2)
1503                 mask &= (3<<4)
1504                         | (dn1 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2))
1505                         | (dn2 >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1506
1507         dp1 = pmax[1] + pmax[2], dn1 = pmax[1] - pmin[2], ap1 = fabs(dp1), an1 = fabs(dn1),
1508         dp2 = pmin[1] + pmin[2], dn2 = pmin[1] - pmax[2], ap2 = fabs(dp2), an2 = fabs(dn2);
1509         if(ap1 > bias*an1 && ap2 > bias*an2)
1510                 mask &= (3<<0)
1511                         | (dp1 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4))
1512                         | (dp2 >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1513         if(an1 > bias*ap1 && an2 > bias*ap2)
1514                 mask &= (3<<0)
1515                         | (dn1 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4))
1516                         | (dn2 >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1517
1518         dp1 = pmax[2] + pmax[0], dn1 = pmax[2] - pmin[0], ap1 = fabs(dp1), an1 = fabs(dn1),
1519         dp2 = pmin[2] + pmin[0], dn2 = pmin[2] - pmax[0], ap2 = fabs(dp2), an2 = fabs(dn2);
1520         if(ap1 > bias*an1 && ap2 > bias*an2)
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         if(an1 > bias*ap1 && an2 > bias*ap2)
1525                 mask &= (3<<2)
1526                         | (dn1 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0))
1527                         | (dn2 >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1528
1529         return mask;
1530 }
1531
1532 #define R_Shadow_CalcEntitySideMask(ent, worldtolight, radiustolight, bias) R_Shadow_CalcBBoxSideMask((ent)->mins, (ent)->maxs, worldtolight, radiustolight, bias)
1533
1534 int R_Shadow_CalcSphereSideMask(const vec3_t p, float radius, float bias)
1535 {
1536         // p is in the cubemap's local coordinate system
1537         // bias = border/(size - border)
1538         float dxyp = p[0] + p[1], dxyn = p[0] - p[1], axyp = fabs(dxyp), axyn = fabs(dxyn);
1539         float dyzp = p[1] + p[2], dyzn = p[1] - p[2], ayzp = fabs(dyzp), ayzn = fabs(dyzn);
1540         float dzxp = p[2] + p[0], dzxn = p[2] - p[0], azxp = fabs(dzxp), azxn = fabs(dzxn);
1541         int mask = 0x3F;
1542         if(axyp > bias*axyn + radius) mask &= dxyp < 0 ? ~((1<<0)|(1<<2)) : ~((2<<0)|(2<<2));
1543         if(axyn > bias*axyp + radius) mask &= dxyn < 0 ? ~((1<<0)|(2<<2)) : ~((2<<0)|(1<<2));
1544         if(ayzp > bias*ayzn + radius) mask &= dyzp < 0 ? ~((1<<2)|(1<<4)) : ~((2<<2)|(2<<4));
1545         if(ayzn > bias*ayzp + radius) mask &= dyzn < 0 ? ~((1<<2)|(2<<4)) : ~((2<<2)|(1<<4));
1546         if(azxp > bias*azxn + radius) mask &= dzxp < 0 ? ~((1<<4)|(1<<0)) : ~((2<<4)|(2<<0));
1547         if(azxn > bias*azxp + radius) mask &= dzxn < 0 ? ~((1<<4)|(2<<0)) : ~((2<<4)|(1<<0));
1548         return mask;
1549 }
1550
1551 static int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border)
1552 {
1553         int i;
1554         vec3_t o, p, n;
1555         int sides = 0x3F, masks[6] = { 3<<4, 3<<4, 3<<0, 3<<0, 3<<2, 3<<2 };
1556         float scale = (size - 2*border)/size, len;
1557         float bias = border / (float)(size - border), dp, dn, ap, an;
1558         // check if cone enclosing side would cross frustum plane 
1559         scale = 2 / (scale*scale + 2);
1560         Matrix4x4_OriginFromMatrix(&rtlight->matrix_lighttoworld, o);
1561         for (i = 0;i < 5;i++)
1562         {
1563                 if (PlaneDiff(o, &r_refdef.view.frustum[i]) > -0.03125)
1564                         continue;
1565                 Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[i].normal, n);
1566                 len = scale*VectorLength2(n);
1567                 if(n[0]*n[0] > len) sides &= n[0] < 0 ? ~(1<<0) : ~(2 << 0);
1568                 if(n[1]*n[1] > len) sides &= n[1] < 0 ? ~(1<<2) : ~(2 << 2);
1569                 if(n[2]*n[2] > len) sides &= n[2] < 0 ? ~(1<<4) : ~(2 << 4);
1570         }
1571         if (PlaneDiff(o, &r_refdef.view.frustum[4]) >= r_refdef.farclip - r_refdef.nearclip + 0.03125)
1572         {
1573                 Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[4].normal, n);
1574                 len = scale*VectorLength2(n);
1575                 if(n[0]*n[0] > len) sides &= n[0] >= 0 ? ~(1<<0) : ~(2 << 0);
1576                 if(n[1]*n[1] > len) sides &= n[1] >= 0 ? ~(1<<2) : ~(2 << 2);
1577                 if(n[2]*n[2] > len) sides &= n[2] >= 0 ? ~(1<<4) : ~(2 << 4);
1578         }
1579         // this next test usually clips off more sides than the former, but occasionally clips fewer/different ones, so do both and combine results
1580         // check if frustum corners/origin cross plane sides
1581 #if 1
1582         // infinite version, assumes frustum corners merely give direction and extend to infinite distance
1583         Matrix4x4_Transform(&rtlight->matrix_worldtolight, r_refdef.view.origin, p);
1584         dp = p[0] + p[1], dn = p[0] - p[1], ap = fabs(dp), an = fabs(dn);
1585         masks[0] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1586         masks[1] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1587         dp = p[1] + p[2], dn = p[1] - p[2], ap = fabs(dp), an = fabs(dn);
1588         masks[2] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1589         masks[3] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1590         dp = p[2] + p[0], dn = p[2] - p[0], ap = fabs(dp), an = fabs(dn);
1591         masks[4] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
1592         masks[5] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1593         for (i = 0;i < 4;i++)
1594         {
1595                 Matrix4x4_Transform(&rtlight->matrix_worldtolight, r_refdef.view.frustumcorner[i], n);
1596                 VectorSubtract(n, p, n);
1597                 dp = n[0] + n[1], dn = n[0] - n[1], ap = fabs(dp), an = fabs(dn);
1598                 if(ap > 0) masks[0] |= dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2);
1599                 if(an > 0) masks[1] |= dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2);
1600                 dp = n[1] + n[2], dn = n[1] - n[2], ap = fabs(dp), an = fabs(dn);
1601                 if(ap > 0) masks[2] |= dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4);
1602                 if(an > 0) masks[3] |= dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4);
1603                 dp = n[2] + n[0], dn = n[2] - n[0], ap = fabs(dp), an = fabs(dn);
1604                 if(ap > 0) masks[4] |= dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0);
1605                 if(an > 0) masks[5] |= dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0);
1606         }
1607 #else
1608         // finite version, assumes corners are a finite distance from origin dependent on far plane
1609         for (i = 0;i < 5;i++)
1610         {
1611                 Matrix4x4_Transform(&rtlight->matrix_worldtolight, !i ? r_refdef.view.origin : r_refdef.view.frustumcorner[i-1], p);
1612                 dp = p[0] + p[1], dn = p[0] - p[1], ap = fabs(dp), an = fabs(dn);
1613                 masks[0] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
1614                 masks[1] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
1615                 dp = p[1] + p[2], dn = p[1] - p[2], ap = fabs(dp), an = fabs(dn);
1616                 masks[2] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
1617                 masks[3] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
1618                 dp = p[2] + p[0], dn = p[2] - p[0], ap = fabs(dp), an = fabs(dn);
1619                 masks[4] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
1620                 masks[5] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
1621         }
1622 #endif
1623         return sides & masks[0] & masks[1] & masks[2] & masks[3] & masks[4] & masks[5];
1624 }
1625
1626 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)
1627 {
1628         int t, tend;
1629         const int *e;
1630         const float *v[3];
1631         float normal[3];
1632         vec3_t p[3];
1633         float bias;
1634         int mask, surfacemask = 0;
1635         if (!BoxesOverlap(lightmins, lightmaxs, surfacemins, surfacemaxs))
1636                 return 0;
1637         bias = r_shadow_shadowmapborder / (float)(r_shadow_shadowmapmaxsize - r_shadow_shadowmapborder);
1638         tend = firsttriangle + numtris;
1639         if (BoxInsideBox(surfacemins, surfacemaxs, lightmins, lightmaxs))
1640         {
1641                 // surface box entirely inside light box, no box cull
1642                 if (projectdirection)
1643                 {
1644                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1645                         {
1646                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3, v[2] = invertex3f + e[2] * 3;
1647                                 TriangleNormal(v[0], v[1], v[2], normal);
1648                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0))
1649                                 {
1650                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1651                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1652                                         surfacemask |= mask;
1653                                         if(totals)
1654                                         {
1655                                                 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;
1656                                                 shadowsides[numshadowsides] = mask;
1657                                                 shadowsideslist[numshadowsides++] = t;
1658                                         }
1659                                 }
1660                         }
1661                 }
1662                 else
1663                 {
1664                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1665                         {
1666                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3,     v[2] = invertex3f + e[2] * 3;
1667                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2]))
1668                                 {
1669                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1670                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1671                                         surfacemask |= mask;
1672                                         if(totals)
1673                                         {
1674                                                 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;
1675                                                 shadowsides[numshadowsides] = mask;
1676                                                 shadowsideslist[numshadowsides++] = t;
1677                                         }
1678                                 }
1679                         }
1680                 }
1681         }
1682         else
1683         {
1684                 // surface box not entirely inside light box, cull each triangle
1685                 if (projectdirection)
1686                 {
1687                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1688                         {
1689                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3,     v[2] = invertex3f + e[2] * 3;
1690                                 TriangleNormal(v[0], v[1], v[2], normal);
1691                                 if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0)
1692                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1693                                 {
1694                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1695                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1696                                         surfacemask |= mask;
1697                                         if(totals)
1698                                         {
1699                                                 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;
1700                                                 shadowsides[numshadowsides] = mask;
1701                                                 shadowsideslist[numshadowsides++] = t;
1702                                         }
1703                                 }
1704                         }
1705                 }
1706                 else
1707                 {
1708                         for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3)
1709                         {
1710                                 v[0] = invertex3f + e[0] * 3, v[1] = invertex3f + e[1] * 3, v[2] = invertex3f + e[2] * 3;
1711                                 if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2])
1712                                  && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs))
1713                                 {
1714                                         Matrix4x4_Transform(worldtolight, v[0], p[0]), Matrix4x4_Transform(worldtolight, v[1], p[1]), Matrix4x4_Transform(worldtolight, v[2], p[2]);
1715                                         mask = R_Shadow_CalcTriangleSideMask(p[0], p[1], p[2], bias);
1716                                         surfacemask |= mask;
1717                                         if(totals)
1718                                         {
1719                                                 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;
1720                                                 shadowsides[numshadowsides] = mask;
1721                                                 shadowsideslist[numshadowsides++] = t;
1722                                         }
1723                                 }
1724                         }
1725                 }
1726         }
1727         return surfacemask;
1728 }
1729
1730 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)
1731 {
1732         int i, j, outtriangles = 0;
1733         int *outelement3i[6];
1734         if (!numverts || !numsidetris || !r_shadow_compilingrtlight)
1735                 return;
1736         outtriangles = sidetotals[0] + sidetotals[1] + sidetotals[2] + sidetotals[3] + sidetotals[4] + sidetotals[5];
1737         // make sure shadowelements is big enough for this mesh
1738         if (maxshadowtriangles < outtriangles)
1739                 R_Shadow_ResizeShadowArrays(0, outtriangles, 0, 1);
1740
1741         // compute the offset and size of the separate index lists for each cubemap side
1742         outtriangles = 0;
1743         for (i = 0;i < 6;i++)
1744         {
1745                 outelement3i[i] = shadowelements + outtriangles * 3;
1746                 r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap->sideoffsets[i] = outtriangles;
1747                 r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap->sidetotals[i] = sidetotals[i];
1748                 outtriangles += sidetotals[i];
1749         }
1750
1751         // gather up the (sparse) triangles into separate index lists for each cubemap side
1752         for (i = 0;i < numsidetris;i++)
1753         {
1754                 const int *element = elements + sidetris[i] * 3;
1755                 for (j = 0;j < 6;j++)
1756                 {
1757                         if (sides[i] & (1 << j))
1758                         {
1759                                 outelement3i[j][0] = element[0];
1760                                 outelement3i[j][1] = element[1];
1761                                 outelement3i[j][2] = element[2];
1762                                 outelement3i[j] += 3;
1763                         }
1764                 }
1765         }
1766                         
1767         Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap, NULL, NULL, NULL, vertex3f, NULL, NULL, NULL, NULL, outtriangles, shadowelements);
1768 }
1769
1770 static void R_Shadow_MakeTextures_MakeCorona(void)
1771 {
1772         float dx, dy;
1773         int x, y, a;
1774         unsigned char pixels[32][32][4];
1775         for (y = 0;y < 32;y++)
1776         {
1777                 dy = (y - 15.5f) * (1.0f / 16.0f);
1778                 for (x = 0;x < 32;x++)
1779                 {
1780                         dx = (x - 15.5f) * (1.0f / 16.0f);
1781                         a = (int)(((1.0f / (dx * dx + dy * dy + 0.2f)) - (1.0f / (1.0f + 0.2))) * 32.0f / (1.0f / (1.0f + 0.2)));
1782                         a = bound(0, a, 255);
1783                         pixels[y][x][0] = a;
1784                         pixels[y][x][1] = a;
1785                         pixels[y][x][2] = a;
1786                         pixels[y][x][3] = 255;
1787                 }
1788         }
1789         r_shadow_lightcorona = R_SkinFrame_LoadInternalBGRA("lightcorona", TEXF_FORCELINEAR, &pixels[0][0][0], 32, 32, false);
1790 }
1791
1792 static unsigned int R_Shadow_MakeTextures_SamplePoint(float x, float y, float z)
1793 {
1794         float dist = sqrt(x*x+y*y+z*z);
1795         float intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
1796         // note this code could suffer byte order issues except that it is multiplying by an integer that reads the same both ways
1797         return (unsigned char)bound(0, intensity * 256.0f, 255) * 0x01010101;
1798 }
1799
1800 static void R_Shadow_MakeTextures(void)
1801 {
1802         int x, y, z;
1803         float intensity, dist;
1804         unsigned int *data;
1805         R_Shadow_FreeShadowMaps();
1806         R_FreeTexturePool(&r_shadow_texturepool);
1807         r_shadow_texturepool = R_AllocTexturePool();
1808         r_shadow_attenlinearscale = r_shadow_lightattenuationlinearscale.value;
1809         r_shadow_attendividebias = r_shadow_lightattenuationdividebias.value;
1810         data = (unsigned int *)Mem_Alloc(tempmempool, max(max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE, ATTEN2DSIZE*ATTEN2DSIZE), ATTEN1DSIZE) * 4);
1811         // the table includes one additional value to avoid the need to clamp indexing due to minor math errors
1812         for (x = 0;x <= ATTENTABLESIZE;x++)
1813         {
1814                 dist = (x + 0.5f) * (1.0f / ATTENTABLESIZE) * (1.0f / 0.9375);
1815                 intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
1816                 r_shadow_attentable[x] = bound(0, intensity, 1);
1817         }
1818         // 1D gradient texture
1819         for (x = 0;x < ATTEN1DSIZE;x++)
1820                 data[x] = R_Shadow_MakeTextures_SamplePoint((x + 0.5f) * (1.0f / ATTEN1DSIZE) * (1.0f / 0.9375), 0, 0);
1821         r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
1822         // 2D circle texture
1823         for (y = 0;y < ATTEN2DSIZE;y++)
1824                 for (x = 0;x < ATTEN2DSIZE;x++)
1825                         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);
1826         r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, -1, NULL);
1827         // 3D sphere texture
1828         if (r_shadow_texture3d.integer && vid.support.ext_texture_3d)
1829         {
1830                 for (z = 0;z < ATTEN3DSIZE;z++)
1831                         for (y = 0;y < ATTEN3DSIZE;y++)
1832                                 for (x = 0;x < ATTEN3DSIZE;x++)
1833                                         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));
1834                 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);
1835         }
1836         else
1837                 r_shadow_attenuation3dtexture = NULL;
1838         Mem_Free(data);
1839
1840         R_Shadow_MakeTextures_MakeCorona();
1841
1842         // Editor light sprites
1843         r_editlights_sprcursor = R_SkinFrame_LoadInternal8bit("gfx/editlights/cursor", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1844         "................"
1845         ".3............3."
1846         "..5...2332...5.."
1847         "...7.3....3.7..."
1848         "....7......7...."
1849         "...3.7....7.3..."
1850         "..2...7..7...2.."
1851         "..3..........3.."
1852         "..3..........3.."
1853         "..2...7..7...2.."
1854         "...3.7....7.3..."
1855         "....7......7...."
1856         "...7.3....3.7..."
1857         "..5...2332...5.."
1858         ".3............3."
1859         "................"
1860         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1861         r_editlights_sprlight = R_SkinFrame_LoadInternal8bit("gfx/editlights/light", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1862         "................"
1863         "................"
1864         "......1111......"
1865         "....11233211...."
1866         "...1234554321..."
1867         "...1356776531..."
1868         "..124677776421.."
1869         "..135777777531.."
1870         "..135777777531.."
1871         "..124677776421.."
1872         "...1356776531..."
1873         "...1234554321..."
1874         "....11233211...."
1875         "......1111......"
1876         "................"
1877         "................"
1878         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1879         r_editlights_sprnoshadowlight = R_SkinFrame_LoadInternal8bit("gfx/editlights/noshadow", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1880         "................"
1881         "................"
1882         "......1111......"
1883         "....11233211...."
1884         "...1234554321..."
1885         "...1356226531..."
1886         "..12462..26421.."
1887         "..1352....2531.."
1888         "..1352....2531.."
1889         "..12462..26421.."
1890         "...1356226531..."
1891         "...1234554321..."
1892         "....11233211...."
1893         "......1111......"
1894         "................"
1895         "................"
1896         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1897         r_editlights_sprcubemaplight = R_SkinFrame_LoadInternal8bit("gfx/editlights/cubemaplight", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1898         "................"
1899         "................"
1900         "......2772......"
1901         "....27755772...."
1902         "..277533335772.."
1903         "..753333333357.."
1904         "..777533335777.."
1905         "..735775577537.."
1906         "..733357753337.."
1907         "..733337733337.."
1908         "..753337733357.."
1909         "..277537735772.."
1910         "....27777772...."
1911         "......2772......"
1912         "................"
1913         "................"
1914         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1915         r_editlights_sprcubemapnoshadowlight = R_SkinFrame_LoadInternal8bit("gfx/editlights/cubemapnoshadowlight", TEXF_ALPHA | TEXF_CLAMP, (const unsigned char *)
1916         "................"
1917         "................"
1918         "......2772......"
1919         "....27722772...."
1920         "..2772....2772.."
1921         "..72........27.."
1922         "..7772....2777.."
1923         "..7.27722772.7.."
1924         "..7...2772...7.."
1925         "..7....77....7.."
1926         "..72...77...27.."
1927         "..2772.77.2772.."
1928         "....27777772...."
1929         "......2772......"
1930         "................"
1931         "................"
1932         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1933         r_editlights_sprselection = R_SkinFrame_LoadInternal8bit("gfx/editlights/selection", TEXF_ALPHA | TEXF_CLAMP, (unsigned char *)
1934         "................"
1935         ".777752..257777."
1936         ".742........247."
1937         ".72..........27."
1938         ".7............7."
1939         ".5............5."
1940         ".2............2."
1941         "................"
1942         "................"
1943         ".2............2."
1944         ".5............5."
1945         ".7............7."
1946         ".72..........27."
1947         ".742........247."
1948         ".777752..257777."
1949         "................"
1950         , 16, 16, palette_bgra_embeddedpic, palette_bgra_embeddedpic);
1951 }
1952
1953 void R_Shadow_ValidateCvars(void)
1954 {
1955         if (r_shadow_texture3d.integer && !vid.support.ext_texture_3d)
1956                 Cvar_SetValueQuick(&r_shadow_texture3d, 0);
1957         if (gl_ext_separatestencil.integer && !vid.support.ati_separate_stencil)
1958                 Cvar_SetValueQuick(&gl_ext_separatestencil, 0);
1959         if (gl_ext_stenciltwoside.integer && !vid.support.ext_stencil_two_side)
1960                 Cvar_SetValueQuick(&gl_ext_stenciltwoside, 0);
1961 }
1962
1963 void R_Shadow_RenderMode_Begin(void)
1964 {
1965 #if 0
1966         GLint drawbuffer;
1967         GLint readbuffer;
1968 #endif
1969         R_Shadow_ValidateCvars();
1970
1971         if (!r_shadow_attenuation2dtexture
1972          || (!r_shadow_attenuation3dtexture && r_shadow_texture3d.integer)
1973          || r_shadow_lightattenuationdividebias.value != r_shadow_attendividebias
1974          || r_shadow_lightattenuationlinearscale.value != r_shadow_attenlinearscale)
1975                 R_Shadow_MakeTextures();
1976
1977         CHECKGLERROR
1978         R_Mesh_ResetTextureState();
1979         GL_BlendFunc(GL_ONE, GL_ZERO);
1980         GL_DepthRange(0, 1);
1981         GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
1982         GL_DepthTest(true);
1983         GL_DepthMask(false);
1984         GL_Color(0, 0, 0, 1);
1985         GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
1986         
1987         r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
1988
1989         if (gl_ext_separatestencil.integer && vid.support.ati_separate_stencil)
1990         {
1991                 r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_SEPARATESTENCIL;
1992                 r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_SEPARATESTENCIL;
1993         }
1994         else if (gl_ext_stenciltwoside.integer && vid.support.ext_stencil_two_side)
1995         {
1996                 r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE;
1997                 r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_STENCILTWOSIDE;
1998         }
1999         else
2000         {
2001                 r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_STENCIL;
2002                 r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_STENCIL;
2003         }
2004
2005         switch(vid.renderpath)
2006         {
2007         case RENDERPATH_GL20:
2008         case RENDERPATH_D3D9:
2009         case RENDERPATH_D3D10:
2010         case RENDERPATH_D3D11:
2011         case RENDERPATH_SOFT:
2012         case RENDERPATH_GLES2:
2013                 r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_GLSL;
2014                 break;
2015         case RENDERPATH_GL11:
2016         case RENDERPATH_GL13:
2017         case RENDERPATH_GLES1:
2018                 if (r_textureunits.integer >= 2 && vid.texunits >= 2 && r_shadow_texture3d.integer && r_shadow_attenuation3dtexture)
2019                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN;
2020                 else if (r_textureunits.integer >= 3 && vid.texunits >= 3)
2021                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN;
2022                 else if (r_textureunits.integer >= 2 && vid.texunits >= 2)
2023                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN;
2024                 else
2025                         r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_VERTEX;
2026                 break;
2027         }
2028
2029         CHECKGLERROR
2030 #if 0
2031         qglGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);CHECKGLERROR
2032         qglGetIntegerv(GL_READ_BUFFER, &readbuffer);CHECKGLERROR
2033         r_shadow_drawbuffer = drawbuffer;
2034         r_shadow_readbuffer = readbuffer;
2035 #endif
2036         r_shadow_cullface_front = r_refdef.view.cullface_front;
2037         r_shadow_cullface_back = r_refdef.view.cullface_back;
2038 }
2039
2040 void R_Shadow_RenderMode_ActiveLight(const rtlight_t *rtlight)
2041 {
2042         rsurface.rtlight = rtlight;
2043 }
2044
2045 void R_Shadow_RenderMode_Reset(void)
2046 {
2047         R_Mesh_ResetTextureState();
2048         R_Mesh_SetRenderTargets(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture, NULL, NULL, NULL);
2049         R_SetViewport(&r_refdef.view.viewport);
2050         GL_Scissor(r_shadow_lightscissor[0], r_shadow_lightscissor[1], r_shadow_lightscissor[2], r_shadow_lightscissor[3]);
2051         GL_DepthRange(0, 1);
2052         GL_DepthTest(true);
2053         GL_DepthMask(false);
2054         GL_DepthFunc(GL_LEQUAL);
2055         GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
2056         r_refdef.view.cullface_front = r_shadow_cullface_front;
2057         r_refdef.view.cullface_back = r_shadow_cullface_back;
2058         GL_CullFace(r_refdef.view.cullface_back);
2059         GL_Color(1, 1, 1, 1);
2060         GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
2061         GL_BlendFunc(GL_ONE, GL_ZERO);
2062         R_SetupShader_Generic_NoTexture(false, false);
2063         r_shadow_usingshadowmap2d = false;
2064         r_shadow_usingshadowmaportho = false;
2065         R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
2066 }
2067
2068 void R_Shadow_ClearStencil(void)
2069 {
2070         GL_Clear(GL_STENCIL_BUFFER_BIT, NULL, 1.0f, 128);
2071         r_refdef.stats[r_stat_lights_clears]++;
2072 }
2073
2074 void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass)
2075 {
2076         r_shadow_rendermode_t mode = zpass ? r_shadow_shadowingrendermode_zpass : r_shadow_shadowingrendermode_zfail;
2077         if (r_shadow_rendermode == mode)
2078                 return;
2079         R_Shadow_RenderMode_Reset();
2080         GL_DepthFunc(GL_LESS);
2081         GL_ColorMask(0, 0, 0, 0);
2082         GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR
2083         GL_CullFace(GL_NONE);
2084         R_SetupShader_DepthOrShadow(false, false, false); // FIXME test if we have a skeletal model?
2085         r_shadow_rendermode = mode;
2086         switch(mode)
2087         {
2088         default:
2089                 break;
2090         case R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE:
2091         case R_SHADOW_RENDERMODE_ZPASS_SEPARATESTENCIL:
2092                 R_SetStencilSeparate(true, 255, GL_KEEP, GL_KEEP, GL_INCR, GL_KEEP, GL_KEEP, GL_DECR, GL_ALWAYS, GL_ALWAYS, 128, 255);
2093                 break;
2094         case R_SHADOW_RENDERMODE_ZFAIL_STENCILTWOSIDE:
2095         case R_SHADOW_RENDERMODE_ZFAIL_SEPARATESTENCIL:
2096                 R_SetStencilSeparate(true, 255, GL_KEEP, GL_INCR, GL_KEEP, GL_KEEP, GL_DECR, GL_KEEP, GL_ALWAYS, GL_ALWAYS, 128, 255);
2097                 break;
2098         }
2099 }
2100
2101 static void R_Shadow_MakeVSDCT(void)
2102 {
2103         // maps to a 2x3 texture rectangle with normalized coordinates
2104         // +-
2105         // XX
2106         // YY
2107         // ZZ
2108         // stores abs(dir.xy), offset.xy/2.5
2109         unsigned char data[4*6] =
2110         {
2111                 255, 0, 0x33, 0x33, // +X: <1, 0>, <0.5, 0.5>
2112                 255, 0, 0x99, 0x33, // -X: <1, 0>, <1.5, 0.5>
2113                 0, 255, 0x33, 0x99, // +Y: <0, 1>, <0.5, 1.5>
2114                 0, 255, 0x99, 0x99, // -Y: <0, 1>, <1.5, 1.5>
2115                 0,   0, 0x33, 0xFF, // +Z: <0, 0>, <0.5, 2.5>
2116                 0,   0, 0x99, 0xFF, // -Z: <0, 0>, <1.5, 2.5>
2117         };
2118         r_shadow_shadowmapvsdcttexture = R_LoadTextureCubeMap(r_shadow_texturepool, "shadowmapvsdct", 1, data, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL);
2119 }
2120
2121 static void R_Shadow_MakeShadowMap(int side, int size)
2122 {
2123         switch (r_shadow_shadowmode)
2124         {
2125         case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
2126                 if (r_shadow_shadowmap2ddepthtexture) return;
2127                 if (r_fb.usedepthtextures)
2128                 {
2129                         r_shadow_shadowmap2ddepthtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), 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);
2130                         r_shadow_shadowmap2ddepthbuffer = NULL;
2131                         r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL);
2132                 }
2133                 else
2134                 {
2135                         r_shadow_shadowmap2ddepthtexture = R_LoadTexture2D(r_shadow_texturepool, "shadowmaprendertarget", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL);
2136                         r_shadow_shadowmap2ddepthbuffer = R_LoadTextureRenderBuffer(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), r_shadow_shadowmapdepthbits >= 24 ? TEXTYPE_DEPTHBUFFER24 : TEXTYPE_DEPTHBUFFER16);
2137                         r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL);
2138                 }
2139                 break;
2140         default:
2141                 return;
2142         }
2143 }
2144
2145 static void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
2146 {
2147         float nearclip, farclip, bias;
2148         r_viewport_t viewport;
2149         int flipped;
2150         GLuint fbo2d = 0;
2151         float clearcolor[4];
2152         nearclip = r_shadow_shadowmapping_nearclip.value / rsurface.rtlight->radius;
2153         farclip = 1.0f;
2154         bias = r_shadow_shadowmapping_bias.value * nearclip * (1024.0f / size);// * rsurface.rtlight->radius;
2155         r_shadow_shadowmap_parameters[1] = -nearclip * farclip / (farclip - nearclip) - 0.5f * bias;
2156         r_shadow_shadowmap_parameters[3] = 0.5f + 0.5f * (farclip + nearclip) / (farclip - nearclip);
2157         r_shadow_shadowmapside = side;
2158         r_shadow_shadowmapsize = size;
2159
2160         r_shadow_shadowmap_parameters[0] = 0.5f * (size - r_shadow_shadowmapborder);
2161         r_shadow_shadowmap_parameters[2] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
2162         R_Viewport_InitRectSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, r_shadow_shadowmapborder, nearclip, farclip, NULL);
2163         if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAP2D) goto init_done;
2164
2165         // complex unrolled cube approach (more flexible)
2166         if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapvsdcttexture)
2167                 R_Shadow_MakeVSDCT();
2168         if (!r_shadow_shadowmap2ddepthtexture)
2169                 R_Shadow_MakeShadowMap(side, r_shadow_shadowmapmaxsize);
2170         fbo2d = r_shadow_fbo2d;
2171         r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2ddepthtexture);
2172         r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2ddepthtexture);
2173         r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D;
2174
2175         R_Mesh_ResetTextureState();
2176         R_Shadow_RenderMode_Reset();
2177         if (r_shadow_shadowmap2ddepthbuffer)
2178                 R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL);
2179         else
2180                 R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL);
2181         R_SetupShader_DepthOrShadow(true, r_shadow_shadowmap2ddepthbuffer != NULL, false); // FIXME test if we have a skeletal model?
2182         GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value);
2183         GL_DepthMask(true);
2184         GL_DepthTest(true);
2185
2186 init_done:
2187         R_SetViewport(&viewport);
2188         flipped = (side & 1) ^ (side >> 2);
2189         r_refdef.view.cullface_front = flipped ? r_shadow_cullface_back : r_shadow_cullface_front;
2190         r_refdef.view.cullface_back = flipped ? r_shadow_cullface_front : r_shadow_cullface_back;
2191         if (r_shadow_shadowmap2ddepthbuffer)
2192         {
2193                 // completely different meaning than in depthtexture approach
2194                 r_shadow_shadowmap_parameters[1] = 0;
2195                 r_shadow_shadowmap_parameters[3] = -bias;
2196         }
2197         Vector4Set(clearcolor, 1,1,1,1);
2198         if (r_shadow_shadowmap2ddepthbuffer)
2199                 GL_ColorMask(1,1,1,1);
2200         else
2201                 GL_ColorMask(0,0,0,0);
2202         switch(vid.renderpath)
2203         {
2204         case RENDERPATH_GL11:
2205         case RENDERPATH_GL13:
2206         case RENDERPATH_GL20:
2207         case RENDERPATH_SOFT:
2208         case RENDERPATH_GLES1:
2209         case RENDERPATH_GLES2:
2210                 GL_CullFace(r_refdef.view.cullface_back);
2211                 // OpenGL lets us scissor larger than the viewport, so go ahead and clear all views at once
2212                 if ((clear & ((2 << side) - 1)) == (1 << side)) // only clear if the side is the first in the mask
2213                 {
2214                         // get tightest scissor rectangle that encloses all viewports in the clear mask
2215                         int x1 = clear & 0x15 ? 0 : size;
2216                         int x2 = clear & 0x2A ? 2 * size : size;
2217                         int y1 = clear & 0x03 ? 0 : (clear & 0xC ? size : 2 * size);
2218                         int y2 = clear & 0x30 ? 3 * size : (clear & 0xC ? 2 * size : size);
2219                         GL_Scissor(x1, y1, x2 - x1, y2 - y1);
2220                         if (clear)
2221                         {
2222                                 if (r_shadow_shadowmap2ddepthbuffer)
2223                                         GL_Clear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0);
2224                                 else
2225                                         GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0);
2226                         }
2227                 }
2228                 GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
2229                 break;
2230         case RENDERPATH_D3D9:
2231         case RENDERPATH_D3D10:
2232         case RENDERPATH_D3D11:
2233                 // we invert the cull mode because we flip the projection matrix
2234                 // NOTE: this actually does nothing because the DrawShadowMap code sets it to doublesided...
2235                 GL_CullFace(r_refdef.view.cullface_front);
2236                 // D3D considers it an error to use a scissor larger than the viewport...  clear just this view
2237                 GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
2238                 if (clear)
2239                 {
2240                         if (r_shadow_shadowmap2ddepthbuffer)
2241                                 GL_Clear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0);
2242                         else
2243                                 GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0);
2244                 }
2245                 break;
2246         }
2247 }
2248
2249 void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qboolean shadowmapping)
2250 {
2251         R_Mesh_ResetTextureState();
2252         if (transparent)
2253         {
2254                 r_shadow_lightscissor[0] = r_refdef.view.viewport.x;
2255                 r_shadow_lightscissor[1] = r_refdef.view.viewport.y;
2256                 r_shadow_lightscissor[2] = r_refdef.view.viewport.width;
2257                 r_shadow_lightscissor[3] = r_refdef.view.viewport.height;
2258         }
2259         R_Shadow_RenderMode_Reset();
2260         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2261         if (!transparent)
2262                 GL_DepthFunc(GL_EQUAL);
2263         // do global setup needed for the chosen lighting mode
2264         if (r_shadow_rendermode == R_SHADOW_RENDERMODE_LIGHT_GLSL)
2265                 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 0);
2266         r_shadow_usingshadowmap2d = shadowmapping;
2267         r_shadow_rendermode = r_shadow_lightingrendermode;
2268         // only draw light where this geometry was already rendered AND the
2269         // stencil is 128 (values other than this mean shadow)
2270         if (stenciltest)
2271                 R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255);
2272         else
2273                 R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
2274 }
2275
2276 static const unsigned short bboxelements[36] =
2277 {
2278         5, 1, 3, 5, 3, 7,
2279         6, 2, 0, 6, 0, 4,
2280         7, 3, 2, 7, 2, 6,
2281         4, 0, 1, 4, 1, 5,
2282         4, 5, 7, 4, 7, 6,
2283         1, 0, 2, 1, 2, 3,
2284 };
2285
2286 static const float bboxpoints[8][3] =
2287 {
2288         {-1,-1,-1},
2289         { 1,-1,-1},
2290         {-1, 1,-1},
2291         { 1, 1,-1},
2292         {-1,-1, 1},
2293         { 1,-1, 1},
2294         {-1, 1, 1},
2295         { 1, 1, 1},
2296 };
2297
2298 void R_Shadow_RenderMode_DrawDeferredLight(qboolean stenciltest, qboolean shadowmapping)
2299 {
2300         int i;
2301         float vertex3f[8*3];
2302         const matrix4x4_t *matrix = &rsurface.rtlight->matrix_lighttoworld;
2303 // do global setup needed for the chosen lighting mode
2304         R_Shadow_RenderMode_Reset();
2305         r_shadow_rendermode = r_shadow_lightingrendermode;
2306         R_EntityMatrix(&identitymatrix);
2307         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2308         // only draw light where this geometry was already rendered AND the
2309         // stencil is 128 (values other than this mean shadow)
2310         R_SetStencil(stenciltest, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255);
2311         if (rsurface.rtlight->specularscale > 0 && r_shadow_gloss.integer > 0)
2312                 R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL);
2313         else
2314                 R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL);
2315
2316         r_shadow_usingshadowmap2d = shadowmapping;
2317
2318         // render the lighting
2319         R_SetupShader_DeferredLight(rsurface.rtlight);
2320         for (i = 0;i < 8;i++)
2321                 Matrix4x4_Transform(matrix, bboxpoints[i], vertex3f + i*3);
2322         GL_ColorMask(1,1,1,1);
2323         GL_DepthMask(false);
2324         GL_DepthRange(0, 1);
2325         GL_PolygonOffset(0, 0);
2326         GL_DepthTest(true);
2327         GL_DepthFunc(GL_GREATER);
2328         GL_CullFace(r_refdef.view.cullface_back);
2329         R_Mesh_PrepareVertices_Vertex3f(8, vertex3f, NULL, 0);
2330         R_Mesh_Draw(0, 8, 0, 12, NULL, NULL, 0, bboxelements, NULL, 0);
2331 }
2332
2333 // these are temporary data per-frame, sorted and performed in a more
2334 // cache-friendly order than the original photons
2335 typedef struct r_shadow_bouncegrid_splatpath_s
2336 {
2337         vec3_t point;
2338         vec3_t step;
2339         vec3_t splatcolor;
2340         vec3_t splatdir;
2341         vec_t splatintensity;
2342         int remainingsplats;
2343 }
2344 r_shadow_bouncegrid_splatpath_t;
2345
2346 static void R_shadow_BounceGrid_AddSplatPath(vec3_t originalstart, vec3_t originalend, vec3_t color)
2347 {
2348         int bestaxis;
2349         int numsplats;
2350         float len;
2351         float ilen;
2352         vec3_t start;
2353         vec3_t end;
2354         vec3_t diff;
2355         vec3_t originaldir;
2356         r_shadow_bouncegrid_splatpath_t *path;
2357
2358         // cull paths that fail R_CullBox in dynamic mode
2359         if (!r_shadow_bouncegrid_state.settings.staticmode
2360          && r_shadow_bouncegrid_dynamic_culllightpaths.integer)
2361         {
2362                 vec3_t cullmins, cullmaxs;
2363                 cullmins[0] = min(originalstart[0], originalend[0]) - r_shadow_bouncegrid_state.settings.spacing[0];
2364                 cullmins[1] = min(originalstart[1], originalend[1]) - r_shadow_bouncegrid_state.settings.spacing[1];
2365                 cullmins[2] = min(originalstart[2], originalend[2]) - r_shadow_bouncegrid_state.settings.spacing[2];
2366                 cullmaxs[0] = max(originalstart[0], originalend[0]) + r_shadow_bouncegrid_state.settings.spacing[0];
2367                 cullmaxs[1] = max(originalstart[1], originalend[1]) + r_shadow_bouncegrid_state.settings.spacing[1];
2368                 cullmaxs[2] = max(originalstart[2], originalend[2]) + r_shadow_bouncegrid_state.settings.spacing[2];
2369                 if (R_CullBox(cullmins, cullmaxs))
2370                         return;
2371         }
2372
2373         // if the light path is going upward, reverse it - we always draw down.
2374         if (originalend[2] < originalstart[2])
2375         {
2376                 VectorCopy(originalend, start);
2377                 VectorCopy(originalstart, end);
2378         }
2379         else
2380         {
2381                 VectorCopy(originalstart, start);
2382                 VectorCopy(originalend, end);
2383         }
2384
2385         // transform to texture pixels
2386         start[0] = (start[0] - r_shadow_bouncegrid_state.mins[0]) * r_shadow_bouncegrid_state.ispacing[0];
2387         start[1] = (start[1] - r_shadow_bouncegrid_state.mins[1]) * r_shadow_bouncegrid_state.ispacing[1];
2388         start[2] = (start[2] - r_shadow_bouncegrid_state.mins[2]) * r_shadow_bouncegrid_state.ispacing[2];
2389         end[0] = (end[0] - r_shadow_bouncegrid_state.mins[0]) * r_shadow_bouncegrid_state.ispacing[0];
2390         end[1] = (end[1] - r_shadow_bouncegrid_state.mins[1]) * r_shadow_bouncegrid_state.ispacing[1];
2391         end[2] = (end[2] - r_shadow_bouncegrid_state.mins[2]) * r_shadow_bouncegrid_state.ispacing[2];
2392
2393         // check if we need to grow the splatpaths array
2394         if (r_shadow_bouncegrid_state.maxsplatpaths <= r_shadow_bouncegrid_state.numsplatpaths)
2395         {
2396                 // double the limit, this will persist from frame to frame so we don't
2397                 // make the same mistake each time
2398                 r_shadow_bouncegrid_splatpath_t *newpaths;
2399                 r_shadow_bouncegrid_state.maxsplatpaths *= 2;
2400                 newpaths = (r_shadow_bouncegrid_splatpath_t *)R_FrameData_Alloc(sizeof(r_shadow_bouncegrid_splatpath_t) * r_shadow_bouncegrid_state.maxsplatpaths);
2401                 if (r_shadow_bouncegrid_state.splatpaths)
2402                         memcpy(newpaths, r_shadow_bouncegrid_state.splatpaths, r_shadow_bouncegrid_state.numsplatpaths * sizeof(r_shadow_bouncegrid_splatpath_t));
2403                 r_shadow_bouncegrid_state.splatpaths = newpaths;
2404         }
2405
2406         // divide a series of splats along the length using the maximum axis
2407         VectorSubtract(end, start, diff);
2408         // pick the best axis to trace along
2409         bestaxis = 0;
2410         if (diff[1]*diff[1] > diff[bestaxis]*diff[bestaxis])
2411                 bestaxis = 1;
2412         if (diff[2]*diff[2] > diff[bestaxis]*diff[bestaxis])
2413                 bestaxis = 2;
2414         len = fabs(diff[bestaxis]);
2415         ilen = 1.0f / len;
2416         numsplats = (int)(floor(len + 0.5f));
2417         // sanity limits
2418         numsplats = bound(0, numsplats, 1024);
2419
2420         VectorSubtract(originalstart, originalend, originaldir);
2421         VectorNormalize(originaldir);
2422
2423         path = r_shadow_bouncegrid_state.splatpaths + r_shadow_bouncegrid_state.numsplatpaths++;
2424         VectorCopy(start, path->point);
2425         VectorScale(diff, ilen, path->step);
2426         VectorCopy(color, path->splatcolor);
2427         VectorCopy(originaldir, path->splatdir);
2428         path->splatintensity = VectorLength(color);
2429         path->remainingsplats = numsplats;
2430 }
2431
2432 static qboolean R_Shadow_BounceGrid_CheckEnable(int flag)
2433 {
2434         qboolean enable = r_shadow_bouncegrid_state.capable && r_shadow_bouncegrid.integer != 0 && r_refdef.scene.worldmodel;
2435         int lightindex;
2436         int range;
2437         dlight_t *light;
2438         rtlight_t *rtlight;
2439         vec3_t lightcolor;
2440
2441         // see if there are really any lights to render...
2442         if (enable && r_shadow_bouncegrid_static.integer)
2443         {
2444                 enable = false;
2445                 range = (unsigned int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
2446                 for (lightindex = 0;lightindex < range;lightindex++)
2447                 {
2448                         light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
2449                         if (!light || !(light->flags & flag))
2450                                 continue;
2451                         rtlight = &light->rtlight;
2452                         // when static, we skip styled lights because they tend to change...
2453                         if (rtlight->style > 0)
2454                                 continue;
2455                         VectorScale(rtlight->color, (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale), lightcolor);
2456                         if (!VectorLength2(lightcolor))
2457                                 continue;
2458                         enable = true;
2459                         break;
2460                 }
2461         }
2462
2463         return enable;
2464 }
2465
2466 static void R_Shadow_BounceGrid_GenerateSettings(r_shadow_bouncegrid_settings_t *settings)
2467 {
2468         qboolean s = r_shadow_bouncegrid_static.integer != 0;
2469         float spacing = s ? r_shadow_bouncegrid_static_spacing.value : r_shadow_bouncegrid_dynamic_spacing.value;
2470
2471         // prevent any garbage in alignment padded areas as we'll be using memcmp
2472         memset(settings, 0, sizeof(*settings)); 
2473
2474         // build up a complete collection of the desired settings, so that memcmp can be used to compare parameters
2475         settings->staticmode                    = s;
2476         settings->bounceanglediffuse            = r_shadow_bouncegrid_bounceanglediffuse.integer != 0;
2477         settings->directionalshading            = (s ? r_shadow_bouncegrid_static_directionalshading.integer != 0 : r_shadow_bouncegrid_dynamic_directionalshading.integer != 0) && r_shadow_bouncegrid_state.allowdirectionalshading;
2478         settings->dlightparticlemultiplier      = s ? 0 : r_shadow_bouncegrid_dynamic_dlightparticlemultiplier.value;
2479         settings->hitmodels                     = s ? false : r_shadow_bouncegrid_dynamic_hitmodels.integer != 0;
2480         settings->includedirectlighting         = r_shadow_bouncegrid_includedirectlighting.integer != 0 || r_shadow_bouncegrid.integer == 2;
2481         settings->lightradiusscale              = (s ? r_shadow_bouncegrid_static_lightradiusscale.value : r_shadow_bouncegrid_dynamic_lightradiusscale.value);
2482         settings->maxbounce                     = (s ? r_shadow_bouncegrid_static_maxbounce.integer : r_shadow_bouncegrid_dynamic_maxbounce.integer);
2483         settings->particlebounceintensity       = r_shadow_bouncegrid_particlebounceintensity.value;
2484         settings->particleintensity             = r_shadow_bouncegrid_particleintensity.value * 16384.0f * (settings->directionalshading ? 4.0f : 1.0f) / (spacing * spacing);
2485         settings->maxphotons                    = s ? r_shadow_bouncegrid_static_maxphotons.integer : r_shadow_bouncegrid_dynamic_maxphotons.integer;
2486         settings->energyperphoton            = s ? r_shadow_bouncegrid_static_energyperphoton.integer : r_shadow_bouncegrid_dynamic_energyperphoton.integer;
2487         settings->spacing[0]                    = spacing;
2488         settings->spacing[1]                    = spacing;
2489         settings->spacing[2]                    = spacing;
2490         settings->stablerandom                  = s ? 0 : r_shadow_bouncegrid_dynamic_stablerandom.integer;
2491
2492         // bound the values for sanity
2493         settings->maxphotons = bound(1, settings->maxphotons, 25000000);
2494         settings->lightradiusscale = bound(0.0001f, settings->lightradiusscale, 1024.0f);
2495         settings->maxbounce = bound(0, settings->maxbounce, 16);
2496         settings->spacing[0] = bound(1, settings->spacing[0], 512);
2497         settings->spacing[1] = bound(1, settings->spacing[1], 512);
2498         settings->spacing[2] = bound(1, settings->spacing[2], 512);
2499 }
2500
2501 static void R_Shadow_BounceGrid_UpdateSpacing(void)
2502 {
2503         float m[16];
2504         int c[4];
2505         int resolution[3];
2506         int numpixels;
2507         vec3_t ispacing;
2508         vec3_t maxs;
2509         vec3_t mins;
2510         vec3_t size;
2511         vec3_t spacing;
2512         r_shadow_bouncegrid_settings_t *settings = &r_shadow_bouncegrid_state.settings;
2513
2514         // get the spacing values
2515         spacing[0] = settings->spacing[0];
2516         spacing[1] = settings->spacing[1];
2517         spacing[2] = settings->spacing[2];
2518         ispacing[0] = 1.0f / spacing[0];
2519         ispacing[1] = 1.0f / spacing[1];
2520         ispacing[2] = 1.0f / spacing[2];
2521
2522         // calculate texture size enclosing entire world bounds at the spacing
2523         if (r_refdef.scene.worldmodel)
2524         {
2525                 VectorMA(r_refdef.scene.worldmodel->normalmins, -2.0f, spacing, mins);
2526                 VectorMA(r_refdef.scene.worldmodel->normalmaxs, 2.0f, spacing, maxs);
2527         }
2528         else
2529         {
2530                 VectorSet(mins, -1048576.0f, -1048576.0f, -1048576.0f);
2531                 VectorSet(maxs,  1048576.0f,  1048576.0f,  1048576.0f);
2532         }
2533         VectorSubtract(maxs, mins, size);
2534         // now we can calculate the resolution we want
2535         c[0] = (int)floor(size[0] / spacing[0] + 0.5f);
2536         c[1] = (int)floor(size[1] / spacing[1] + 0.5f);
2537         c[2] = (int)floor(size[2] / spacing[2] + 0.5f);
2538         // figure out the exact texture size (honoring power of 2 if required)
2539         c[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
2540         c[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
2541         c[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
2542         if (vid.support.arb_texture_non_power_of_two)
2543         {
2544                 resolution[0] = c[0];
2545                 resolution[1] = c[1];
2546                 resolution[2] = c[2];
2547         }
2548         else
2549         {
2550                 for (resolution[0] = 4;resolution[0] < c[0];resolution[0]*=2) ;
2551                 for (resolution[1] = 4;resolution[1] < c[1];resolution[1]*=2) ;
2552                 for (resolution[2] = 4;resolution[2] < c[2];resolution[2]*=2) ;
2553         }
2554         size[0] = spacing[0] * resolution[0];
2555         size[1] = spacing[1] * resolution[1];
2556         size[2] = spacing[2] * resolution[2];
2557
2558         // if dynamic we may or may not want to use the world bounds
2559         // if the dynamic size is smaller than the world bounds, use it instead
2560         if (!settings->staticmode && (r_shadow_bouncegrid_x.integer * r_shadow_bouncegrid_y.integer * r_shadow_bouncegrid_z.integer < resolution[0] * resolution[1] * resolution[2]))
2561         {
2562                 // we know the resolution we want
2563                 c[0] = r_shadow_bouncegrid_x.integer;
2564                 c[1] = r_shadow_bouncegrid_y.integer;
2565                 c[2] = r_shadow_bouncegrid_z.integer;
2566                 // now we can calculate the texture size (power of 2 if required)
2567                 c[0] = bound(4, c[0], (int)vid.maxtexturesize_3d);
2568                 c[1] = bound(4, c[1], (int)vid.maxtexturesize_3d);
2569                 c[2] = bound(4, c[2], (int)vid.maxtexturesize_3d);
2570                 if (vid.support.arb_texture_non_power_of_two)
2571                 {
2572                         resolution[0] = c[0];
2573                         resolution[1] = c[1];
2574                         resolution[2] = c[2];
2575                 }
2576                 else
2577                 {
2578                         for (resolution[0] = 4;resolution[0] < c[0];resolution[0]*=2) ;
2579                         for (resolution[1] = 4;resolution[1] < c[1];resolution[1]*=2) ;
2580                         for (resolution[2] = 4;resolution[2] < c[2];resolution[2]*=2) ;
2581                 }
2582                 size[0] = spacing[0] * resolution[0];
2583                 size[1] = spacing[1] * resolution[1];
2584                 size[2] = spacing[2] * resolution[2];
2585                 // center the rendering on the view
2586                 mins[0] = floor(r_refdef.view.origin[0] * ispacing[0] + 0.5f) * spacing[0] - 0.5f * size[0];
2587                 mins[1] = floor(r_refdef.view.origin[1] * ispacing[1] + 0.5f) * spacing[1] - 0.5f * size[1];
2588                 mins[2] = floor(r_refdef.view.origin[2] * ispacing[2] + 0.5f) * spacing[2] - 0.5f * size[2];
2589         }
2590
2591         // recalculate the maxs in case the resolution was not satisfactory
2592         VectorAdd(mins, size, maxs);
2593
2594         // check if this changed the texture size
2595         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);
2596         r_shadow_bouncegrid_state.directional = r_shadow_bouncegrid_state.settings.directionalshading;
2597         VectorCopy(mins, r_shadow_bouncegrid_state.mins);
2598         VectorCopy(maxs, r_shadow_bouncegrid_state.maxs);
2599         VectorCopy(size, r_shadow_bouncegrid_state.size);
2600         VectorCopy(spacing, r_shadow_bouncegrid_state.spacing);
2601         VectorCopy(ispacing, r_shadow_bouncegrid_state.ispacing);
2602         VectorCopy(resolution, r_shadow_bouncegrid_state.resolution);
2603
2604         // reallocate pixels for this update if needed...
2605         r_shadow_bouncegrid_state.pixelbands = settings->directionalshading ? 8 : 1;
2606         r_shadow_bouncegrid_state.pixelsperband = resolution[0]*resolution[1]*resolution[2];
2607         r_shadow_bouncegrid_state.bytesperband = r_shadow_bouncegrid_state.pixelsperband*4;
2608         numpixels = r_shadow_bouncegrid_state.pixelsperband*r_shadow_bouncegrid_state.pixelbands;
2609         if (r_shadow_bouncegrid_state.numpixels != numpixels || !r_shadow_bouncegrid_state.pixels || !r_shadow_bouncegrid_state.highpixels)
2610         {
2611                 if (r_shadow_bouncegrid_state.texture)
2612                 {
2613                         R_FreeTexture(r_shadow_bouncegrid_state.texture);
2614                         r_shadow_bouncegrid_state.texture = NULL;
2615                 }
2616                 r_shadow_bouncegrid_state.pixels = (unsigned char *)Mem_Realloc(r_main_mempool, r_shadow_bouncegrid_state.pixels, numpixels * sizeof(unsigned char[4]));
2617                 r_shadow_bouncegrid_state.highpixels = (float *)Mem_Realloc(r_main_mempool, r_shadow_bouncegrid_state.highpixels, numpixels * sizeof(float[4]));
2618                 r_shadow_bouncegrid_state.numpixels = numpixels;
2619         }
2620
2621         // update the bouncegrid matrix to put it in the world properly
2622         memset(m, 0, sizeof(m));
2623         m[0] = 1.0f / r_shadow_bouncegrid_state.size[0];
2624         m[3] = -r_shadow_bouncegrid_state.mins[0] * m[0];
2625         m[5] = 1.0f / r_shadow_bouncegrid_state.size[1];
2626         m[7] = -r_shadow_bouncegrid_state.mins[1] * m[5];
2627         m[10] = 1.0f / r_shadow_bouncegrid_state.size[2];
2628         m[11] = -r_shadow_bouncegrid_state.mins[2] * m[10];
2629         m[15] = 1.0f;
2630         Matrix4x4_FromArrayFloatD3D(&r_shadow_bouncegrid_state.matrix, m);
2631 }
2632
2633 #define MAXBOUNCEGRIDPARTICLESPERLIGHT 1048576
2634
2635 // enumerate world rtlights and sum the overall amount of light in the world,
2636 // from that we can calculate a scaling factor to fairly distribute photons
2637 // to all the lights
2638 //
2639 // this modifies rtlight->photoncolor and rtlight->photons
2640 static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *settings, unsigned int range, unsigned int range1, unsigned int range2, int flag, float *photonscaling)
2641 {
2642         float normalphotonscaling;
2643         float maxphotonscaling;
2644         float photoncount = 0.0f;
2645         float lightintensity;
2646         float radius;
2647         float s;
2648         float w;
2649         vec3_t cullmins;
2650         vec3_t cullmaxs;
2651         unsigned int lightindex;
2652         dlight_t *light;
2653         rtlight_t *rtlight;
2654         for (lightindex = 0;lightindex < range2;lightindex++)
2655         {
2656                 if (lightindex < range)
2657                 {
2658                         light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
2659                         if (!light)
2660                                 continue;
2661                         rtlight = &light->rtlight;
2662                         VectorClear(rtlight->photoncolor);
2663                         rtlight->photons = 0;
2664                         if (!(light->flags & flag))
2665                                 continue;
2666                         if (settings->staticmode)
2667                         {
2668                                 // when static, we skip styled lights because they tend to change...
2669                                 if (rtlight->style > 0 && r_shadow_bouncegrid.integer != 2)
2670                                         continue;
2671                         }
2672                 }
2673                 else
2674                 {
2675                         rtlight = r_refdef.scene.lights[lightindex - range];
2676                         VectorClear(rtlight->photoncolor);
2677                         rtlight->photons = 0;
2678                 }
2679                 // draw only visible lights (major speedup)
2680                 radius = rtlight->radius * settings->lightradiusscale;
2681                 cullmins[0] = rtlight->shadoworigin[0] - radius;
2682                 cullmins[1] = rtlight->shadoworigin[1] - radius;
2683                 cullmins[2] = rtlight->shadoworigin[2] - radius;
2684                 cullmaxs[0] = rtlight->shadoworigin[0] + radius;
2685                 cullmaxs[1] = rtlight->shadoworigin[1] + radius;
2686                 cullmaxs[2] = rtlight->shadoworigin[2] + radius;
2687                 w = r_shadow_lightintensityscale.value * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
2688                 if (!settings->staticmode)
2689                 {
2690                         if (R_CullBox(cullmins, cullmaxs))
2691                                 continue;
2692                         if (r_refdef.scene.worldmodel
2693                          && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs
2694                          && !r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, cullmins, cullmaxs))
2695                                 continue;
2696                         if (w * VectorLength2(rtlight->color) == 0.0f)
2697                                 continue;
2698                 }
2699                 // a light that does not emit any light before style is applied, can be
2700                 // skipped entirely (it may just be a corona)
2701                 if (rtlight->radius == 0.0f || VectorLength2(rtlight->color) == 0.0f)
2702                         continue;
2703                 w *= ((rtlight->style >= 0 && rtlight->style < MAX_LIGHTSTYLES) ? r_refdef.scene.rtlightstylevalue[rtlight->style] : 1);
2704                 VectorScale(rtlight->color, w, rtlight->photoncolor);
2705                 // skip lights that will emit no photons
2706                 if (!VectorLength2(rtlight->photoncolor))
2707                         continue;
2708                 // shoot particles from this light
2709                 // use a calculation for the number of particles that will not
2710                 // vary with lightstyle, otherwise we get randomized particle
2711                 // distribution, the seeded random is only consistent for a
2712                 // consistent number of particles on this light...
2713                 s = rtlight->radius;
2714                 lightintensity = VectorLength(rtlight->color) * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
2715                 if (lightindex >= range)
2716                         lightintensity *= settings->dlightparticlemultiplier;
2717                 rtlight->photons = bound(0.0f, lightintensity * s * s, MAXBOUNCEGRIDPARTICLESPERLIGHT);
2718                 photoncount += rtlight->photons;
2719                 // if the lightstyle happens to be off right now, we can skip actually
2720                 // firing the photons, but we did have to count them in the total.
2721                 //if (VectorLength2(rtlight->photoncolor) == 0.0f)
2722                 //      rtlight->photons = 0;
2723         }
2724         // the user provided an energyperphoton value which we try to use
2725         // if that results in too many photons to shoot this frame, then we cap it
2726         // which causes photons to appear/disappear from frame to frame, so we don't
2727         // like doing that in the typical case
2728         normalphotonscaling = 1.0f / max(0.0001f, r_shadow_bouncegrid_dynamic_energyperphoton.value);
2729         maxphotonscaling = (float)settings->maxphotons / max(1, photoncount);
2730         *photonscaling = min(normalphotonscaling, maxphotonscaling);
2731 }
2732
2733 static int R_Shadow_BounceGrid_SplatPathCompare(const void *pa, const void *pb)
2734 {
2735         r_shadow_bouncegrid_splatpath_t *a = (r_shadow_bouncegrid_splatpath_t *)pa;
2736         r_shadow_bouncegrid_splatpath_t *b = (r_shadow_bouncegrid_splatpath_t *)pb;
2737         // we only really care about sorting by Z
2738         if (a->point[2] < b->point[2])
2739                 return -1;
2740         if (a->point[2] > b->point[2])
2741                 return 1;
2742         return 0;
2743 }
2744
2745 static void R_Shadow_BounceGrid_ClearPixels(void)
2746 {
2747         // clear the highpixels array we'll be accumulating into
2748         memset(r_shadow_bouncegrid_state.highpixels, 0, r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
2749 }
2750
2751 static void R_Shadow_BounceGrid_PerformSplats(void)
2752 {
2753         r_shadow_bouncegrid_splatpath_t *splatpaths = r_shadow_bouncegrid_state.splatpaths;
2754         r_shadow_bouncegrid_splatpath_t *splatpath;
2755         float *highpixel;
2756         float *highpixels = r_shadow_bouncegrid_state.highpixels;
2757         int numsplatpaths = r_shadow_bouncegrid_state.numsplatpaths;
2758         int splatindex;
2759         vec3_t steppos;
2760         vec3_t stepdelta;
2761         vec3_t dir;
2762         float texlerp[2][3];
2763         float splatcolor[32];
2764         float pixelweight[8];
2765         float w;
2766         int resolution[3];
2767         int tex[3];
2768         int pixelindex[8];
2769         int corner;
2770         int pixelsperband = r_shadow_bouncegrid_state.pixelsperband;
2771         int pixelband;
2772         int pixelbands = r_shadow_bouncegrid_state.pixelbands;
2773         int numsteps;
2774         int step;
2775
2776         // hush warnings about uninitialized data - pixelbands doesn't change but...
2777         memset(splatcolor, 0, sizeof(splatcolor));
2778
2779         // we use this a lot, so get a local copy
2780         VectorCopy(r_shadow_bouncegrid_state.resolution, resolution);
2781
2782         // sort the splats before we execute them, to reduce cache misses
2783         if (r_shadow_bouncegrid_sortlightpaths.integer)
2784                 qsort(splatpaths, numsplatpaths, sizeof(*splatpaths), R_Shadow_BounceGrid_SplatPathCompare);
2785         
2786         splatpath = splatpaths;
2787         for (splatindex = 0;splatindex < numsplatpaths;splatindex++, splatpath++)
2788         {
2789                 
2790                 // calculate second order spherical harmonics values (average, slopeX, slopeY, slopeZ)
2791                 // accumulate average shotcolor
2792                 VectorCopy(splatpath->splatdir, dir);
2793                 splatcolor[ 0] = splatpath->splatcolor[0];
2794                 splatcolor[ 1] = splatpath->splatcolor[1];
2795                 splatcolor[ 2] = splatpath->splatcolor[2];
2796                 splatcolor[ 3] = 0.0f;
2797                 if (pixelbands > 1)
2798                 {
2799                         // store bentnormal in case the shader has a use for it,
2800                         // bentnormal is an intensity-weighted average of the directions,
2801                         // and will be normalized on conversion to texture pixels.
2802                         splatcolor[ 4] = dir[0] * splatpath->splatintensity;
2803                         splatcolor[ 5] = dir[1] * splatpath->splatintensity;
2804                         splatcolor[ 6] = dir[2] * splatpath->splatintensity;
2805                         splatcolor[ 7] = splatpath->splatintensity;
2806                         // for each color component (R, G, B) calculate the amount that a
2807                         // direction contributes
2808                         splatcolor[ 8] = splatcolor[0] * max(0.0f, dir[0]);
2809                         splatcolor[ 9] = splatcolor[0] * max(0.0f, dir[1]);
2810                         splatcolor[10] = splatcolor[0] * max(0.0f, dir[2]);
2811                         splatcolor[11] = 0.0f;
2812                         splatcolor[12] = splatcolor[1] * max(0.0f, dir[0]);
2813                         splatcolor[13] = splatcolor[1] * max(0.0f, dir[1]);
2814                         splatcolor[14] = splatcolor[1] * max(0.0f, dir[2]);
2815                         splatcolor[15] = 0.0f;
2816                         splatcolor[16] = splatcolor[2] * max(0.0f, dir[0]);
2817                         splatcolor[17] = splatcolor[2] * max(0.0f, dir[1]);
2818                         splatcolor[18] = splatcolor[2] * max(0.0f, dir[2]);
2819                         splatcolor[19] = 0.0f;
2820                         // and do the same for negative directions
2821                         splatcolor[20] = splatcolor[0] * max(0.0f, -dir[0]);
2822                         splatcolor[21] = splatcolor[0] * max(0.0f, -dir[1]);
2823                         splatcolor[22] = splatcolor[0] * max(0.0f, -dir[2]);
2824                         splatcolor[23] = 0.0f;
2825                         splatcolor[24] = splatcolor[1] * max(0.0f, -dir[0]);
2826                         splatcolor[25] = splatcolor[1] * max(0.0f, -dir[1]);
2827                         splatcolor[26] = splatcolor[1] * max(0.0f, -dir[2]);
2828                         splatcolor[27] = 0.0f;
2829                         splatcolor[28] = splatcolor[2] * max(0.0f, -dir[0]);
2830                         splatcolor[29] = splatcolor[2] * max(0.0f, -dir[1]);
2831                         splatcolor[30] = splatcolor[2] * max(0.0f, -dir[2]);
2832                         splatcolor[31] = 0.0f;
2833                 }
2834                 // calculate the number of steps we need to traverse this distance
2835                 VectorCopy(splatpath->point, steppos);
2836                 VectorCopy(splatpath->step, stepdelta);
2837                 numsteps = splatpath->remainingsplats;
2838                 for (step = 0;step < numsteps;step++)
2839                 {
2840                         r_refdef.stats[r_stat_bouncegrid_splats]++;
2841                         // figure out which texture pixels this is in
2842                         texlerp[1][0] = steppos[0] - 0.5f;
2843                         texlerp[1][1] = steppos[1] - 0.5f;
2844                         texlerp[1][2] = steppos[2] - 0.5f;
2845                         tex[0] = (int)floor(texlerp[1][0]);
2846                         tex[1] = (int)floor(texlerp[1][1]);
2847                         tex[2] = (int)floor(texlerp[1][2]);
2848                         if (tex[0] >= 1
2849                          && tex[1] >= 1
2850                          && tex[2] >= 1
2851                          && tex[0] < resolution[0] - 2
2852                          && tex[1] < resolution[1] - 2
2853                          && tex[2] < resolution[2] - 2)
2854                         {
2855                                 // it is within bounds...  do the real work now
2856                                 // calculate the lerp factors
2857                                 texlerp[1][0] -= tex[0];
2858                                 texlerp[1][1] -= tex[1];
2859                                 texlerp[1][2] -= tex[2];
2860                                 texlerp[0][0] = 1.0f - texlerp[1][0];
2861                                 texlerp[0][1] = 1.0f - texlerp[1][1];
2862                                 texlerp[0][2] = 1.0f - texlerp[1][2];
2863                                 // calculate individual pixel indexes and weights
2864                                 pixelindex[0] = (((tex[2]  )*resolution[1]+tex[1]  )*resolution[0]+tex[0]  );pixelweight[0] = (texlerp[0][0]*texlerp[0][1]*texlerp[0][2]);
2865                                 pixelindex[1] = (((tex[2]  )*resolution[1]+tex[1]  )*resolution[0]+tex[0]+1);pixelweight[1] = (texlerp[1][0]*texlerp[0][1]*texlerp[0][2]);
2866                                 pixelindex[2] = (((tex[2]  )*resolution[1]+tex[1]+1)*resolution[0]+tex[0]  );pixelweight[2] = (texlerp[0][0]*texlerp[1][1]*texlerp[0][2]);
2867                                 pixelindex[3] = (((tex[2]  )*resolution[1]+tex[1]+1)*resolution[0]+tex[0]+1);pixelweight[3] = (texlerp[1][0]*texlerp[1][1]*texlerp[0][2]);
2868                                 pixelindex[4] = (((tex[2]+1)*resolution[1]+tex[1]  )*resolution[0]+tex[0]  );pixelweight[4] = (texlerp[0][0]*texlerp[0][1]*texlerp[1][2]);
2869                                 pixelindex[5] = (((tex[2]+1)*resolution[1]+tex[1]  )*resolution[0]+tex[0]+1);pixelweight[5] = (texlerp[1][0]*texlerp[0][1]*texlerp[1][2]);
2870                                 pixelindex[6] = (((tex[2]+1)*resolution[1]+tex[1]+1)*resolution[0]+tex[0]  );pixelweight[6] = (texlerp[0][0]*texlerp[1][1]*texlerp[1][2]);
2871                                 pixelindex[7] = (((tex[2]+1)*resolution[1]+tex[1]+1)*resolution[0]+tex[0]+1);pixelweight[7] = (texlerp[1][0]*texlerp[1][1]*texlerp[1][2]);
2872                                 // update the 8 pixels...
2873                                 for (pixelband = 0;pixelband < pixelbands;pixelband++)
2874                                 {
2875                                         for (corner = 0;corner < 8;corner++)
2876                                         {
2877                                                 // calculate address for pixel
2878                                                 w = pixelweight[corner];
2879                                                 highpixel = highpixels + 4 * pixelindex[corner] + pixelband * pixelsperband * 4;
2880                                                 // add to the high precision pixel color
2881                                                 highpixel[0] += (splatcolor[pixelband*4+0]*w);
2882                                                 highpixel[1] += (splatcolor[pixelband*4+1]*w);
2883                                                 highpixel[2] += (splatcolor[pixelband*4+2]*w);
2884                                                 highpixel[3] += (splatcolor[pixelband*4+3]*w);
2885                                         }
2886                                 }
2887                         }
2888                         VectorAdd(steppos, stepdelta, steppos);
2889                 }
2890         }
2891 }
2892
2893 static void R_Shadow_BounceGrid_BlurPixelsInDirection(const float *inpixels, float *outpixels, int off)
2894 {
2895         const float *inpixel;
2896         float *outpixel;
2897         int pixelbands = r_shadow_bouncegrid_state.pixelbands;
2898         int pixelband;
2899         unsigned int index;
2900         unsigned int x, y, z;
2901         unsigned int resolution[3];
2902         VectorCopy(r_shadow_bouncegrid_state.resolution, resolution);
2903         for (pixelband = 0;pixelband < pixelbands;pixelband++)
2904         {
2905                 for (z = 1;z < resolution[2]-1;z++)
2906                 {
2907                         for (y = 1;y < resolution[1]-1;y++)
2908                         {
2909                                 x = 1;
2910                                 index = ((pixelband*resolution[2]+z)*resolution[1]+y)*resolution[0]+x;
2911                                 inpixel = inpixels + 4*index;
2912                                 outpixel = outpixels + 4*index;
2913                                 for (;x < resolution[0]-1;x++, inpixel += 4, outpixel += 4)
2914                                 {
2915                                         outpixel[0] = (inpixel[0] + inpixel[  off] + inpixel[0-off]) * (1.0f / 3.0);
2916                                         outpixel[1] = (inpixel[1] + inpixel[1+off] + inpixel[1-off]) * (1.0f / 3.0);
2917                                         outpixel[2] = (inpixel[2] + inpixel[2+off] + inpixel[2-off]) * (1.0f / 3.0);
2918                                         outpixel[3] = (inpixel[3] + inpixel[3+off] + inpixel[3-off]) * (1.0f / 3.0);
2919                                 }
2920                         }
2921                 }
2922         }
2923 }
2924
2925 static void R_Shadow_BounceGrid_BlurPixels(void)
2926 {
2927         float *highpixels = r_shadow_bouncegrid_state.highpixels;
2928         float *temppixels1 = (float *)R_FrameData_Alloc(r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
2929         float *temppixels2 = (float *)R_FrameData_Alloc(r_shadow_bouncegrid_state.numpixels * sizeof(float[4]));
2930         unsigned int resolution[3];
2931
2932         if (!r_shadow_bouncegrid_blur.integer)
2933                 return;
2934         
2935         VectorCopy(r_shadow_bouncegrid_state.resolution, resolution);
2936
2937         // blur on X
2938         R_Shadow_BounceGrid_BlurPixelsInDirection(highpixels, temppixels1, 4);
2939         // blur on Y
2940         R_Shadow_BounceGrid_BlurPixelsInDirection(temppixels1, temppixels2, resolution[0] * 4);
2941         // blur on Z
2942         R_Shadow_BounceGrid_BlurPixelsInDirection(temppixels2, highpixels, resolution[0] * resolution[1] * 4);
2943 }
2944
2945 static void R_Shadow_BounceGrid_ConvertPixelsAndUpload(void)
2946 {
2947         unsigned char *pixels = r_shadow_bouncegrid_state.pixels;
2948         unsigned char *pixel;
2949         float *highpixels = r_shadow_bouncegrid_state.highpixels;
2950         float *highpixel;
2951         float *bandpixel;
2952         unsigned int pixelsperband = r_shadow_bouncegrid_state.pixelsperband;
2953         unsigned int pixelbands = r_shadow_bouncegrid_state.pixelbands;
2954         unsigned int pixelband;
2955         unsigned int x, y, z;
2956         unsigned int index, bandindex;
2957         unsigned int resolution[3];
2958         int c[4];
2959         VectorCopy(r_shadow_bouncegrid_state.resolution, resolution);
2960         // start by clearing the pixels array - we won't be writing to all of it
2961         for (pixelband = 0;pixelband < pixelbands;pixelband++)
2962         {
2963                 // clear to neutral values before we bother converting
2964                 if (pixelband == 1)
2965                         memset(r_shadow_bouncegrid_state.pixels + pixelband * r_shadow_bouncegrid_state.bytesperband, 128, r_shadow_bouncegrid_state.bytesperband);
2966                 else
2967                         memset(r_shadow_bouncegrid_state.pixels + pixelband * r_shadow_bouncegrid_state.bytesperband, 0, r_shadow_bouncegrid_state.bytesperband);
2968         }
2969         // skip first and last columns, rows, and layers as these are always blank
2970         // skip higher pixelbands on pixels that have no color
2971         for (z = 1;z < resolution[2]-1;z++)
2972         {
2973                 for (y = 1;y < resolution[1]-1;y++)
2974                 {
2975                         x = 1;
2976                         pixelband = 0;
2977                         index = ((pixelband*resolution[2]+z)*resolution[1]+y)*resolution[0]+x;
2978                         highpixel = highpixels + 4*index;
2979                         for (;x < resolution[0]-1;x++, index++, highpixel += 4)
2980                         {
2981                                 // only convert pixels that were hit by photons
2982                                 if (VectorLength2(highpixel))
2983                                 {
2984                                         // process all of the pixelbands for this pixel
2985                                         for (pixelband = 0, bandindex = index;pixelband < pixelbands;pixelband++, bandindex += pixelsperband)
2986                                         {
2987                                                 pixel = pixels + 4*bandindex;
2988                                                 bandpixel = highpixels + 4*bandindex;
2989                                                 // normalize the bentnormal pixelband...
2990                                                 if (pixelband == 1)
2991                                                 {
2992                                                         VectorNormalize(bandpixel);
2993                                                         c[0] = (int)(bandpixel[0]*128.0f+128.0f);
2994                                                         c[1] = (int)(bandpixel[1]*128.0f+128.0f);
2995                                                         c[2] = (int)(bandpixel[2]*128.0f+128.0f);
2996                                                         c[3] = (int)(bandpixel[3]*128.0f+128.0f);
2997                                                 }
2998                                                 else
2999                                                 {
3000                                                         c[0] = (int)(bandpixel[0]*256.0f);
3001                                                         c[1] = (int)(bandpixel[1]*256.0f);
3002                                                         c[2] = (int)(bandpixel[2]*256.0f);
3003                                                         c[3] = (int)(bandpixel[3]*256.0f);
3004                                                 }
3005                                                 pixel[2] = (unsigned char)bound(0, c[0], 255);
3006                                                 pixel[1] = (unsigned char)bound(0, c[1], 255);
3007                                                 pixel[0] = (unsigned char)bound(0, c[2], 255);
3008                                                 pixel[3] = (unsigned char)bound(0, c[3], 255);
3009                                         }
3010                                 }
3011                         }
3012                 }
3013         }
3014
3015         if (!r_shadow_bouncegrid_state.createtexture)
3016                 R_UpdateTexture(r_shadow_bouncegrid_state.texture, pixels, 0, 0, 0, resolution[0], resolution[1], resolution[2]*pixelbands);
3017         else
3018         {
3019                 if (r_shadow_bouncegrid_state.texture)
3020                         R_FreeTexture(r_shadow_bouncegrid_state.texture);
3021                 r_shadow_bouncegrid_state.texture = R_LoadTexture3D(r_shadow_texturepool, "bouncegrid", resolution[0], resolution[1], resolution[2]*pixelbands, pixels, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCELINEAR, 0, NULL);
3022         }
3023         r_shadow_bouncegrid_state.lastupdatetime = realtime;
3024 }
3025
3026 static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t settings, unsigned int range, unsigned int range1, unsigned int range2, float photonscaling, int flag)
3027 {
3028         dlight_t *light;
3029         int bouncecount;
3030         int hitsupercontentsmask;
3031         int maxbounce;
3032         int shootparticles;
3033         int shotparticles;
3034         trace_t cliptrace;
3035         //trace_t cliptrace2;
3036         //trace_t cliptrace3;
3037         unsigned int lightindex;
3038         unsigned int seed = (unsigned int)(realtime * 1000.0f);
3039         vec3_t shotcolor;
3040         vec3_t baseshotcolor;
3041         vec3_t surfcolor;
3042         vec3_t clipend;
3043         vec3_t clipstart;
3044         vec3_t clipdiff;
3045         vec_t radius;
3046         vec_t s;
3047         rtlight_t *rtlight;
3048
3049         // we'll need somewhere to store these
3050         r_shadow_bouncegrid_state.numsplatpaths = 0;
3051         r_shadow_bouncegrid_state.splatpaths = (r_shadow_bouncegrid_splatpath_t *)R_FrameData_Alloc(sizeof(r_shadow_bouncegrid_splatpath_t) * r_shadow_bouncegrid_state.maxsplatpaths);
3052
3053         // figure out what we want to interact with
3054         if (settings.hitmodels)
3055                 hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;// | SUPERCONTENTS_LIQUIDSMASK;
3056         else
3057                 hitsupercontentsmask = SUPERCONTENTS_SOLID;// | SUPERCONTENTS_LIQUIDSMASK;
3058         maxbounce = settings.maxbounce;
3059
3060         for (lightindex = 0;lightindex < range2;lightindex++)
3061         {
3062                 if (lightindex < range)
3063                 {
3064                         light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
3065                         if (!light)
3066                                 continue;
3067                         rtlight = &light->rtlight;
3068                 }
3069                 else
3070                         rtlight = r_refdef.scene.lights[lightindex - range];
3071                 // note that this code used to keep track of residual photons and
3072                 // distribute them evenly to achieve exactly a desired photon count,
3073                 // but that caused unwanted flickering in dynamic mode
3074                 shootparticles = (int)floor(rtlight->photons * photonscaling);
3075                 // skip if we won't be shooting any photons
3076                 if (!shootparticles)
3077                         continue;
3078                 radius = rtlight->radius * settings.lightradiusscale;
3079                 s = settings.particleintensity / shootparticles;
3080                 VectorScale(rtlight->photoncolor, s, baseshotcolor);
3081                 r_refdef.stats[r_stat_bouncegrid_lights]++;
3082                 r_refdef.stats[r_stat_bouncegrid_particles] += shootparticles;
3083                 for (shotparticles = 0;shotparticles < shootparticles;shotparticles++)
3084                 {
3085                         if (settings.stablerandom > 0)
3086                                 seed = lightindex * 11937 + shotparticles;
3087                         VectorCopy(baseshotcolor, shotcolor);
3088                         VectorCopy(rtlight->shadoworigin, clipstart);
3089                         if (settings.stablerandom < 0)
3090                                 VectorRandom(clipend);
3091                         else
3092                                 VectorCheeseRandom(clipend);
3093                         VectorMA(clipstart, radius, clipend, clipend);
3094                         for (bouncecount = 0;;bouncecount++)
3095                         {
3096                                 r_refdef.stats[r_stat_bouncegrid_traces]++;
3097                                 //r_refdef.scene.worldmodel->TraceLineAgainstSurfaces(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace, clipstart, clipend, hitsupercontentsmask);
3098                                 //r_refdef.scene.worldmodel->TraceLine(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace2, clipstart, clipend, hitsupercontentsmask);
3099                                 if (settings.staticmode)
3100                                 {
3101                                         // static mode fires a LOT of rays but none of them are identical, so they are not cached
3102                                         cliptrace = CL_TraceLine(clipstart, clipend, settings.staticmode ? MOVE_WORLDONLY : (settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS), NULL, hitsupercontentsmask, collision_extendmovelength.value, true, false, NULL, true, true);
3103                                 }
3104                                 else
3105                                 {
3106                                         // dynamic mode fires many rays and most will match the cache from the previous frame
3107                                         cliptrace = CL_Cache_TraceLineSurfaces(clipstart, clipend, settings.staticmode ? MOVE_WORLDONLY : (settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS), hitsupercontentsmask);
3108                                 }
3109                                 if (bouncecount > 0 || settings.includedirectlighting)
3110                                 {
3111                                         vec3_t hitpos;
3112                                         VectorCopy(cliptrace.endpos, hitpos);
3113                                         R_shadow_BounceGrid_AddSplatPath(clipstart, hitpos, shotcolor);
3114                                 }
3115                                 if (cliptrace.fraction >= 1.0f)
3116                                         break;
3117                                 r_refdef.stats[r_stat_bouncegrid_hits]++;
3118                                 if (bouncecount >= maxbounce)
3119                                         break;
3120                                 // scale down shot color by bounce intensity and texture color (or 50% if no texture reported)
3121                                 // also clamp the resulting color to never add energy, even if the user requests extreme values
3122                                 if (cliptrace.hittexture && cliptrace.hittexture->currentskinframe)
3123                                         VectorCopy(cliptrace.hittexture->currentskinframe->avgcolor, surfcolor);
3124                                 else
3125                                         VectorSet(surfcolor, 0.5f, 0.5f, 0.5f);
3126                                 VectorScale(surfcolor, settings.particlebounceintensity, surfcolor);
3127                                 surfcolor[0] = min(surfcolor[0], 1.0f);
3128                                 surfcolor[1] = min(surfcolor[1], 1.0f);
3129                                 surfcolor[2] = min(surfcolor[2], 1.0f);
3130                                 VectorMultiply(shotcolor, surfcolor, shotcolor);
3131                                 if (VectorLength2(baseshotcolor) == 0.0f)
3132                                         break;
3133                                 r_refdef.stats[r_stat_bouncegrid_bounces]++;
3134                                 if (settings.bounceanglediffuse)
3135                                 {
3136                                         // random direction, primarily along plane normal
3137                                         s = VectorDistance(cliptrace.endpos, clipend);
3138                                         if (settings.stablerandom < 0)
3139                                                 VectorRandom(clipend);
3140                                         else
3141                                                 VectorCheeseRandom(clipend);
3142                                         VectorMA(cliptrace.plane.normal, 0.95f, clipend, clipend);
3143                                         VectorNormalize(clipend);
3144                                         VectorScale(clipend, s, clipend);
3145                                 }
3146                                 else
3147                                 {
3148                                         // reflect the remaining portion of the line across plane normal
3149                                         VectorSubtract(clipend, cliptrace.endpos, clipdiff);
3150                                         VectorReflect(clipdiff, 1.0, cliptrace.plane.normal, clipend);
3151                                 }
3152                                 // calculate the new line start and end
3153                                 VectorCopy(cliptrace.endpos, clipstart);
3154                                 VectorAdd(clipstart, clipend, clipend);
3155                         }
3156                 }
3157         }
3158 }
3159
3160 void R_Shadow_UpdateBounceGridTexture(void)
3161 {
3162         int flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
3163         r_shadow_bouncegrid_settings_t settings;
3164         qboolean enable = false;
3165         qboolean settingschanged;
3166         unsigned int range; // number of world lights
3167         unsigned int range1; // number of dynamic lights (or zero if disabled)
3168         unsigned int range2; // range+range1
3169         float photonscaling;
3170
3171         enable = R_Shadow_BounceGrid_CheckEnable(flag);
3172         
3173         R_Shadow_BounceGrid_GenerateSettings(&settings);
3174         
3175         // changing intensity does not require an update
3176         r_shadow_bouncegrid_state.intensity = r_shadow_bouncegrid_intensity.value;
3177
3178         settingschanged = memcmp(&r_shadow_bouncegrid_state.settings, &settings, sizeof(settings)) != 0;
3179
3180         // when settings change, we free everything as it is just simpler that way.
3181         if (settingschanged || !enable)
3182         {
3183                 // not enabled, make sure we free anything we don't need anymore.
3184                 if (r_shadow_bouncegrid_state.texture)
3185                 {
3186                         R_FreeTexture(r_shadow_bouncegrid_state.texture);
3187                         r_shadow_bouncegrid_state.texture = NULL;
3188                 }
3189                 if (r_shadow_bouncegrid_state.pixels)
3190                         Mem_Free(r_shadow_bouncegrid_state.pixels);
3191                 r_shadow_bouncegrid_state.pixels = NULL;
3192                 if (r_shadow_bouncegrid_state.highpixels)
3193                         Mem_Free(r_shadow_bouncegrid_state.highpixels);
3194                 r_shadow_bouncegrid_state.highpixels = NULL;
3195                 r_shadow_bouncegrid_state.numpixels = 0;
3196                 r_shadow_bouncegrid_state.directional = false;
3197
3198                 if (!enable)
3199                         return;
3200         }
3201
3202         // if all the settings seem identical to the previous update, return
3203         if (r_shadow_bouncegrid_state.texture && (settings.staticmode || realtime < r_shadow_bouncegrid_state.lastupdatetime + r_shadow_bouncegrid_dynamic_updateinterval.value) && !settingschanged)
3204                 return;
3205
3206         // store the new settings
3207         r_shadow_bouncegrid_state.settings = settings;
3208
3209         R_Shadow_BounceGrid_UpdateSpacing();
3210
3211         // get the range of light numbers we'll be looping over:
3212         // range = static lights
3213         // range1 = dynamic lights (optional)
3214         // range2 = range + range1
3215         range = (unsigned int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
3216         range1 = settings.staticmode ? 0 : r_refdef.scene.numlights;
3217         range2 = range + range1;
3218
3219         // calculate weighting factors for distributing photons among the lights
3220         R_Shadow_BounceGrid_AssignPhotons(&settings, range, range1, range2, flag, &photonscaling);
3221
3222         // trace the photons from lights and accumulate illumination
3223         R_Shadow_BounceGrid_TracePhotons(settings, range, range1, range2, photonscaling, flag);
3224
3225         // clear the texture
3226         R_Shadow_BounceGrid_ClearPixels();
3227         
3228         // accumulate the light splatting into texture
3229         R_Shadow_BounceGrid_PerformSplats();
3230
3231         // apply a mild blur filter to the texture
3232         R_Shadow_BounceGrid_BlurPixels();
3233
3234         // convert the pixels to lower precision and upload the texture
3235         R_Shadow_BounceGrid_ConvertPixelsAndUpload();
3236 }
3237
3238 void R_Shadow_RenderMode_VisibleShadowVolumes(void)
3239 {
3240         R_Shadow_RenderMode_Reset();
3241         GL_BlendFunc(GL_ONE, GL_ONE);
3242         GL_DepthRange(0, 1);
3243         GL_DepthTest(r_showshadowvolumes.integer < 2);
3244         GL_Color(0.0, 0.0125 * r_refdef.view.colorscale, 0.1 * r_refdef.view.colorscale, 1);
3245         GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR
3246         GL_CullFace(GL_NONE);
3247         r_shadow_rendermode = R_SHADOW_RENDERMODE_VISIBLEVOLUMES;
3248 }
3249
3250 void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transparent)
3251 {
3252         R_Shadow_RenderMode_Reset();
3253         GL_BlendFunc(GL_ONE, GL_ONE);
3254         GL_DepthRange(0, 1);
3255         GL_DepthTest(r_showlighting.integer < 2);
3256         GL_Color(0.1 * r_refdef.view.colorscale, 0.0125 * r_refdef.view.colorscale, 0, 1);
3257         if (!transparent)
3258                 GL_DepthFunc(GL_EQUAL);
3259         R_SetStencil(stenciltest, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255);
3260         r_shadow_rendermode = R_SHADOW_RENDERMODE_VISIBLELIGHTING;
3261 }
3262
3263 void R_Shadow_RenderMode_End(void)
3264 {
3265         R_Shadow_RenderMode_Reset();
3266         R_Shadow_RenderMode_ActiveLight(NULL);
3267         GL_DepthMask(true);
3268         GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
3269         r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE;
3270 }
3271
3272 int bboxedges[12][2] =
3273 {
3274         // top
3275         {0, 1}, // +X
3276         {0, 2}, // +Y
3277         {1, 3}, // Y, +X
3278         {2, 3}, // X, +Y
3279         // bottom
3280         {4, 5}, // +X
3281         {4, 6}, // +Y
3282         {5, 7}, // Y, +X
3283         {6, 7}, // X, +Y
3284         // verticals
3285         {0, 4}, // +Z
3286         {1, 5}, // X, +Z
3287         {2, 6}, // Y, +Z
3288         {3, 7}, // XY, +Z
3289 };
3290
3291 qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
3292 {
3293         if (!r_shadow_scissor.integer || r_shadow_usingdeferredprepass || r_trippy.integer)
3294         {
3295                 r_shadow_lightscissor[0] = r_refdef.view.viewport.x;
3296                 r_shadow_lightscissor[1] = r_refdef.view.viewport.y;
3297                 r_shadow_lightscissor[2] = r_refdef.view.viewport.width;
3298                 r_shadow_lightscissor[3] = r_refdef.view.viewport.height;
3299                 return false;
3300         }
3301         if(R_ScissorForBBox(mins, maxs, r_shadow_lightscissor))
3302                 return true; // invisible
3303         if(r_shadow_lightscissor[0] != r_refdef.view.viewport.x
3304         || r_shadow_lightscissor[1] != r_refdef.view.viewport.y
3305         || r_shadow_lightscissor[2] != r_refdef.view.viewport.width
3306         || r_shadow_lightscissor[3] != r_refdef.view.viewport.height)
3307                 r_refdef.stats[r_stat_lights_scissored]++;
3308         return false;
3309 }
3310
3311 static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int numverts, const float *diffusecolor, const float *ambientcolor)
3312 {
3313         int i;
3314         const float *vertex3f;
3315         const float *normal3f;
3316         float *color4f;
3317         float dist, dot, distintensity, shadeintensity, v[3], n[3];
3318         switch (r_shadow_rendermode)
3319         {
3320         case R_SHADOW_RENDERMODE_LIGHT_VERTEX3DATTEN:
3321         case R_SHADOW_RENDERMODE_LIGHT_VERTEX2D1DATTEN:
3322                 if (VectorLength2(diffusecolor) > 0)
3323                 {
3324                         for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, normal3f = rsurface.batchnormal3f + 3*firstvertex, color4f = rsurface.passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, normal3f += 3, color4f += 4)
3325                         {
3326                                 Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
3327                                 Matrix4x4_Transform3x3(&rsurface.entitytolight, normal3f, n);
3328                                 if ((dot = DotProduct(n, v)) < 0)
3329                                 {
3330                                         shadeintensity = -dot / sqrt(VectorLength2(v) * VectorLength2(n));
3331                                         VectorMA(ambientcolor, shadeintensity, diffusecolor, color4f);
3332                                 }
3333                                 else
3334                                         VectorCopy(ambientcolor, color4f);
3335                                 if (r_refdef.fogenabled)
3336                                 {
3337                                         float f;
3338                                         f = RSurf_FogVertex(vertex3f);
3339                                         VectorScale(color4f, f, color4f);
3340                                 }
3341                                 color4f[3] = 1;
3342                         }
3343                 }
3344                 else
3345                 {
3346                         for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, color4f = rsurface.passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, color4f += 4)
3347                         {
3348                                 VectorCopy(ambientcolor, color4f);
3349                                 if (r_refdef.fogenabled)
3350                                 {
3351                                         float f;
3352                                         Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
3353                                         f = RSurf_FogVertex(vertex3f);
3354                                         VectorScale(color4f + 4*i, f, color4f);
3355                                 }
3356                                 color4f[3] = 1;
3357                         }
3358                 }
3359                 break;
3360         case R_SHADOW_RENDERMODE_LIGHT_VERTEX2DATTEN:
3361                 if (VectorLength2(diffusecolor) > 0)
3362                 {
3363                         for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, normal3f = rsurface.batchnormal3f + 3*firstvertex, color4f = rsurface.passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, normal3f += 3, color4f += 4)
3364                         {
3365                                 Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
3366                                 if ((dist = fabs(v[2])) < 1 && (distintensity = r_shadow_attentable[(int)(dist * ATTENTABLESIZE)]))
3367                                 {
3368                                         Matrix4x4_Transform3x3(&rsurface.entitytolight, normal3f, n);
3369                                         if ((dot = DotProduct(n, v)) < 0)
3370                                         {
3371                                                 shadeintensity = -dot / sqrt(VectorLength2(v) * VectorLength2(n));
3372                                                 color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]) * distintensity;
3373                                                 color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]) * distintensity;
3374                                                 color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]) * distintensity;
3375                                         }
3376                                         else
3377                                         {
3378                                                 color4f[0] = ambientcolor[0] * distintensity;
3379                                                 color4f[1] = ambientcolor[1] * distintensity;
3380                                                 color4f[2] = ambientcolor[2] * distintensity;
3381                                         }
3382                                         if (r_refdef.fogenabled)
3383                                         {
3384                                                 float f;
3385                                                 f = RSurf_FogVertex(vertex3f);
3386                                                 VectorScale(color4f, f, color4f);
3387                                         }
3388                                 }
3389                                 else
3390                                         VectorClear(color4f);
3391                                 color4f[3] = 1;
3392                         }
3393                 }
3394                 else
3395                 {
3396                         for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, color4f = rsurface.passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, color4f += 4)
3397                         {
3398                                 Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
3399                                 if ((dist = fabs(v[2])) < 1 && (distintensity = r_shadow_attentable[(int)(dist * ATTENTABLESIZE)]))
3400                                 {
3401                                         color4f[0] = ambientcolor[0] * distintensity;
3402                                         color4f[1] = ambientcolor[1] * distintensity;
3403                                         color4f[2] = ambientcolor[2] * distintensity;
3404                                         if (r_refdef.fogenabled)
3405                                         {
3406                                                 float f;
3407                                                 f = RSurf_FogVertex(vertex3f);
3408                                                 VectorScale(color4f, f, color4f);
3409                                         }
3410                                 }
3411                                 else
3412                                         VectorClear(color4f);
3413                                 color4f[3] = 1;
3414                         }
3415                 }
3416                 break;
3417         case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
3418                 if (VectorLength2(diffusecolor) > 0)
3419                 {
3420                         for (i = 0, vertex3f = rsurface.batchvertex3f + 3*firstvertex, normal3f = rsurface.batchnormal3f + 3*firstvertex, color4f = rsurface.passcolor4f + 4 * firstvertex;i < numverts;i++, vertex3f += 3, normal3f += 3, color4f += 4)
3421                         {
3422                                 Matrix4x4_Transform(&rsurface.entitytolight, vertex3f, v);
3423                                 if ((dist = VectorLength(v)) < 1 && (distintensity = r_shadow_attentable[(int)(dist * ATTENTABLESIZE)]))
3424                                 {
3425                                         distintensity = (1 - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist);
3426                                         Matrix4x4_Transform3x3(&rsurface.entitytolight, normal3f, n);
3427                                         if ((dot = DotProduct(n, v)) < 0)
3428                                         {
3429                                                 shadeintensity = -dot / sqrt(VectorLength2(v) * VectorLength2(n));
3430                                                 color4f[0] = (ambientcolor[0] + shadeintensity * diffusecolor[0]) * distintensity;
3431                                                 color4f[1] = (ambientcolor[1] + shadeintensity * diffusecolor[1]) * distintensity;
3432                                                 color4f[2] = (ambientcolor[2] + shadeintensity * diffusecolor[2]) * distintensity;
3433                                         }
3434                                         else
3435                                         {
3436                                                 color4f[0] = ambientcolor[0] * distintensity;
3437                                                 color4f[1] = ambientcolor[1] * distintensity;
3438                                                 color4f[2] = ambientcolor[2] * distintensity;
3439                                         }
3440                                         if (r_refdef.fogenabled)
3441                                         {
3442                                                 float f;
3443                                                 f = RSurf_FogVertex(vertex3f);
3444                                                 VectorScale(color4f, f, color4f);
3445                                         }
3446                                 }
3447                                 else
3448                                         VectorClear(color4f);
3449                                 color4f[3] = 1;
3450                         }
3451                 }
3452                 else
3453                 {