home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / client / gl_rlight.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-21  |  7.6 KB  |  382 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.  
  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<MAX_LIGHTSTYLES ; 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. //Con_Printf("AddLightBlend(): %4.2f %4.2f %4.2f %4.6f\n", v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
  74. }
  75.  
  76. float bubble_sintable[17], bubble_costable[17];
  77.  
  78. void R_InitBubble() {
  79.     float a;
  80.     int i;
  81.     float *bub_sin, *bub_cos;
  82.  
  83.     bub_sin = bubble_sintable;
  84.     bub_cos = bubble_costable;
  85.  
  86.     for (i=16 ; i>=0 ; i--)
  87.     {
  88.         a = i/16.0 * M_PI*2;
  89.         *bub_sin++ = sin(a);
  90.         *bub_cos++ = cos(a);
  91.     }
  92. }
  93.  
  94. void R_RenderDlight (dlight_t *light)
  95. {
  96.     int        i, j;
  97. //    float    a;
  98.     vec3_t    v;
  99.     float    rad;
  100.     float    *bub_sin, *bub_cos;
  101.  
  102.     bub_sin = bubble_sintable;
  103.     bub_cos = bubble_costable;
  104.     rad = light->radius * 0.35;
  105.  
  106.     VectorSubtract (light->origin, r_origin, v);
  107.     if (Length (v) < rad)
  108.     {    // view is inside the dlight
  109.         AddLightBlend (1, 0.5, 0, light->radius * 0.0003);
  110.         return;
  111.     }
  112.  
  113.     glBegin (GL_TRIANGLE_FAN);
  114. //    glColor3f (0.2,0.1,0.0);
  115. //    glColor3f (0.2,0.1,0.05); // changed dimlight effect
  116.     glColor4f (light->color[0], light->color[1], light->color[2],
  117.         light->color[3]);
  118.     for (i=0 ; i<3 ; i++)
  119.         v[i] = light->origin[i] - vpn[i]*rad;
  120.     glVertex3fv (v);
  121.     glColor3f (0,0,0);
  122.     for (i=16 ; i>=0 ; i--)
  123.     {
  124. //        a = i/16.0 * M_PI*2;
  125.         for (j=0 ; j<3 ; j++)
  126.             v[j] = light->origin[j] + (vright[j]*(*bub_cos) +
  127.                 + vup[j]*(*bub_sin)) * rad;
  128.         bub_sin++; 
  129.         bub_cos++;
  130.         glVertex3fv (v);
  131.     }
  132.     glEnd ();
  133. }
  134.  
  135. /*
  136. =============
  137. R_RenderDlights
  138. =============
  139. */
  140. void R_RenderDlights (void)
  141. {
  142.     int        i;
  143.     dlight_t    *l;
  144.  
  145.     if (!gl_flashblend.value)
  146.         return;
  147.  
  148.     r_dlightframecount = r_framecount + 1;    // because the count hasn't
  149.                                             //  advanced yet for this frame
  150.     glDepthMask (0);
  151.     glDisable (GL_TEXTURE_2D);
  152.     glShadeModel (GL_SMOOTH);
  153.     glEnable (GL_BLEND);
  154.     glBlendFunc (GL_ONE, GL_ONE);
  155.  
  156.     l = cl_dlights;
  157.     for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
  158.     {
  159.         if (l->die < cl.time || !l->radius)
  160.             continue;
  161.         R_RenderDlight (l);
  162.     }
  163.  
  164.     glColor3f (1,1,1);
  165.     glDisable (GL_BLEND);
  166.     glEnable (GL_TEXTURE_2D);
  167.     glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  168.     glDepthMask (1);
  169. }
  170.  
  171.  
  172. /*
  173. =============================================================================
  174.  
  175. DYNAMIC LIGHTS
  176.  
  177. =============================================================================
  178. */
  179.  
  180. /*
  181. =============
  182. R_MarkLights
  183. =============
  184. */
  185. void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
  186. {
  187.     mplane_t    *splitplane;
  188.     float        dist;
  189.     msurface_t    *surf;
  190.     int            i;
  191.     
  192.     if (node->contents < 0)
  193.         return;
  194.  
  195.     splitplane = node->plane;
  196.     dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
  197.     
  198.     if (dist > light->radius)
  199.     {
  200.         R_MarkLights (light, bit, node->children[0]);
  201.         return;
  202.     }
  203.     if (dist < -light->radius)
  204.     {
  205.         R_MarkLights (light, bit, node->children[1]);
  206.         return;
  207.     }
  208.         
  209. // mark the polygons
  210.     surf = cl.worldmodel->surfaces + node->firstsurface;
  211.     for (i=0 ; i<node->numsurfaces ; i++, surf++)
  212.     {
  213.         if (surf->dlightframe != r_dlightframecount)
  214.         {
  215.             surf->dlightbits = 0;
  216.             surf->dlightframe = r_dlightframecount;
  217.         }
  218.         surf->dlightbits |= bit;
  219.     }
  220.  
  221.     R_MarkLights (light, bit, node->children[0]);
  222.     R_MarkLights (light, bit, node->children[1]);
  223. }
  224.  
  225.  
  226. /*
  227. =============
  228. R_PushDlights
  229. =============
  230. */
  231. void R_PushDlights (void)
  232. {
  233.     int        i;
  234.     dlight_t    *l;
  235.  
  236.     if (gl_flashblend.value)
  237.         return;
  238.  
  239.     r_dlightframecount = r_framecount + 1;    // because the count hasn't
  240.                                             //  advanced yet for this frame
  241.     l = cl_dlights;
  242.  
  243.     for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
  244.     {
  245.         if (l->die < cl.time || !l->radius)
  246.             continue;
  247.         R_MarkLights ( l, 1<<i, cl.worldmodel->nodes );
  248.     }
  249. }
  250.  
  251.  
  252. /*
  253. =============================================================================
  254.  
  255. LIGHT SAMPLING
  256.  
  257. =============================================================================
  258. */
  259.  
  260. mplane_t        *lightplane;
  261. vec3_t            lightspot;
  262.  
  263. int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
  264. {
  265.     int            r;
  266.     float        front, back, frac;
  267.     int            side;
  268.     mplane_t    *plane;
  269.     vec3_t        mid;
  270.     msurface_t    *surf;
  271.     int            s, t, ds, dt;
  272.     int            i;
  273.     mtexinfo_t    *tex;
  274.     byte        *lightmap;
  275.     unsigned    scale;
  276.     int            maps;
  277.  
  278.     if (node->contents < 0)
  279.         return -1;        // didn't hit anything
  280.     
  281. // calculate mid point
  282.  
  283. // FIXME: optimize for axial
  284.     plane = node->plane;
  285.     front = DotProduct (start, plane->normal) - plane->dist;
  286.     back = DotProduct (end, plane->normal) - plane->dist;
  287.     side = front < 0;
  288.     
  289.     if ( (back < 0) == side)
  290.         return RecursiveLightPoint (node->children[side], start, end);
  291.     
  292.     frac = front / (front-back);
  293.     mid[0] = start[0] + (end[0] - start[0])*frac;
  294.     mid[1] = start[1] + (end[1] - start[1])*frac;
  295.     mid[2] = start[2] + (end[2] - start[2])*frac;
  296.     
  297. // go down front side    
  298.     r = RecursiveLightPoint (node->children[side], start, mid);
  299.     if (r >= 0)
  300.         return r;        // hit something
  301.         
  302.     if ( (back < 0) == side )
  303.         return -1;        // didn't hit anuthing
  304.         
  305. // check for impact on this node
  306.     VectorCopy (mid, lightspot);
  307.     lightplane = plane;
  308.  
  309.     surf = cl.worldmodel->surfaces + node->firstsurface;
  310.     for (i=0 ; i<node->numsurfaces ; i++, surf++)
  311.     {
  312.         if (surf->flags & SURF_DRAWTILED)
  313.             continue;    // no lightmaps
  314.  
  315.         tex = surf->texinfo;
  316.         
  317.         s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
  318.         t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];;
  319.  
  320.         if (s < surf->texturemins[0] ||
  321.         t < surf->texturemins[1])
  322.             continue;
  323.         
  324.         ds = s - surf->texturemins[0];
  325.         dt = t - surf->texturemins[1];
  326.         
  327.         if ( ds > surf->extents[0] || dt > surf->extents[1] )
  328.             continue;
  329.  
  330.         if (!surf->samples)
  331.             return 0;
  332.  
  333.         ds >>= 4;
  334.         dt >>= 4;
  335.  
  336.         lightmap = surf->samples;
  337.         r = 0;
  338.         if (lightmap)
  339.         {
  340.  
  341.             lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
  342.  
  343.             for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  344.                     maps++)
  345.             {
  346.                 scale = d_lightstylevalue[surf->styles[maps]];
  347.                 r += *lightmap * scale;
  348.                 lightmap += ((surf->extents[0]>>4)+1) *
  349.                         ((surf->extents[1]>>4)+1);
  350.             }
  351.             
  352.             r >>= 8;
  353.         }
  354.         
  355.         return r;
  356.     }
  357.  
  358. // go down back side
  359.     return RecursiveLightPoint (node->children[!side], mid, end);
  360. }
  361.  
  362. int R_LightPoint (vec3_t p)
  363. {
  364.     vec3_t        end;
  365.     int            r;
  366.     
  367.     if (!cl.worldmodel->lightdata)
  368.         return 255;
  369.     
  370.     end[0] = p[0];
  371.     end[1] = p[1];
  372.     end[2] = p[2] - 2048;
  373.     
  374.     r = RecursiveLightPoint (cl.worldmodel->nodes, p, end);
  375.     
  376.     if (r == -1)
  377.         r = 0;
  378.  
  379.     return r;
  380. }
  381.  
  382.