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 ; i |
||
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 ; i |
||
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 | }>>>>>>>>>>>3>3>> |
||
354 |