Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 Id Software, Inc.
3
 
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
 
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 
13
See the GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
19
*/
20
// r_light.c
21
 
22
#include "quakedef.h"
23
 
24
int	r_dlightframecount;
25
 
26
 
27
/*
28
==================
29
R_AnimateLight
30
==================
31
*/
32
void R_AnimateLight (void)
33
{
34
	int			i,j,k;
35
 
36
//
37
// light animations
38
// 'm' is normal light, 'a' is no light, 'z' is double bright
39
	i = (int)(cl.time*10);
40
	for (j=0 ; j
41
	{
42
		if (!cl_lightstyle[j].length)
43
		{
44
			d_lightstylevalue[j] = 256;
45
			continue;
46
		}
47
		k = i % cl_lightstyle[j].length;
48
		k = cl_lightstyle[j].map[k] - 'a';
49
		k = k*22;
50
		d_lightstylevalue[j] = k;
51
	}
52
}
53
 
54
/*
55
=============================================================================
56
 
57
DYNAMIC LIGHTS BLEND RENDERING
58
 
59
=============================================================================
60
*/
61
 
62
void AddLightBlend (float r, float g, float b, float a2)
63
{
64
	float	a;
65
 
66
	v_blend[3] = a = v_blend[3] + a2*(1-v_blend[3]);
67
 
68
	a2 = a2/a;
69
 
70
	v_blend[0] = v_blend[1]*(1-a2) + r*a2;
71
	v_blend[1] = v_blend[1]*(1-a2) + g*a2;
72
	v_blend[2] = v_blend[2]*(1-a2) + b*a2;
73
}
74
 
75
void R_RenderDlight (dlight_t *light)
76
{
77
	int		i, j;
78
	float	a;
79
	vec3_t	v;
80
	float	rad;
81
 
82
	rad = light->radius * 0.35;
83
 
84
	VectorSubtract (light->origin, r_origin, v);
85
	if (Length (v) < rad)
86
	{	// view is inside the dlight
87
		AddLightBlend (1, 0.5, 0, light->radius * 0.0003);
88
		return;
89
	}
90
 
91
	glBegin (GL_TRIANGLE_FAN);
92
	glColor3f (0.2,0.1,0.0);
93
	for (i=0 ; i<3 ; i++)
94
		v[i] = light->origin[i] - vpn[i]*rad;
95
	glVertex3fv (v);
96
	glColor3f (0,0,0);
97
	for (i=16 ; i>=0 ; i--)
98
	{
99
		a = i/16.0 * M_PI*2;
100
		for (j=0 ; j<3 ; j++)
101
			v[j] = light->origin[j] + vright[j]*cos(a)*rad
102
				+ vup[j]*sin(a)*rad;
103
		glVertex3fv (v);
104
	}
105
	glEnd ();
106
}
107
 
108
/*
109
=============
110
R_RenderDlights
111
=============
112
*/
113
void R_RenderDlights (void)
114
{
115
	int		i;
116
	dlight_t	*l;
117
 
118
	if (!gl_flashblend.value)
119
		return;
120
 
121
	r_dlightframecount = r_framecount + 1;	// because the count hasn't
122
											//  advanced yet for this frame
123
	glDepthMask (0);
124
	glDisable (GL_TEXTURE_2D);
125
	glShadeModel (GL_SMOOTH);
126
	glEnable (GL_BLEND);
127
	glBlendFunc (GL_ONE, GL_ONE);
128
 
129
	l = cl_dlights;
130
	for (i=0 ; i
131
	{
132
		if (l->die < cl.time || !l->radius)
133
			continue;
134
		R_RenderDlight (l);
135
	}
136
 
137
	glColor3f (1,1,1);
138
	glDisable (GL_BLEND);
139
	glEnable (GL_TEXTURE_2D);
140
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
141
	glDepthMask (1);
142
}
143
 
144
 
145
/*
146
=============================================================================
147
 
148
DYNAMIC LIGHTS
149
 
150
=============================================================================
151
*/
152
 
153
/*
154
=============
155
R_MarkLights
156
=============
157
*/
158
void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
159
{
160
	mplane_t	*splitplane;
161
	float		dist;
162
	msurface_t	*surf;
163
	int			i;
164
 
165
	if (node->contents < 0)
166
		return;
167
 
168
	splitplane = node->plane;
169
	dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
170
 
171
	if (dist > light->radius)
172
	{
173
		R_MarkLights (light, bit, node->children[0]);
174
		return;
175
	}
176
	if (dist < -light->radius)
177
	{
178
		R_MarkLights (light, bit, node->children[1]);
179
		return;
180
	}
181
 
182
// mark the polygons
183
	surf = cl.worldmodel->surfaces + node->firstsurface;
184
	for (i=0 ; inumsurfaces ; i++, surf++)
185
	{
186
		if (surf->dlightframe != r_dlightframecount)
187
		{
188
			surf->dlightbits = 0;
189
			surf->dlightframe = r_dlightframecount;
190
		}
191
		surf->dlightbits |= bit;
192
	}
193
 
194
	R_MarkLights (light, bit, node->children[0]);
195
	R_MarkLights (light, bit, node->children[1]);
196
}
197
 
198
 
199
/*
200
=============
201
R_PushDlights
202
=============
203
*/
204
void R_PushDlights (void)
205
{
206
	int		i;
207
	dlight_t	*l;
208
 
209
	if (gl_flashblend.value)
210
		return;
211
 
212
	r_dlightframecount = r_framecount + 1;	// because the count hasn't
213
											//  advanced yet for this frame
214
	l = cl_dlights;
215
 
216
	for (i=0 ; i
217
	{
218
		if (l->die < cl.time || !l->radius)
219
			continue;
220
		R_MarkLights ( l, 1<nodes );
221
	}
222
}
223
 
224
 
225
/*
226
=============================================================================
227
 
228
LIGHT SAMPLING
229
 
230
=============================================================================
231
*/
232
 
233
mplane_t		*lightplane;
234
vec3_t			lightspot;
235
 
236
int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
237
{
238
	int			r;
239
	float		front, back, frac;
240
	int			side;
241
	mplane_t	*plane;
242
	vec3_t		mid;
243
	msurface_t	*surf;
244
	int			s, t, ds, dt;
245
	int			i;
246
	mtexinfo_t	*tex;
247
	byte		*lightmap;
248
	unsigned	scale;
249
	int			maps;
250
 
251
	if (node->contents < 0)
252
		return -1;		// didn't hit anything
253
 
254
// calculate mid point
255
 
256
// FIXME: optimize for axial
257
	plane = node->plane;
258
	front = DotProduct (start, plane->normal) - plane->dist;
259
	back = DotProduct (end, plane->normal) - plane->dist;
260
	side = front < 0;
261
 
262
	if ( (back < 0) == side)
263
		return RecursiveLightPoint (node->children[side], start, end);
264
 
265
	frac = front / (front-back);
266
	mid[0] = start[0] + (end[0] - start[0])*frac;
267
	mid[1] = start[1] + (end[1] - start[1])*frac;
268
	mid[2] = start[2] + (end[2] - start[2])*frac;
269
 
270
// go down front side
271
	r = RecursiveLightPoint (node->children[side], start, mid);
272
	if (r >= 0)
273
		return r;		// hit something
274
 
275
	if ( (back < 0) == side )
276
		return -1;		// didn't hit anuthing
277
 
278
// check for impact on this node
279
	VectorCopy (mid, lightspot);
280
	lightplane = plane;
281
 
282
	surf = cl.worldmodel->surfaces + node->firstsurface;
283
	for (i=0 ; inumsurfaces ; i++, surf++)
284
	{
285
		if (surf->flags & SURF_DRAWTILED)
286
			continue;	// no lightmaps
287
 
288
		tex = surf->texinfo;
289
 
290
		s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
291
		t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];;
292
 
293
		if (s < surf->texturemins[0] ||
294
		t < surf->texturemins[1])
295
			continue;
296
 
297
		ds = s - surf->texturemins[0];
298
		dt = t - surf->texturemins[1];
299
 
300
		if ( ds > surf->extents[0] || dt > surf->extents[1] )
301
			continue;
302
 
303
		if (!surf->samples)
304
			return 0;
305
 
306
		ds >>= 4;
307
		dt >>= 4;
308
 
309
		lightmap = surf->samples;
310
		r = 0;
311
		if (lightmap)
312
		{
313
 
314
			lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
315
 
316
			for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
317
					maps++)
318
			{
319
				scale = d_lightstylevalue[surf->styles[maps]];
320
				r += *lightmap * scale;
321
				lightmap += ((surf->extents[0]>>4)+1) *
322
						((surf->extents[1]>>4)+1);
323
			}
324
 
325
			r >>= 8;
326
		}
327
 
328
		return r;
329
	}
330
 
331
// go down back side
332
	return RecursiveLightPoint (node->children[!side], mid, end);
333
}
334
 
335
int R_LightPoint (vec3_t p)
336
{
337
	vec3_t		end;
338
	int			r;
339
 
340
	if (!cl.worldmodel->lightdata)
341
		return 255;
342
 
343
	end[0] = p[0];
344
	end[1] = p[1];
345
	end[2] = p[2] - 2048;
346
 
347
	r = RecursiveLightPoint (cl.worldmodel->nodes, p, end);
348
 
349
	if (r == -1)
350
		r = 0;
351
 
352
	return r;
353
}
354