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