19fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
29fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamCopyright (C) 1996-1997 Id Software, Inc.
39fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
49fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is free software; you can redistribute it and/or
59fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammodify it under the terms of the GNU General Public License
69fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamas published by the Free Software Foundation; either version 2
79fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamof the License, or (at your option) any later version.
89fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
99fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is distributed in the hope that it will be useful,
109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreambut WITHOUT ANY WARRANTY; without even the implied warranty of
111b0eae1b322d3164b83c3f6346999da8c4916fa6Jack PalevichMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamSee the GNU General Public License for more details.
149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamYou should have received a copy of the GNU General Public License
169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamalong with this program; if not, write to the Free Software
179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
20cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// r_light.c
21cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "quakedef.h"
23cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
24cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint	r_dlightframecount;
25cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
26cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
27cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
28cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==================
29cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichR_AnimateLight
30cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==================
31cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
32cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid R_AnimateLight (void)
33cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
34cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			i,j,k;
351b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
36cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
37cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// light animations
38cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// 'm' is normal light, 'a' is no light, 'z' is double bright
39cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	i = (int)(cl.time*10);
40cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (j=0 ; j<MAX_LIGHTSTYLES ; j++)
41cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
42cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (!cl_lightstyle[j].length)
43cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
44cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			d_lightstylevalue[j] = 256;
45cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
46cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
47cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		k = i % cl_lightstyle[j].length;
48cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		k = cl_lightstyle[j].map[k] - 'a';
49cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		k = k*22;
50cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		d_lightstylevalue[j] = k;
511b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich	}
52cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
53cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream=============================================================================
569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamDYNAMIC LIGHTS BLEND RENDERING
589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream=============================================================================
609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid AddLightBlend (float r, float g, float b, float a2)
639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float	a;
659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	v_blend[3] = a = v_blend[3] + a2*(1-v_blend[3]);
679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	a2 = a2/a;
699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	v_blend[0] = v_blend[1]*(1-a2) + r*a2;
719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	v_blend[1] = v_blend[1]*(1-a2) + g*a2;
729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	v_blend[2] = v_blend[2]*(1-a2) + b*a2;
739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderDlight (dlight_t *light)
769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int		i, j;
789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float	a;
799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	vec3_t	v;
809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float	rad;
819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	rad = light->radius * 0.35;
839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	VectorSubtract (light->origin, r_origin, v);
859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (Length (v) < rad)
869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{	// view is inside the dlight
879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		AddLightBlend (1, 0.5, 0, light->radius * 0.0003);
889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
91cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#ifdef USE_OPENGLES
92cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    glEnableClientState(GL_COLOR_ARRAY);
93cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
94cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	glVertexPointer(3, GL_FLOAT, 0, gVertexBuffer);
951b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich	glColorPointer(4, GL_FLOAT, 0, gColorBuffer);
96cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
97cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
98cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	    float* pPos = gVertexBuffer;
99cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		float* pColor = gColorBuffer;
1001b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich		*pColor++ = 0.2f;
1011b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich		*pColor++ = 0.1f;
1021b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich		*pColor++ = 0.0f;
1031b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich		*pColor++ = 1.0f;
104cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		for (i=0 ; i<3 ; i++)
105cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			*pPos++ = light->origin[i] - vpn[i]*rad;
106cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		for (i=16 ; i>=0 ; i--)
107cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
1081b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich			*pColor++ = 0.0f;
1091b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich			*pColor++ = 0.0f;
1101b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich			*pColor++ = 0.0f;
1111b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich			*pColor++ = 0.0f;
112cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			a = i/16.0 * M_PI*2;
113cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			for (j=0 ; j<3 ; j++)
114cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				*pPos++ = light->origin[j] + vright[j]*cos(a)*rad
115cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					+ vup[j]*sin(a)*rad;
116cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
117cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
118cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	glDrawArrays(GL_TRIANGLE_FAN, 0, 18);
119cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    glDisableClientState(GL_COLOR_ARRAY);
120cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
121cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	glColor3f(0,0,0); // Ensure the color ends up being zero just like the non-OpenGLES code
1221b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
123cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#else
1249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glBegin (GL_TRIANGLE_FAN);
1259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glColor3f (0.2,0.1,0.0);
1269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=0 ; i<3 ; i++)
1279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v[i] = light->origin[i] - vpn[i]*rad;
1289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glVertex3fv (v);
1299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glColor3f (0,0,0);
1309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=16 ; i>=0 ; i--)
1319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
1329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		a = i/16.0 * M_PI*2;
1339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		for (j=0 ; j<3 ; j++)
1349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			v[j] = light->origin[j] + vright[j]*cos(a)*rad
1359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				+ vup[j]*sin(a)*rad;
1369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		glVertex3fv (v);
1379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
1389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glEnd ();
139cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#endif
1409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
1419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
1439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream=============
1449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderDlights
1459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream=============
1469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
1479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderDlights (void)
1489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int		i;
1509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dlight_t	*l;
1519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (!gl_flashblend.value)
1539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
1549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_dlightframecount = r_framecount + 1;	// because the count hasn't
1569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream											//  advanced yet for this frame
1579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glDepthMask (0);
1589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glDisable (GL_TEXTURE_2D);
1599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glShadeModel (GL_SMOOTH);
1609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glEnable (GL_BLEND);
1619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glBlendFunc (GL_ONE, GL_ONE);
1629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	l = cl_dlights;
1649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
1659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
1669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (l->die < cl.time || !l->radius)
1679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			continue;
1689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		R_RenderDlight (l);
1699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
1709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glColor3f (1,1,1);
1729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glDisable (GL_BLEND);
1739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glEnable (GL_TEXTURE_2D);
1749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	glDepthMask (1);
1769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
1779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
178cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
179cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
180cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============================================================================
181cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
182cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichDYNAMIC LIGHTS
183cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
184cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============================================================================
185cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
186cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
187cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
188cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============
189cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichR_MarkLights
190cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============
191cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
192cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid R_MarkLights (dlight_t *light, int bit, mnode_t *node)
193cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
194cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	mplane_t	*splitplane;
195cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float		dist;
196cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	msurface_t	*surf;
197cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			i;
1981b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
199cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (node->contents < 0)
200cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
201cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
202cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	splitplane = node->plane;
203cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
2041b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
205cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (dist > light->radius)
206cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
207cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		R_MarkLights (light, bit, node->children[0]);
208cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
209cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
210cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (dist < -light->radius)
211cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
212cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		R_MarkLights (light, bit, node->children[1]);
213cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
214cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
2151b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
216cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// mark the polygons
217cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	surf = cl.worldmodel->surfaces + node->firstsurface;
218cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<node->numsurfaces ; i++, surf++)
219cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
220cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (surf->dlightframe != r_dlightframecount)
221cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
222cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			surf->dlightbits = 0;
223cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			surf->dlightframe = r_dlightframecount;
224cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
225cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		surf->dlightbits |= bit;
226cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
227cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
228cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	R_MarkLights (light, bit, node->children[0]);
229cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	R_MarkLights (light, bit, node->children[1]);
230cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
231cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
232cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
233cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
234cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============
235cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichR_PushDlights
236cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============
237cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
238cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid R_PushDlights (void)
239cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
240cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		i;
241cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	dlight_t	*l;
2429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (gl_flashblend.value)
2449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
245cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
246cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	r_dlightframecount = r_framecount + 1;	// because the count hasn't
247cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich											//  advanced yet for this frame
248cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	l = cl_dlights;
249cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
250cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
251cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
252cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (l->die < cl.time || !l->radius)
253cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
254cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		R_MarkLights ( l, 1<<i, cl.worldmodel->nodes );
255cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
256cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
257cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
258cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
259cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
260cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============================================================================
261cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
262cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichLIGHT SAMPLING
263cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
264cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich=============================================================================
265cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
2669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammplane_t		*lightplane;
2689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvec3_t			lightspot;
269cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
270cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
271cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
272cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			r;
273cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float		front, back, frac;
274cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			side;
275cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	mplane_t	*plane;
276cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t		mid;
277cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	msurface_t	*surf;
278cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			s, t, ds, dt;
279cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			i;
280cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	mtexinfo_t	*tex;
281cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	byte		*lightmap;
282cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	unsigned	scale;
283cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			maps;
284cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
285cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (node->contents < 0)
286cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return -1;		// didn't hit anything
2871b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
288cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// calculate mid point
289cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
290cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// FIXME: optimize for axial
291cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	plane = node->plane;
292cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	front = DotProduct (start, plane->normal) - plane->dist;
293cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	back = DotProduct (end, plane->normal) - plane->dist;
294cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	side = front < 0;
2951b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
296cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if ( (back < 0) == side)
297cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return RecursiveLightPoint (node->children[side], start, end);
2981b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
299cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	frac = front / (front-back);
300cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	mid[0] = start[0] + (end[0] - start[0])*frac;
301cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	mid[1] = start[1] + (end[1] - start[1])*frac;
302cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	mid[2] = start[2] + (end[2] - start[2])*frac;
3031b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
3041b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich// go down front side
305cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	r = RecursiveLightPoint (node->children[side], start, mid);
306cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (r >= 0)
307cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return r;		// hit something
3081b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
309cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if ( (back < 0) == side )
310cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return -1;		// didn't hit anuthing
3111b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
312cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// check for impact on this node
3139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	VectorCopy (mid, lightspot);
3149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	lightplane = plane;
315cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
316cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	surf = cl.worldmodel->surfaces + node->firstsurface;
317cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<node->numsurfaces ; i++, surf++)
318cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
319cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (surf->flags & SURF_DRAWTILED)
320cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;	// no lightmaps
321cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
322cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		tex = surf->texinfo;
3231b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
324cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		s = (int) (DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]);
325cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		t = (int) (DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3]);
326cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
327cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (s < surf->texturemins[0] ||
328cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		t < surf->texturemins[1])
329cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
3301b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
331cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		ds = s - surf->texturemins[0];
332cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		dt = t - surf->texturemins[1];
3331b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
334cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if ( ds > surf->extents[0] || dt > surf->extents[1] )
335cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
336cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
337cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (!surf->samples)
338cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			return 0;
339cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
340cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		ds >>= 4;
341cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		dt >>= 4;
342cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
343cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		lightmap = surf->samples;
344cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		r = 0;
345cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (lightmap)
346cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
347cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
348cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
349cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
350cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
351cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					maps++)
352cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			{
353cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				scale = d_lightstylevalue[surf->styles[maps]];
354cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				r += *lightmap * scale;
355cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				lightmap += ((surf->extents[0]>>4)+1) *
356cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich						((surf->extents[1]>>4)+1);
357cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			}
3581b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
359cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			r >>= 8;
360cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
3611b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
362cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return r;
363cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
364cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
365cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// go down back side
366cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	return RecursiveLightPoint (node->children[!side], mid, end);
367cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
368cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
369cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint R_LightPoint (vec3_t p)
370cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
371cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t		end;
372cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			r;
3731b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
374cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (!cl.worldmodel->lightdata)
375cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return 255;
3761b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
377cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	end[0] = p[0];
378cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	end[1] = p[1];
379cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	end[2] = p[2] - 2048;
3801b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
381cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	r = RecursiveLightPoint (cl.worldmodel->nodes, p, end);
3821b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich
383cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (r == -1)
384cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		r = 0;
385cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
386cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	return r;
387cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
388