home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / gl_rlight.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-19  |  7.6 KB  |  360 lines

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