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