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