19fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 29fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamCopyright (C) 1996-1997 Id Software, Inc. 39fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 49fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is free software; you can redistribute it and/or 59fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammodify it under the terms of the GNU General Public License 69fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamas published by the Free Software Foundation; either version 2 79fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamof the License, or (at your option) any later version. 89fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 99fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is distributed in the hope that it will be useful, 109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreambut WITHOUT ANY WARRANTY; without even the implied warranty of 111b0eae1b322d3164b83c3f6346999da8c4916fa6Jack PalevichMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamSee the GNU General Public License for more details. 149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamYou should have received a copy of the GNU General Public License 169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamalong with this program; if not, write to the Free Software 179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 20cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// r_light.c 21cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "quakedef.h" 23cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 24cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint r_dlightframecount; 25cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 26cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 27cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/* 28cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich================== 29cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichR_AnimateLight 30cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich================== 31cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/ 32cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid R_AnimateLight (void) 33cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{ 34cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int i,j,k; 351b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 36cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// 37cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// light animations 38cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// 'm' is normal light, 'a' is no light, 'z' is double bright 39cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich i = (int)(cl.time*10); 40cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (j=0 ; j<MAX_LIGHTSTYLES ; j++) 41cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 42cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (!cl_lightstyle[j].length) 43cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 44cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich d_lightstylevalue[j] = 256; 45cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich continue; 46cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 47cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich k = i % cl_lightstyle[j].length; 48cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich k = cl_lightstyle[j].map[k] - 'a'; 49cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich k = k*22; 50cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich d_lightstylevalue[j] = k; 511b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich } 52cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich} 53cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream============================================================================= 569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamDYNAMIC LIGHTS BLEND RENDERING 589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream============================================================================= 609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid AddLightBlend (float r, float g, float b, float a2) 639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float a; 659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v_blend[3] = a = v_blend[3] + a2*(1-v_blend[3]); 679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream a2 = a2/a; 699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v_blend[0] = v_blend[1]*(1-a2) + r*a2; 719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v_blend[1] = v_blend[1]*(1-a2) + g*a2; 729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v_blend[2] = v_blend[2]*(1-a2) + b*a2; 739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderDlight (dlight_t *light) 769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int i, j; 789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float a; 799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream vec3_t v; 809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream float rad; 819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream rad = light->radius * 0.35; 839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream VectorSubtract (light->origin, r_origin, v); 859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (Length (v) < rad) 869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { // view is inside the dlight 879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream AddLightBlend (1, 0.5, 0, light->radius * 0.0003); 889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 91cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#ifdef USE_OPENGLES 92cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich glEnableClientState(GL_COLOR_ARRAY); 93cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich glDisableClientState(GL_TEXTURE_COORD_ARRAY); 94cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich glVertexPointer(3, GL_FLOAT, 0, gVertexBuffer); 951b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich glColorPointer(4, GL_FLOAT, 0, gColorBuffer); 96cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 97cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 98cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich float* pPos = gVertexBuffer; 99cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich float* pColor = gColorBuffer; 1001b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 0.2f; 1011b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 0.1f; 1021b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 0.0f; 1031b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 1.0f; 104cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (i=0 ; i<3 ; i++) 105cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich *pPos++ = light->origin[i] - vpn[i]*rad; 106cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (i=16 ; i>=0 ; i--) 107cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 1081b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 0.0f; 1091b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 0.0f; 1101b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 0.0f; 1111b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich *pColor++ = 0.0f; 112cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich a = i/16.0 * M_PI*2; 113cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (j=0 ; j<3 ; j++) 114cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich *pPos++ = light->origin[j] + vright[j]*cos(a)*rad 115cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich + vup[j]*sin(a)*rad; 116cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 117cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 118cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich glDrawArrays(GL_TRIANGLE_FAN, 0, 18); 119cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich glDisableClientState(GL_COLOR_ARRAY); 120cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich glEnableClientState(GL_TEXTURE_COORD_ARRAY); 121cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich glColor3f(0,0,0); // Ensure the color ends up being zero just like the non-OpenGLES code 1221b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 123cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#else 1249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glBegin (GL_TRIANGLE_FAN); 1259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glColor3f (0.2,0.1,0.0); 1269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=0 ; i<3 ; i++) 1279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v[i] = light->origin[i] - vpn[i]*rad; 1289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glVertex3fv (v); 1299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glColor3f (0,0,0); 1309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=16 ; i>=0 ; i--) 1319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 1329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream a = i/16.0 * M_PI*2; 1339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (j=0 ; j<3 ; j++) 1349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream v[j] = light->origin[j] + vright[j]*cos(a)*rad 1359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream + vup[j]*sin(a)*rad; 1369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glVertex3fv (v); 1379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 1389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glEnd (); 139cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#endif 1409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 1419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/* 1439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream============= 1449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderDlights 1459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream============= 1469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/ 1479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderDlights (void) 1489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{ 1499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream int i; 1509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream dlight_t *l; 1519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (!gl_flashblend.value) 1539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 1549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream r_dlightframecount = r_framecount + 1; // because the count hasn't 1569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream // advanced yet for this frame 1579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glDepthMask (0); 1589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glDisable (GL_TEXTURE_2D); 1599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glShadeModel (GL_SMOOTH); 1609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glEnable (GL_BLEND); 1619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glBlendFunc (GL_ONE, GL_ONE); 1629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream l = cl_dlights; 1649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream for (i=0 ; i<MAX_DLIGHTS ; i++, l++) 1659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream { 1669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (l->die < cl.time || !l->radius) 1679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream continue; 1689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream R_RenderDlight (l); 1699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream } 1709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 1719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glColor3f (1,1,1); 1729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glDisable (GL_BLEND); 1739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glEnable (GL_TEXTURE_2D); 1749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream glDepthMask (1); 1769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} 1779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 178cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 179cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/* 180cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============================================================================= 181cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 182cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichDYNAMIC LIGHTS 183cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 184cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============================================================================= 185cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/ 186cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 187cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/* 188cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============= 189cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichR_MarkLights 190cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============= 191cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/ 192cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid R_MarkLights (dlight_t *light, int bit, mnode_t *node) 193cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{ 194cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich mplane_t *splitplane; 195cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich float dist; 196cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich msurface_t *surf; 197cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int i; 1981b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 199cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (node->contents < 0) 200cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return; 201cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 202cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich splitplane = node->plane; 203cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; 2041b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 205cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (dist > light->radius) 206cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 207cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich R_MarkLights (light, bit, node->children[0]); 208cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return; 209cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 210cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (dist < -light->radius) 211cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 212cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich R_MarkLights (light, bit, node->children[1]); 213cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return; 214cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 2151b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 216cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// mark the polygons 217cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich surf = cl.worldmodel->surfaces + node->firstsurface; 218cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (i=0 ; i<node->numsurfaces ; i++, surf++) 219cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 220cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (surf->dlightframe != r_dlightframecount) 221cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 222cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich surf->dlightbits = 0; 223cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich surf->dlightframe = r_dlightframecount; 224cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 225cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich surf->dlightbits |= bit; 226cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 227cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 228cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich R_MarkLights (light, bit, node->children[0]); 229cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich R_MarkLights (light, bit, node->children[1]); 230cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich} 231cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 232cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 233cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/* 234cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============= 235cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichR_PushDlights 236cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============= 237cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/ 238cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid R_PushDlights (void) 239cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{ 240cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int i; 241cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich dlight_t *l; 2429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream if (gl_flashblend.value) 2449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream return; 245cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 246cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich r_dlightframecount = r_framecount + 1; // because the count hasn't 247cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich // advanced yet for this frame 248cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich l = cl_dlights; 249cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 250cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (i=0 ; i<MAX_DLIGHTS ; i++, l++) 251cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 252cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (l->die < cl.time || !l->radius) 253cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich continue; 254cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich R_MarkLights ( l, 1<<i, cl.worldmodel->nodes ); 255cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 256cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich} 257cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 258cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 259cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/* 260cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============================================================================= 261cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 262cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichLIGHT SAMPLING 263cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 264cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich============================================================================= 265cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/ 2669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream 2679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammplane_t *lightplane; 2689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvec3_t lightspot; 269cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 270cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) 271cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{ 272cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int r; 273cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich float front, back, frac; 274cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int side; 275cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich mplane_t *plane; 276cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich vec3_t mid; 277cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich msurface_t *surf; 278cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int s, t, ds, dt; 279cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int i; 280cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich mtexinfo_t *tex; 281cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich byte *lightmap; 282cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich unsigned scale; 283cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int maps; 284cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 285cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (node->contents < 0) 286cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return -1; // didn't hit anything 2871b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 288cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// calculate mid point 289cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 290cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// FIXME: optimize for axial 291cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich plane = node->plane; 292cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich front = DotProduct (start, plane->normal) - plane->dist; 293cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich back = DotProduct (end, plane->normal) - plane->dist; 294cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich side = front < 0; 2951b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 296cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if ( (back < 0) == side) 297cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return RecursiveLightPoint (node->children[side], start, end); 2981b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 299cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich frac = front / (front-back); 300cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich mid[0] = start[0] + (end[0] - start[0])*frac; 301cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich mid[1] = start[1] + (end[1] - start[1])*frac; 302cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich mid[2] = start[2] + (end[2] - start[2])*frac; 3031b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 3041b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich// go down front side 305cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich r = RecursiveLightPoint (node->children[side], start, mid); 306cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (r >= 0) 307cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return r; // hit something 3081b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 309cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if ( (back < 0) == side ) 310cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return -1; // didn't hit anuthing 3111b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 312cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// check for impact on this node 3139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream VectorCopy (mid, lightspot); 3149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream lightplane = plane; 315cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 316cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich surf = cl.worldmodel->surfaces + node->firstsurface; 317cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (i=0 ; i<node->numsurfaces ; i++, surf++) 318cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 319cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (surf->flags & SURF_DRAWTILED) 320cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich continue; // no lightmaps 321cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 322cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich tex = surf->texinfo; 3231b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 324cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich s = (int) (DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]); 325cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich t = (int) (DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3]); 326cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 327cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (s < surf->texturemins[0] || 328cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich t < surf->texturemins[1]) 329cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich continue; 3301b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 331cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich ds = s - surf->texturemins[0]; 332cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich dt = t - surf->texturemins[1]; 3331b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 334cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if ( ds > surf->extents[0] || dt > surf->extents[1] ) 335cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich continue; 336cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 337cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (!surf->samples) 338cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return 0; 339cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 340cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich ds >>= 4; 341cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich dt >>= 4; 342cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 343cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich lightmap = surf->samples; 344cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich r = 0; 345cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (lightmap) 346cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 347cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 348cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich lightmap += dt * ((surf->extents[0]>>4)+1) + ds; 349cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 350cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; 351cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich maps++) 352cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich { 353cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich scale = d_lightstylevalue[surf->styles[maps]]; 354cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich r += *lightmap * scale; 355cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich lightmap += ((surf->extents[0]>>4)+1) * 356cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich ((surf->extents[1]>>4)+1); 357cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 3581b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 359cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich r >>= 8; 360cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 3611b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 362cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return r; 363cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich } 364cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 365cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// go down back side 366cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return RecursiveLightPoint (node->children[!side], mid, end); 367cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich} 368cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 369cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint R_LightPoint (vec3_t p) 370cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{ 371cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich vec3_t end; 372cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich int r; 3731b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 374cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (!cl.worldmodel->lightdata) 375cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return 255; 3761b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 377cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich end[0] = p[0]; 378cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich end[1] = p[1]; 379cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich end[2] = p[2] - 2048; 3801b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 381cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich r = RecursiveLightPoint (cl.worldmodel->nodes, p, end); 3821b0eae1b322d3164b83c3f6346999da8c4916fa6Jack Palevich 383cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich if (r == -1) 384cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich r = 0; 385cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich 386cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich return r; 387cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich} 388