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