Gigantic commit - dlight system rewritten
[divverent/darkplaces.git] / r_light.c
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 cvar_t r_lightmodels = {"r_lightmodels", "1"};
25
26 void rlight_init()
27 {
28         Cvar_RegisterVariable(&r_lightmodels);
29 }
30
31 int     r_dlightframecount;
32
33 /*
34 ==================
35 R_AnimateLight
36 ==================
37 */
38 void R_AnimateLight (void)
39 {
40         int                     i,j,k;
41         
42 //
43 // light animations
44 // 'm' is normal light, 'a' is no light, 'z' is double bright
45         i = (int)(cl.time*10);
46         for (j=0 ; j<MAX_LIGHTSTYLES ; j++)
47         {
48                 if (!cl_lightstyle[j].length)
49                 {
50                         d_lightstylevalue[j] = 256;
51                         continue;
52                 }
53                 k = i % cl_lightstyle[j].length;
54                 k = cl_lightstyle[j].map[k] - 'a';
55                 k = k*22;
56                 d_lightstylevalue[j] = k;
57         }       
58 }
59
60 /*
61 =============================================================================
62
63 DYNAMIC LIGHTS
64
65 =============================================================================
66 */
67
68 /*
69 =============
70 R_MarkLights
71 =============
72 */
73 void R_OldMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, mnode_t *node)
74 {
75         float           dist;
76         msurface_t      *surf;
77         int                     i;
78 //      float           l, maxdist;
79 //      int                     j, s, t;
80 //      vec3_t          impact;
81         float cr = light->color[0];
82         float cg = light->color[1];
83         float cb = light->color[2];
84         float radius = light->radius*light->radius*16.0f;
85         float radius2 = radius * 16.0f;
86         radius -= 65536.0f; // for comparisons
87
88 loc0:
89         if (node->contents < 0)
90                 return;
91
92 //      dist = DotProduct (lightorigin, node->plane->normal) - node->plane->dist;
93         dist = PlaneDiff(lightorigin, node->plane);
94         
95         if (dist > light->radius)
96         {
97                 if (node->children[0]->contents >= 0) // LordHavoc: save some time by not pushing another stack frame
98                 {
99                         node = node->children[0];
100                         goto loc0;
101                 }
102                 return;
103         }
104         if (dist < -light->radius)
105         {
106                 if (node->children[1]->contents >= 0) // LordHavoc: save some time by not pushing another stack frame
107                 {
108                         node = node->children[1];
109                         goto loc0;
110                 }
111                 return;
112         }
113
114         if (node->dlightframe != r_dlightframecount) // not dynamic until now
115         {
116                 node->dlightbits[0] = node->dlightbits[1] = node->dlightbits[2] = node->dlightbits[3] = node->dlightbits[4] = node->dlightbits[5] = node->dlightbits[6] = node->dlightbits[7] = 0;
117                 node->dlightframe = r_dlightframecount;
118         }
119         node->dlightbits[bitindex] |= bit;
120
121 //      maxdist = light->radius*light->radius;
122
123 // mark the polygons
124         surf = cl.worldmodel->surfaces + node->firstsurface;
125         for (i=0 ; i<node->numsurfaces ; i++, surf++)
126         {
127                 glpoly_t *p;
128                 float f;
129                 int j;
130                 float *v;
131                 if (surf->dlightframe != r_dlightframecount) // not dynamic until now
132                 {
133 //                      surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
134 //                      surf->dlightframe = r_dlightframecount;
135 //                      surf->dlightbits[bitindex] = bit;
136                         for (p = surf->polys;p;p = p->next)
137                         {
138                                 for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
139                                 {
140                                         f = VectorDistance2(v, lightorigin);
141                                         if (f < radius)
142                                         {
143                                                 surf->dlightframe = r_dlightframecount;
144                                                 f = radius2 / (f + 65536.0f);
145                                                 v[ 9] = cr * f;
146                                                 v[10] = cg * f;
147                                                 v[11] = cb * f;
148                                         }
149                                         else
150                                                 v[9] = v[10] = v[11] = 0;
151                                 }
152                         }
153                 }
154                 else
155                 {
156 //                      surf->dlightbits[bitindex] |= bit;
157                         for (p = surf->polys;p;p = p->next)
158                         {
159                                 for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
160                                 {
161                                         f = VectorDistance2(v, lightorigin);
162                                         if (f < radius)
163                                         {
164                                                 f = radius2 / (f + 65536.0f);
165                                                 v[ 9] += cr * f;
166                                                 v[10] += cg * f;
167                                                 v[11] += cb * f;
168                                         }
169                                 }
170                         }
171                 }
172 /*
173                 if (surf->flags & SURF_DRAWTURB) // water
174                 {
175                         if (surf->dlightframe != r_dlightframecount) // not dynamic until now
176                         {
177                                 surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
178                                 surf->dlightframe = r_dlightframecount;
179                         }
180                         surf->dlightbits[bitindex] |= bit;
181                 }
182                 // LordHavoc: MAJOR dynamic light speedup here, eliminates marking of surfaces that are too far away from light, thus preventing unnecessary uploads
183 //              else if (r_dynamicbothsides.value || (((surf->flags & SURF_PLANEBACK) && (dist < -BACKFACE_EPSILON)) || (!(surf->flags & SURF_PLANEBACK) && (dist > BACKFACE_EPSILON))))
184                 else if (((surf->flags & SURF_PLANEBACK) != 0) != (dist >= 0))
185                 {
186                         // passed the plane side check
187                         for (j=0 ; j<3 ; j++)
188                                 impact[j] = lightorigin[j] - surf->plane->normal[j]*dist;
189
190                         // clamp center of light to corner and check brightness
191                         l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
192                         s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0];
193                         s = l - s;
194                         l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
195                         t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1];
196                         t = l - t;
197                         // compare to minimum light
198                         if ((s*s+t*t+dist*dist) < maxdist)
199                         {
200                                 if (surf->dlightframe != r_dlightframecount) // not dynamic until now
201                                 {
202                                         surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
203                                         surf->dlightframe = r_dlightframecount;
204                                 }
205                                 surf->dlightbits[bitindex] |= bit;
206                         }
207                 }
208 */
209         }
210
211         if (node->children[0]->contents >= 0)
212         {
213                 if (node->children[1]->contents >= 0)
214                 {
215                         R_OldMarkLights (lightorigin, light, bit, bitindex, node->children[0]);
216                         node = node->children[1];
217                         goto loc0;
218                 }
219                 else
220                 {
221                         node = node->children[0];
222                         goto loc0;
223                 }
224         }
225         else if (node->children[1]->contents >= 0)
226         {
227                 node = node->children[1];
228                 goto loc0;
229         }
230 }
231
232 void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model)
233 {
234         mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model);
235
236         if (!pvsleaf->compressed_vis)
237         {       // no vis info, so make all visible
238                 R_OldMarkLights(lightorigin, light, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
239                 return;
240         }
241         else
242         {
243                 int             i, j, k, l, m, c;
244                 msurface_t *surf, **mark;
245                 mleaf_t *leaf;
246                 static int lightframe = 0;
247                 byte    *in = pvsleaf->compressed_vis;
248                 int             row = (model->numleafs+7)>>3;
249                 float   cr = light->color[0];
250                 float   cg = light->color[1];
251                 float   cb = light->color[2];
252                 float   radius = light->radius*light->radius*16.0f;
253                 float   radius2 = radius * 16.0f;
254                 glpoly_t *p;
255                 float f;
256                 float *v;
257
258                 lightframe++;
259                 k = 0;
260                 while (k < row)
261                 {
262                         c = *in++;
263                         if (c)
264                         {
265                                 l = model->numleafs - (k << 3);
266                                 if (l > 8)
267                                         l = 8;
268                                 for (i=0 ; i<l ; i++)
269                                 {
270                                         if (c & (1<<i))
271                                         {
272                                                 leaf = &model->leafs[(k << 3)+i+1];
273                                                 if (leaf->visframe != r_visframecount)
274                                                         continue;
275                                                 if (leaf->contents == CONTENTS_SOLID)
276                                                         continue;
277                                                 leaf->lightframe = lightframe;
278                                                 if (leaf->dlightframe != r_dlightframecount) // not dynamic until now
279                                                 {
280                                                         leaf->dlightbits[0] = leaf->dlightbits[1] = leaf->dlightbits[2] = leaf->dlightbits[3] = leaf->dlightbits[4] = leaf->dlightbits[5] = leaf->dlightbits[6] = leaf->dlightbits[7] = 0;
281                                                         leaf->dlightframe = r_dlightframecount;
282                                                 }
283                                                 leaf->dlightbits[bitindex] |= bit;
284                                                 if ((m = leaf->nummarksurfaces))
285                                                 {
286                                                         mark = leaf->firstmarksurface;
287                                                         do
288                                                         {
289                                                                 surf = *mark++;
290                                                                 if (surf->visframe != r_framecount || surf->lightframe == lightframe)
291                                                                         continue;
292                                                                 surf->lightframe = lightframe;
293 //                                                              if (((surf->flags & SURF_PLANEBACK) == 0) == ((PlaneDiff(lightorigin, surf->plane)) >= 0))
294 //                                                              {
295                                                                         if (surf->dlightframe != r_dlightframecount) // not dynamic until now
296                                                                         {
297 //                                                                              surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
298 //                                                                              surf->dlightframe = r_dlightframecount;
299 //                                                                              surf->dlightbits[bitindex] = bit;
300                                                                                 for (p = surf->polys;p;p = p->next)
301                                                                                 {
302                                                                                         for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
303                                                                                         {
304                                                                                                 f = VectorDistance2(v, lightorigin);
305                                                                                                 if (f < radius)
306                                                                                                 {
307                                                                                                         surf->dlightframe = r_dlightframecount;
308                                                                                                         f = radius2 / (f + 65536.0f);
309                                                                                                         v[ 9] = cr * f;
310                                                                                                         v[10] = cg * f;
311                                                                                                         v[11] = cb * f;
312                                                                                                 }
313                                                                                                 else
314                                                                                                         v[9] = v[10] = v[11] = 0;
315                                                                                         }
316                                                                                 }
317                                                                         }
318                                                                         else
319                                                                         {
320 //                                                                              surf->dlightbits[bitindex] |= bit;
321                                                                                 for (p = surf->polys;p;p = p->next)
322                                                                                 {
323                                                                                         for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
324                                                                                         {
325                                                                                                 f = VectorDistance2(v, lightorigin);
326                                                                                                 if (f < radius)
327                                                                                                 {
328                                                                                                         f = radius2 / (f + 65536.0f);
329                                                                                                         v[ 9] += cr * f;
330                                                                                                         v[10] += cg * f;
331                                                                                                         v[11] += cb * f;
332                                                                                                 }
333                                                                                         }
334                                                                                 }
335                                                                         }
336 //                                                              }
337                                                         }
338                                                         while (--m);
339                                                 }
340                                         }
341                                 }
342                                 k++;
343                                 continue;
344                         }
345                 
346                         k += *in++;
347                 }
348         }
349 }
350
351
352 /*
353 =============
354 R_PushDlights
355 =============
356 */
357 void R_PushDlights (void)
358 {
359         int             i;
360         dlight_t        *l;
361
362         r_dlightframecount = r_framecount + 1;  // because the count hasn't advanced yet for this frame
363
364         if (!r_dynamic.value)
365                 return;
366
367         l = cl_dlights;
368
369         for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
370         {
371                 if (l->die < cl.time || !l->radius)
372                         continue;
373 //              R_MarkLights (l->origin, l, 1<<(i&31), i >> 5, cl.worldmodel->nodes );
374                 R_VisMarkLights (l->origin, l, 1<<(i&31), i >> 5, cl.worldmodel);
375         }
376 }
377
378
379 /*
380 =============================================================================
381
382 LIGHT SAMPLING
383
384 =============================================================================
385 */
386
387 mplane_t                *lightplane;
388 vec3_t                  lightspot;
389
390 extern cvar_t r_ambient;
391
392 int RecursiveLightPoint (vec3_t color, mnode_t *node, vec3_t start, vec3_t end)
393 {
394         float           front, back, frac;
395         vec3_t          mid;
396
397 loc0:
398         if (node->contents < 0)
399                 return false;           // didn't hit anything
400         
401 // calculate mid point
402         front = PlaneDiff (start, node->plane);
403         back = PlaneDiff (end, node->plane);
404
405         // LordHavoc: optimized recursion
406         if ((back < 0) == (front < 0))
407 //              return RecursiveLightPoint (color, node->children[front < 0], start, end);
408         {
409                 node = node->children[front < 0];
410                 goto loc0;
411         }
412         
413         frac = front / (front-back);
414         mid[0] = start[0] + (end[0] - start[0])*frac;
415         mid[1] = start[1] + (end[1] - start[1])*frac;
416         mid[2] = start[2] + (end[2] - start[2])*frac;
417         
418 // go down front side
419         if (RecursiveLightPoint (color, node->children[front < 0], start, mid))
420                 return true;    // hit something
421         else
422         {
423                 int i, ds, dt;
424                 msurface_t *surf;
425         // check for impact on this node
426                 VectorCopy (mid, lightspot);
427                 lightplane = node->plane;
428
429                 surf = cl.worldmodel->surfaces + node->firstsurface;
430                 for (i = 0;i < node->numsurfaces;i++, surf++)
431                 {
432                         if (surf->flags & SURF_DRAWTILED)
433                                 continue;       // no lightmaps
434
435                         ds = (int) ((float) DotProduct (mid, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]);
436                         dt = (int) ((float) DotProduct (mid, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]);
437
438                         if (ds < surf->texturemins[0] || dt < surf->texturemins[1])
439                                 continue;
440                         
441                         ds -= surf->texturemins[0];
442                         dt -= surf->texturemins[1];
443                         
444                         if (ds > surf->extents[0] || dt > surf->extents[1])
445                                 continue;
446
447                         if (surf->samples)
448                         {
449                                 byte *lightmap;
450                                 int maps, line3, dsfrac = ds & 15, dtfrac = dt & 15, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0;
451                                 float scale;
452                                 line3 = ((surf->extents[0]>>4)+1)*3;
453
454                                 lightmap = surf->samples + ((dt>>4) * ((surf->extents[0]>>4)+1) + (ds>>4))*3; // LordHavoc: *3 for color
455
456                                 for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++)
457                                 {
458                                         scale = (float) d_lightstylevalue[surf->styles[maps]] * 1.0 / 256.0;
459                                         r00 += (float) lightmap[      0] * scale;g00 += (float) lightmap[      1] * scale;b00 += (float) lightmap[2] * scale;
460                                         r01 += (float) lightmap[      3] * scale;g01 += (float) lightmap[      4] * scale;b01 += (float) lightmap[5] * scale;
461                                         r10 += (float) lightmap[line3+0] * scale;g10 += (float) lightmap[line3+1] * scale;b10 += (float) lightmap[line3+2] * scale;
462                                         r11 += (float) lightmap[line3+3] * scale;g11 += (float) lightmap[line3+4] * scale;b11 += (float) lightmap[line3+5] * scale;
463                                         lightmap += ((surf->extents[0]>>4)+1) * ((surf->extents[1]>>4)+1)*3; // LordHavoc: *3 for colored lighting
464                                 }
465
466                                 color[0] += (float) ((int) ((((((((r11-r10) * dsfrac) >> 4) + r10)-((((r01-r00) * dsfrac) >> 4) + r00)) * dtfrac) >> 4) + ((((r01-r00) * dsfrac) >> 4) + r00)));
467                                 color[1] += (float) ((int) ((((((((g11-g10) * dsfrac) >> 4) + g10)-((((g01-g00) * dsfrac) >> 4) + g00)) * dtfrac) >> 4) + ((((g01-g00) * dsfrac) >> 4) + g00)));
468                                 color[2] += (float) ((int) ((((((((b11-b10) * dsfrac) >> 4) + b10)-((((b01-b00) * dsfrac) >> 4) + b00)) * dtfrac) >> 4) + ((((b01-b00) * dsfrac) >> 4) + b00)));
469                         }
470                         return true; // success
471                 }
472
473         // go down back side
474                 return RecursiveLightPoint (color, node->children[front >= 0], mid, end);
475         }
476 }
477
478 void R_LightPoint (vec3_t color, vec3_t p)
479 {
480         vec3_t          end;
481         
482         if (r_fullbright.value || !cl.worldmodel->lightdata)
483         {
484                 color[0] = color[1] = color[2] = 255;
485                 return;
486         }
487         
488         end[0] = p[0];
489         end[1] = p[1];
490         end[2] = p[2] - 2048;
491
492         color[0] = color[1] = color[2] = r_ambient.value * 2.0f;
493         RecursiveLightPoint (color, cl.worldmodel->nodes, p, end);
494 }
495
496 // LordHavoc: R_DynamicLightPoint - acumulates the dynamic lighting
497 void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits)
498 {
499         int             i, j, k;
500         vec3_t  dist;
501         float   brightness, r, f;
502
503         if (!r_dynamic.value || (!dlightbits[0] && !dlightbits[1] && !dlightbits[2] && !dlightbits[3] && !dlightbits[4] && !dlightbits[5] && !dlightbits[6] && !dlightbits[7]))
504                 return;
505
506         for (j = 0;j < (MAX_DLIGHTS >> 5);j++)
507         {
508                 if (dlightbits[j])
509                 {
510                         for (i=0 ; i<32 ; i++)
511                         {
512                                 if ((!((1 << (i&31)) & dlightbits[i>>5])) || cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
513                                         continue;
514                                 k = (j<<5)+i;
515                                 VectorSubtract (org, cl_dlights[k].origin, dist);
516                                 f = DotProduct(dist, dist) + 65536.0f;
517                                 r = cl_dlights[k].radius*cl_dlights[k].radius*16.0f;
518                                 if (f < r)
519                                 {
520                                         brightness = r * 16.0f / f;
521                                         color[0] += brightness * cl_dlights[k].color[0];
522                                         color[1] += brightness * cl_dlights[k].color[1];
523                                         color[2] += brightness * cl_dlights[k].color[2];
524                                 }
525                         }
526                 }
527         }
528 }
529
530 // same as above but no bitmask to check
531 void R_DynamicLightPointNoMask(vec3_t color, vec3_t org)
532 {
533         int             i;
534         vec3_t  dist;
535         float   brightness, r, f;
536
537         if (!r_dynamic.value)
538                 return;
539
540         for (i=0 ; i<MAX_DLIGHTS ; i++)
541         {
542                 if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
543                         continue;
544                 VectorSubtract (org, cl_dlights[i].origin, dist);
545                 f = DotProduct(dist, dist) + 65536.0f;
546                 r = cl_dlights[i].radius*cl_dlights[i].radius*16.0f;
547                 if (f < r)
548                 {
549                         brightness = r * 16.0f / f;
550                         if (cl_dlights[i].dark)
551                                 brightness = -brightness;
552                         color[0] += brightness * cl_dlights[i].color[0];
553                         color[1] += brightness * cl_dlights[i].color[1];
554                         color[2] += brightness * cl_dlights[i].color[2];
555                 }
556         }
557 }
558
559 void R_CompleteLightPoint (vec3_t color, vec3_t p)
560 {
561         R_LightPoint(color, p);
562         R_DynamicLightPointNoMask(color, p);
563 }
564
565 extern float *aliasvert;
566 extern float *aliasvertnorm;
567 extern byte *aliasvertcolor;
568 extern vec_t shadecolor[];
569 extern float modelalpha;
570 extern qboolean lighthalf;
571 extern int modeldlightbits[8];
572 void R_LightModel(int numverts, vec3_t center)
573 {
574         int i, j, nearlights = 0;
575         vec3_t dist;
576         float t, t1, t2, t3, *avn;
577         byte r,g,b,a, *avc;
578         struct
579         {
580                 vec3_t color;
581                 vec3_t origin;
582         } nearlight[MAX_DLIGHTS];
583         if (!lighthalf)
584         {
585                 shadecolor[0] *= 2.0f;
586                 shadecolor[1] *= 2.0f;
587                 shadecolor[2] *= 2.0f;
588         }
589         avc = aliasvertcolor;
590         avn = aliasvertnorm;
591         a = (byte) bound((int) 0, (int) (modelalpha * 255.0f), (int) 255);
592         if (currententity->effects & EF_FULLBRIGHT)
593         {
594                 if (lighthalf)
595                 {
596                         r = (byte) ((float) (128.0f * currententity->colormod[0]));
597                         g = (byte) ((float) (128.0f * currententity->colormod[1]));
598                         b = (byte) ((float) (128.0f * currententity->colormod[2]));
599                 }
600                 else
601                 {
602                         r = (byte) ((float) (255.0f * currententity->colormod[0]));
603                         g = (byte) ((float) (255.0f * currententity->colormod[1]));
604                         b = (byte) ((float) (255.0f * currententity->colormod[2]));
605                 }
606                 for (i = 0;i < numverts;i++)
607                 {
608                         *avc++ = r;
609                         *avc++ = g;
610                         *avc++ = b;
611                         *avc++ = a;
612                 }
613                 return;
614         }
615         if (r_lightmodels.value)
616         {
617                 for (i = 0;i < MAX_DLIGHTS;i++)
618                 {
619                         if (!modeldlightbits[i >> 5])
620                         {
621                                 i |= 31;
622                                 continue;
623                         }
624                         if (!(modeldlightbits[i >> 5] & (1 << (i & 31))))
625                                 continue;
626 //                      if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
627 //                              continue;
628                         VectorSubtract (center, cl_dlights[i].origin, dist);
629                         t1 = cl_dlights[i].radius*cl_dlights[i].radius*16.0f;
630                         t2 = DotProduct(dist,dist) + 65536.0f;
631                         if (t2 < t1)
632                         {
633                                 VectorCopy(cl_dlights[i].origin, nearlight[nearlights].origin);
634                                 nearlight[nearlights].color[0] = cl_dlights[i].color[0] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
635                                 nearlight[nearlights].color[1] = cl_dlights[i].color[1] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
636                                 nearlight[nearlights].color[2] = cl_dlights[i].color[2] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
637                                 if (lighthalf)
638                                 {
639                                         nearlight[nearlights].color[0] *= 0.5f;
640                                         nearlight[nearlights].color[1] *= 0.5f;
641                                         nearlight[nearlights].color[2] *= 0.5f;
642                                 }
643                                 t1 = 0.5f / t2;
644                                 shadecolor[0] += nearlight[nearlights].color[0] * t1;
645                                 shadecolor[1] += nearlight[nearlights].color[1] * t1;
646                                 shadecolor[2] += nearlight[nearlights].color[2] * t1;
647                                 nearlight[nearlights].color[0] *= currententity->colormod[0];
648                                 nearlight[nearlights].color[1] *= currententity->colormod[1];
649                                 nearlight[nearlights].color[2] *= currententity->colormod[2];
650                                 nearlights++;
651                         }
652                 }
653         }
654         else
655         {
656                 for (i = 0;i < MAX_DLIGHTS;i++)
657                 {
658                         if (!modeldlightbits[i >> 5])
659                         {
660                                 i |= 31;
661                                 continue;
662                         }
663                         if (!(modeldlightbits[i >> 5] & (1 << (i & 31))))
664                                 continue;
665 //                      if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
666 //                              continue;
667                         VectorSubtract (center, cl_dlights[i].origin, dist);
668                         t2 = DotProduct(dist,dist) + 65536.0f;
669                         t1 = cl_dlights[i].radius*cl_dlights[i].radius*16.0f;
670                         if (t2 < t1)
671                         {
672                                 dist[0] = cl_dlights[i].color[0] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
673                                 dist[1] = cl_dlights[i].color[1] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
674                                 dist[2] = cl_dlights[i].color[2] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
675                                 if (lighthalf)
676                                 {
677                                         dist[0] *= 0.5f;
678                                         dist[1] *= 0.5f;
679                                         dist[2] *= 0.5f;
680                                 }
681                                 t1 = 0.75f / t2;
682                                 shadecolor[0] += dist[0] * t1;
683                                 shadecolor[1] += dist[1] * t1;
684                                 shadecolor[2] += dist[2] * t1;
685                         }
686                 }
687         }
688         shadecolor[0] *= currententity->colormod[0];
689         shadecolor[1] *= currententity->colormod[1];
690         shadecolor[2] *= currententity->colormod[2];
691         t1 = bound(0, shadecolor[0], 255);r = (byte) t1;
692         t1 = bound(0, shadecolor[1], 255);g = (byte) t1;
693         t1 = bound(0, shadecolor[2], 255);b = (byte) t1;
694         if (nearlights)
695         {
696                 int temp;
697                 vec3_t v;
698                 float *av;
699                 av = aliasvert;
700                 if (nearlights == 1)
701                 {
702                         for (i = 0;i < numverts;i++)
703                         {
704                                 VectorSubtract(nearlight[0].origin, av, v);
705                                 t = DotProduct(avn,v);
706                                 if (t > 0)
707                                 {
708                                         t /= DotProduct(v,v);
709                                         temp = (int) ((float) (shadecolor[0] + nearlight[0].color[0] * t));if (temp < 0) temp = 0;else if (temp > 255) temp = 255;*avc++ = temp;
710                                         temp = (int) ((float) (shadecolor[1] + nearlight[0].color[1] * t));if (temp < 0) temp = 0;else if (temp > 255) temp = 255;*avc++ = temp;
711                                         temp = (int) ((float) (shadecolor[2] + nearlight[0].color[2] * t));if (temp < 0) temp = 0;else if (temp > 255) temp = 255;*avc++ = temp;
712                                 }
713                                 else
714                                 {
715                                         *avc++ = r;
716                                         *avc++ = g;
717                                         *avc++ = b;
718                                 }
719                                 *avc++ = a;
720                                 av+=3;
721                                 avn+=3;
722                         }
723                 }
724                 else
725                 {
726                         int i1, i2, i3;
727                         for (i = 0;i < numverts;i++)
728                         {
729                                 t1 = shadecolor[0];
730                                 t2 = shadecolor[1];
731                                 t3 = shadecolor[2];
732                                 for (j = 0;j < nearlights;j++)
733                                 {
734                                         VectorSubtract(nearlight[j].origin, av, v);
735                                         t = DotProduct(avn,v);
736                                         if (t > 0)
737                                         {
738                                                 t /= DotProduct(v,v);
739                                                 t1 += nearlight[j].color[0] * t;
740                                                 t2 += nearlight[j].color[1] * t;
741                                                 t3 += nearlight[j].color[2] * t;
742                                         }
743                                 }
744                                 i1 = t1;if (i1 < 0) i1 = 0;else if (i1 > 255) i1 = 255;
745                                 i2 = t2;if (i2 < 0) i2 = 0;else if (i2 > 255) i2 = 255;
746                                 i3 = t3;if (i3 < 0) i3 = 0;else if (i3 > 255) i3 = 255;
747                                 *avc++ = i1;
748                                 *avc++ = i2;
749                                 *avc++ = i3;
750                                 *avc++ = a;
751                         }
752                 }
753         }
754         else
755         {
756                 for (i = 0;i < numverts;i++)
757                 {
758                         *avc++ = r;
759                         *avc++ = g;
760                         *avc++ = b;
761                         *avc++ = a;
762                 }
763         }
764 }