diff --git a/include/r_cvar.h b/include/r_cvar.h index 1b5cb2a6e..9595e408b 100644 --- a/include/r_cvar.h +++ b/include/r_cvar.h @@ -15,7 +15,6 @@ extern struct cvar_s *gl_clear; extern struct cvar_s *gl_conalpha; extern struct cvar_s *gl_conspin; extern struct cvar_s *gl_constretch; -extern struct cvar_s *gl_dlight_lightmap; extern struct cvar_s *gl_dlight_polyblend; extern struct cvar_s *gl_dlight_smooth; extern struct cvar_s *gl_fb_bmodels; @@ -25,7 +24,6 @@ extern struct cvar_s *gl_keeptjunctions; extern struct cvar_s *gl_lerp_anim; extern struct cvar_s *gl_libgl; extern struct cvar_s *gl_lightmap_align; -extern struct cvar_s *gl_lightmap_components; extern struct cvar_s *gl_lightmap_subimage; extern struct cvar_s *gl_max_size; extern struct cvar_s *gl_multitexture; @@ -47,6 +45,7 @@ extern struct cvar_s *r_aliastransadj; extern struct cvar_s *r_aliastransbase; extern struct cvar_s *r_ambient; extern struct cvar_s *r_clearcolor; +extern struct cvar_s *r_dlight_lightmap; extern struct cvar_s *r_drawentities; extern struct cvar_s *r_drawflat; extern struct cvar_s *r_draworder; @@ -57,6 +56,7 @@ extern struct cvar_s *r_firecolor; extern struct cvar_s *r_fullbright; extern struct cvar_s *r_graphheight; extern struct cvar_s *r_lightmap; +extern struct cvar_s *r_lightmap_components; extern struct cvar_s *r_maxedges; extern struct cvar_s *r_maxsurfs; extern struct cvar_s *r_mirroralpha; diff --git a/libs/video/renderer/Makefile.am b/libs/video/renderer/Makefile.am index 164919a60..579943ca7 100644 --- a/libs/video/renderer/Makefile.am +++ b/libs/video/renderer/Makefile.am @@ -21,7 +21,8 @@ endif lib_LTLIBRARIES = $(RENDERER_GL) $(RENDERER_SW) $(RENDERER_SW32) -common_SOURCES = r_cvar.c r_efrag.c r_ent.c r_graph.c r_main.c r_part.c +common_SOURCES = r_cvar.c r_efrag.c r_ent.c r_graph.c r_light.c r_main.c \ + r_part.c libQFrenderer_gl_la_LDFLAGS = -version-info 1:0:0 libQFrenderer_gl_la_LIBADD = gl/libgl.la diff --git a/libs/video/renderer/gl/Makefile.am b/libs/video/renderer/gl/Makefile.am index 3f70f6e29..24f6854a9 100644 --- a/libs/video/renderer/gl/Makefile.am +++ b/libs/video/renderer/gl/Makefile.am @@ -10,7 +10,7 @@ endif noinst_LTLIBRARIES = $(GL) libgl_la_LDFLAGS = -version-info 1:0:0 -libgl_la_SOURCES = gl_draw.c gl_dyn_fires.c gl_dyn_part.c gl_dyn_textures.c \ - gl_graph.c gl_rlight.c gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c \ - gl_skin.c gl_sky.c gl_sky_clip.c gl_textures.c gl_warp.c gl_funcs.c \ - noisetextures.c +libgl_la_SOURCES = gl_draw.c gl_dyn_fires.c gl_dyn_part.c gl_dyn_lights.c \ + gl_dyn_textures.c gl_graph.c gl_rmain.c gl_rmisc.c gl_rsurf.c \ + gl_screen.c gl_skin.c gl_sky.c gl_sky_clip.c gl_textures.c gl_warp.c \ + gl_funcs.c noisetextures.c diff --git a/libs/video/renderer/gl/gl_draw.c b/libs/video/renderer/gl/gl_draw.c index 6ab0fb591..f0f21c952 100644 --- a/libs/video/renderer/gl/gl_draw.c +++ b/libs/video/renderer/gl/gl_draw.c @@ -59,10 +59,12 @@ #include "sbar.h" extern byte *vid_basepal; + extern cvar_t *crosshair, *cl_crossx, *cl_crossy, *crosshaircolor, - *gl_lightmap_components; + *r_lightmap_components; byte *draw_chars; // 8*8 graphic characters + qpic_t *draw_backtile; static int translate_texture; @@ -109,7 +111,8 @@ Draw_PicFromWad (const char *name) p = W_GetLumpName (name); gl = (glpic_t *) p->data; - gl->texnum = GL_LoadTexture (name, p->width, p->height, p->data, false, true, 1); + gl->texnum = GL_LoadTexture (name, p->width, p->height, p->data, false, + true, 1); return p; } diff --git a/libs/video/renderer/gl/gl_dyn_lights.c b/libs/video/renderer/gl/gl_dyn_lights.c new file mode 100644 index 000000000..f6bbfc6b5 --- /dev/null +++ b/libs/video/renderer/gl/gl_dyn_lights.c @@ -0,0 +1,156 @@ +/* + gl_dyn_lights.c + + polyblended dynamic lights + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include +#include + +#include "QF/cvar.h" +#include "QF/render.h" +#include "QF/GL/defines.h" +#include "QF/GL/funcs.h" + +#include "r_cvar.h" +#include "r_local.h" +#include "r_shared.h" + +float bubble_sintable[33], bubble_costable[33]; + +extern float v_blend[4]; + + +void +AddLightBlend (float r, float g, float b, float a2) +{ + float a; + + v_blend[3] = a = v_blend[3] + a2 * (1 - v_blend[3]); + + a2 = a2 / a; + + v_blend[0] = v_blend[0] * (1 - a2) + r * a2; + v_blend[1] = v_blend[1] * (1 - a2) + g * a2; + v_blend[2] = v_blend[2] * (1 - a2) + b * a2; +} + +void +R_InitBubble () +{ + int i; + float a; + float *bub_sin, *bub_cos; + + bub_sin = bubble_sintable; + bub_cos = bubble_costable; + + for (i = 32; i >= 0; i--) { + a = i / 32.0 * M_PI * 2; + *bub_sin++ = sin (a); + *bub_cos++ = cos (a); + } +} + +void +R_RenderDlight (dlight_t *light) +{ + int i, j; + vec3_t v; + float rad; + float *bub_sin, *bub_cos; + + bub_sin = bubble_sintable; + bub_cos = bubble_costable; + rad = light->radius * 0.35; + + VectorSubtract (light->origin, r_origin, v); + if (Length (v) < rad) { // view is inside the dlight + return; + } + + qfglBegin (GL_TRIANGLE_FAN); + + qfglColor3fv (light->color); + + VectorSubtract (r_origin, light->origin, v); + VectorNormalize (v); + + for (i = 0; i < 3; i++) + v[i] = light->origin[i] + v[i] * rad; + + qfglVertex3fv (v); + qfglColor3f (0, 0, 0); + + for (i = 16; i >= 0; i--) { + for (j = 0; j < 3; j++) + v[j] = light->origin[j] + (vright[j] * (*bub_cos) + + vup[j] * (*bub_sin)) * rad; + bub_sin += 2; + bub_cos += 2; + qfglVertex3fv (v); + } + + qfglEnd (); +} + +void +R_RenderDlights (void) +{ + int i; + dlight_t *l; + + if (!gl_dlight_polyblend->int_val) + return; + + qfglDepthMask (GL_FALSE); + qfglDisable (GL_TEXTURE_2D); + qfglBlendFunc (GL_ONE, GL_ONE); + qfglShadeModel (GL_SMOOTH); + + l = r_dlights; + for (i = 0; i < MAX_DLIGHTS; i++, l++) { + if (l->die < r_realtime || !l->radius) + continue; + R_RenderDlight (l); + } + + if (!gl_dlight_smooth->int_val) + qfglShadeModel (GL_FLAT); + qfglColor3ubv (lighthalf_v); + qfglEnable (GL_TEXTURE_2D); + qfglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qfglDepthMask (GL_TRUE); +} diff --git a/libs/video/renderer/gl/gl_dyn_part.c b/libs/video/renderer/gl/gl_dyn_part.c index d701858c4..7f1504bec 100644 --- a/libs/video/renderer/gl/gl_dyn_part.c +++ b/libs/video/renderer/gl/gl_dyn_part.c @@ -222,7 +222,6 @@ R_ParticleExplosion (vec3_t org) { if (!r_particles->int_val) return; - particle_new_random (pt_smokecloud, part_tex_smoke[rand () & 7], org, 4, 30, 8, r_realtime + 5, (rand () & 7) + 8, 128 + (rand () & 63)); @@ -275,9 +274,9 @@ R_RunSparkEffect (vec3_t org, int count, int ofuzz) (ofuzz / 8) * .75, vec3_origin, r_realtime + 99, 12 + (rand () & 3), 96, vec3_origin, vec3_origin); while (count--) - particle_new_random (pt_fallfadespark, part_tex_spark, org, ofuzz * .75, - 1, 96, r_realtime + 5, ramp[rand () % 6], - lhrandom (0, 255)); + particle_new_random (pt_fallfadespark, part_tex_spark, org, + ofuzz * .75, 1, 96, r_realtime + 5, + ramp[rand () % 6], lhrandom (0, 255)); } static void @@ -532,7 +531,6 @@ R_RocketTrail (int type, entity_t *ent) } break; case 6: // voor trail -// Use smoke ring effects here, once merged with nq? --Despair dist = 3; pcolor = 9 * 16 + 8 + (rand () & 3); ptype = pt_static; @@ -680,13 +678,13 @@ R_DrawParticles (void) if ((part->alpha -= r_frametime * 90) < 1) part->die = -1; part->scale += r_frametime * 6; -// part->org[2] += r_frametime * 30; +// part->org[2] += r_frametime * 30 - grav; break; case pt_smokering: if ((part->alpha -= r_frametime * 130) < 1) part->die = -1; part->scale += r_frametime * 10; -// part->org[2] += r_frametime * 30; +// part->org[2] += r_frametime * 30 - grav; break; case pt_smokecloud: if ((part->alpha -= r_frametime * 128) < 1) diff --git a/libs/video/renderer/gl/gl_rlight.c b/libs/video/renderer/gl/gl_rlight.c deleted file mode 100644 index 369747d8c..000000000 --- a/libs/video/renderer/gl/gl_rlight.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - gl_rlight.c - - @description@ - - Copyright (C) 1996-1997 Id Software, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include -#include - -#include "QF/cvar.h" -#include "QF/render.h" -#include "QF/GL/defines.h" -#include "QF/GL/funcs.h" - -#include "r_cvar.h" -#include "r_local.h" -#include "r_shared.h" - -extern float v_blend[4]; - - -void -R_AnimateLight (void) -{ - int i, j, k; - -// light animations -// 'm' is normal light, 'a' is no light, 'z' is double bright - i = (int) (r_realtime * 10); - for (j = 0; j < MAX_LIGHTSTYLES; j++) { - if (!r_lightstyle[j].length) { - d_lightstylevalue[j] = 256; - continue; - } - k = i % r_lightstyle[j].length; - k = r_lightstyle[j].map[k] - 'a'; - k = k * 22; - d_lightstylevalue[j] = k; - } -} - -/* - DYNAMIC LIGHTS BLEND RENDERING -*/ - -void -AddLightBlend (float r, float g, float b, float a2) -{ - float a; - - v_blend[3] = a = v_blend[3] + a2 * (1 - v_blend[3]); - - a2 = a2 / a; - - v_blend[0] = v_blend[0] * (1 - a2) + r * a2; - v_blend[1] = v_blend[1] * (1 - a2) + g * a2; - v_blend[2] = v_blend[2] * (1 - a2) + b * a2; -} - -float bubble_sintable[33], bubble_costable[33]; - -void -R_InitBubble () -{ - int i; - float a; - float *bub_sin, *bub_cos; - - bub_sin = bubble_sintable; - bub_cos = bubble_costable; - - for (i = 32; i >= 0; i--) { - a = i / 32.0 * M_PI * 2; - *bub_sin++ = sin (a); - *bub_cos++ = cos (a); - } -} - -void -R_RenderDlight (dlight_t *light) -{ - int i, j; - vec3_t v; - float rad; - float *bub_sin, *bub_cos; - - bub_sin = bubble_sintable; - bub_cos = bubble_costable; - rad = light->radius * 0.35; - - VectorSubtract (light->origin, r_origin, v); - if (Length (v) < rad) { // view is inside the dlight - return; - } - - qfglBegin (GL_TRIANGLE_FAN); - - qfglColor3fv (light->color); - - VectorSubtract (r_origin, light->origin, v); - VectorNormalize (v); - - for (i = 0; i < 3; i++) - v[i] = light->origin[i] + v[i] * rad; - - qfglVertex3fv (v); - qfglColor3f (0, 0, 0); - - for (i = 16; i >= 0; i--) { - for (j = 0; j < 3; j++) - v[j] = light->origin[j] + (vright[j] * (*bub_cos) + - vup[j] * (*bub_sin)) * rad; - bub_sin += 2; - bub_cos += 2; - qfglVertex3fv (v); - } - - qfglEnd (); -} - -void -R_RenderDlights (void) -{ - int i; - dlight_t *l; - - if (!gl_dlight_polyblend->int_val) - return; - - qfglDepthMask (GL_FALSE); - qfglDisable (GL_TEXTURE_2D); - qfglBlendFunc (GL_ONE, GL_ONE); - qfglShadeModel (GL_SMOOTH); - - l = r_dlights; - for (i = 0; i < MAX_DLIGHTS; i++, l++) { - if (l->die < r_realtime || !l->radius) - continue; - R_RenderDlight (l); - } - - if (!gl_dlight_smooth->int_val) - qfglShadeModel (GL_FLAT); - qfglColor3ubv (lighthalf_v); - qfglEnable (GL_TEXTURE_2D); - qfglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qfglDepthMask (GL_TRUE); -} - -/* - DYNAMIC LIGHTS -*/ - -// LordHavoc: heavily modified, to eliminate unnecessary texture uploads, -// and support bmodel lighting better -void -R_RecursiveMarkLights (vec3_t lightorigin, dlight_t *light, int bit, - mnode_t *node) -{ - mplane_t *splitplane; - float ndist, maxdist; - msurface_t *surf; - int i; - - maxdist = light->radius * light->radius; - -loc0: - if (node->contents < 0) - return; - - splitplane = node->plane; - ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist; - - if (ndist > light->radius) { - // Save time by not pushing another stack frame. - if (node->children[0]->contents >= 0) { - node = node->children[0]; - goto loc0; - } - return; - } - if (ndist < -light->radius) { - // Save time by not pushing another stack frame. - if (node->children[1]->contents >= 0) { - node = node->children[1]; - goto loc0; - } - return; - } - -// mark the polygons - surf = r_worldentity.model->surfaces + node->firstsurface; - for (i = 0; i < node->numsurfaces; i++, surf++) { - int s, t; - float l, dist, dist2; - vec3_t impact; - - dist = ndist; - - dist2 = dist * dist; - if (dist2 >= maxdist) - continue; - - impact[0] = light->origin[0] - surf->plane->normal[0] * dist; - impact[1] = light->origin[1] - surf->plane->normal[1] * dist; - impact[2] = light->origin[2] - surf->plane->normal[2] * dist; - - l = DotProduct (impact, surf->texinfo->vecs[0]) + - surf->texinfo->vecs[0][3] - surf->texturemins[0]; - s = l + 0.5; - if (s < 0) - s = 0; - else if (s > surf->extents[0]) - s = surf->extents[0]; - s = l - s; - l = DotProduct (impact, surf->texinfo->vecs[1]) + - surf->texinfo->vecs[1][3] - surf->texturemins[1]; - t = l + 0.5; - if (t < 0) - t = 0; - else if (t > surf->extents[1]) - t = surf->extents[1]; - t = l - t; - - if ((s * s + t * t + dist * dist) < maxdist) { - if (surf->dlightframe != r_framecount) { - surf->dlightframe = r_framecount; - surf->dlightbits = bit; - } else { - surf->dlightbits |= bit; - } - } - } - - if (node->children[0]->contents >= 0) { - if (node->children[1]->contents >= 0) - R_RecursiveMarkLights (lightorigin, light, bit, node->children[1]); - node = node->children[0]; - goto loc0; - } else if (node->children[1]->contents >= 0) { - node = node->children[1]; - goto loc0; - } -} - -static void -mark_surfaces (msurface_t *surf, vec3_t lightorigin, dlight_t *light, - int bit) -{ - float dist; -#if 1 - float dist2, d; - float maxdist = light->radius * light->radius; - vec3_t impact; -#endif - - dist = PlaneDiff(lightorigin, surf->plane); - if (surf->flags & SURF_PLANEBACK) - dist = -dist; - if ((dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES)) - || dist > light->radius) - return; -#if 1 - dist2 = dist * dist; - dist = -dist; - VectorMA (light->origin, dist, surf->plane->normal, impact); - - d = DotProduct (impact, surf->texinfo->vecs[0]) - + surf->texinfo->vecs[0][3] - surf->texturemins[0]; - if (d < 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } else { - d -= surf->extents[0] + 16; - if (d > 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } - } - d = DotProduct (impact, surf->texinfo->vecs[1]) - + surf->texinfo->vecs[1][3] - surf->texturemins[1]; - if (d < 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } else { - d -= surf->extents[1] + 16; - if (d > 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } - } -#endif - if (surf->dlightframe != r_framecount) { - surf->dlightbits = 0; - surf->dlightframe = r_framecount; - } - surf->dlightbits |= bit; -} - -void -R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, model_t *model) -{ - mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model); - - if (!pvsleaf->compressed_vis) { - mnode_t *node = model->nodes + model->hulls[0].firstclipnode; - R_RecursiveMarkLights (lightorigin, light, bit, node); - } else { - float radius = light->radius; - vec3_t mins, maxs; - int leafnum = 0; - byte *in = pvsleaf->compressed_vis; - byte vis_bits; - - mins[0] = lightorigin[0] - radius; - mins[1] = lightorigin[1] - radius; - mins[2] = lightorigin[2] - radius; - maxs[0] = lightorigin[0] + radius; - maxs[1] = lightorigin[1] + radius; - maxs[2] = lightorigin[2] + radius; - while (leafnum < model->numleafs) { - int i; - if (!(vis_bits = *in++)) { - leafnum += (*in++) * 8; - continue; - } - for (i = 0; i < 8 && leafnum < model->numleafs; i++, leafnum++) { - int m; - mleaf_t *leaf = &model->leafs[leafnum + 1]; - if (!(vis_bits & (1 << i))) - continue; - if (leaf->visframe != r_visframecount) - continue; - if (leaf->mins[0] > maxs[0] || leaf->maxs[0] < mins[0] - || leaf->mins[1] > maxs[1] || leaf->maxs[1] < mins[1] - || leaf->mins[2] > maxs[2] || leaf->maxs[2] < mins[2]) - continue; - if (leaf->dlightframe != r_framecount) { - leaf->dlightbits = 0; - leaf->dlightframe = r_framecount; - } - leaf->dlightbits |= bit; - for (m = 0; m < leaf->nummarksurfaces; m++) { - msurface_t *surf = leaf->firstmarksurface[m]; - if (surf->visframe != r_visframecount) - continue; - mark_surfaces (surf, lightorigin, light, bit); - } - } - } - } -} - -void -R_PushDlights (vec3_t entorigin) -{ - int i; - dlight_t *l; - vec3_t lightorigin; - - if (!gl_dlight_lightmap->int_val) - return; - - l = r_dlights; - - for (i = 0; i < MAX_DLIGHTS; i++, l++) { - if (l->die < r_realtime || !l->radius) - continue; - VectorSubtract (l->origin, entorigin, lightorigin); - R_MarkLights (lightorigin, l, 1 << i, r_worldentity.model); - } -} - -/* - LIGHT SAMPLING -*/ - -mplane_t *lightplane; -vec3_t lightspot; - -int -RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) -{ - int r; - float front, back, frac; - int side; - mplane_t *plane; - vec3_t mid; - msurface_t *surf; - int s, t, ds, dt; - int i; - mtexinfo_t *tex; - byte *lightmap; - unsigned int scale; - int maps; - - if (node->contents < 0) - return -1; // didn't hit anything - -// calculate mid point - -// FIXME: optimize for axial - plane = node->plane; - front = DotProduct (start, plane->normal) - plane->dist; - back = DotProduct (end, plane->normal) - plane->dist; - side = front < 0; - - if ((back < 0) == side) - return RecursiveLightPoint (node->children[side], start, end); - - frac = front / (front - back); - mid[0] = start[0] + (end[0] - start[0]) * frac; - mid[1] = start[1] + (end[1] - start[1]) * frac; - mid[2] = start[2] + (end[2] - start[2]) * frac; - -// go down front side - r = RecursiveLightPoint (node->children[side], start, mid); - if (r >= 0) - return r; // hit something - - if ((back < 0) == side) - return -1; // didn't hit anything - -// check for impact on this node - VectorCopy (mid, lightspot); - lightplane = plane; - - surf = r_worldentity.model->surfaces + node->firstsurface; - for (i = 0; i < node->numsurfaces; i++, surf++) { - if (surf->flags & SURF_DRAWTILED) - continue; // no lightmaps - - tex = surf->texinfo; - - s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; - t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];; - - if (s < surf->texturemins[0] || t < surf->texturemins[1]) - continue; - - ds = s - surf->texturemins[0]; - dt = t - surf->texturemins[1]; - - if (ds > surf->extents[0] || dt > surf->extents[1]) - continue; - - if (!surf->samples) - return 0; - - ds >>= 4; - dt >>= 4; - - lightmap = surf->samples; - r = 0; - if (lightmap) { - - lightmap += dt * ((surf->extents[0] >> 4) + 1) + ds; - - for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; - maps++) { - scale = d_lightstylevalue[surf->styles[maps]]; - r += *lightmap * scale; - lightmap += ((surf->extents[0] >> 4) + 1) * - ((surf->extents[1] >> 4) + 1); - } - - r >>= 8; - } - - return r; - } - -// go down back side - return RecursiveLightPoint (node->children[!side], mid, end); -} - -int -R_LightPoint (vec3_t p) -{ - vec3_t end; - int r; - - if (!r_worldentity.model->lightdata) - return 255; - - end[0] = p[0]; - end[1] = p[1]; - end[2] = p[2] - 2048; - - r = RecursiveLightPoint (r_worldentity.model->nodes, p, end); - - if (r == -1) - r = 0; - - return r; -} diff --git a/libs/video/renderer/gl/gl_rsurf.c b/libs/video/renderer/gl/gl_rsurf.c index 555486df3..1bcf6295a 100644 --- a/libs/video/renderer/gl/gl_rsurf.c +++ b/libs/video/renderer/gl/gl_rsurf.c @@ -130,9 +130,9 @@ R_ForceLightUpdate (void) } /* - R_AddDynamicLights + R_AddDynamicLights - LordHavoc: completely rewrote this, relies on 64bit integer math... + LordHavoc: completely rewrote this, relies on 64bit integer math... */ void R_AddDynamicLights (msurface_t *surf) @@ -208,12 +208,12 @@ R_AddDynamicLights (msurface_t *surf) } /* - R_BuildLightMap + R_BuildLightMap - Combine and scale multiple lightmaps - After talking it over with LordHavoc, I've decided to switch to using - GL_RGB for colored lights and averaging them out for plain white - lighting if needed. Much cleaner that way. --KB + Combine and scale multiple lightmaps. + After talking it over with LordHavoc, I've decided to switch to using + GL_RGB for colored lights and averaging them out for plain white + lighting if needed. Much cleaner that way. --KB */ void R_BuildLightMap (msurface_t *surf, byte * dest, int stride) @@ -311,9 +311,9 @@ R_BuildLightMap (msurface_t *surf, byte * dest, int stride) } /* - R_TextureAnimation + R_TextureAnimation - Returns the proper texture for a given time and base texture + Returns the proper texture for a given time and base texture */ texture_t * R_TextureAnimation (texture_t *base) @@ -344,7 +344,7 @@ R_TextureAnimation (texture_t *base) } /* - BRUSH MODELS + BRUSH MODELS */ extern int solidskytexture; @@ -699,7 +699,7 @@ R_DrawBrushModel (entity_t *e) psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; // calculate dynamic lighting for bmodel if it's not an instanced model - if (clmodel->firstmodelsurface != 0 && gl_dlight_lightmap->int_val) { + if (clmodel->firstmodelsurface != 0 && r_dlight_lightmap->int_val) { vec3_t lightorigin; for (k = 0; k < MAX_DLIGHTS; k++) { @@ -759,7 +759,7 @@ R_DrawBrushModel (entity_t *e) } /* - WORLD MODEL + WORLD MODEL */ void @@ -1107,9 +1107,9 @@ GL_CreateSurfaceLightmap (msurface_t *surf) } /* - GL_BuildLightmaps + GL_BuildLightmaps - Builds the lightmap texture with all the surfaces from all brush models + Builds the lightmap texture with all the surfaces from all brush models */ void GL_BuildLightmaps (model_t **models, int num_models) @@ -1126,7 +1126,7 @@ GL_BuildLightmaps (model_t **models, int num_models) texture_extension_number += MAX_LIGHTMAPS; } - switch (gl_lightmap_components->int_val) { + switch (r_lightmap_components->int_val) { case 1: gl_internalformat = 1; gl_lightmap_format = GL_LUMINANCE; @@ -1156,7 +1156,8 @@ GL_BuildLightmaps (model_t **models, int num_models) for (i = 0; i < m->numsurfaces; i++) { if (m->surfaces[i].flags & SURF_DRAWTURB) continue; - if (gl_sky_divide->int_val && (m->surfaces[i].flags & SURF_DRAWSKY)) + if (gl_sky_divide->int_val && (m->surfaces[i].flags & + SURF_DRAWSKY)) continue; GL_CreateSurfaceLightmap (m->surfaces + i); BuildSurfaceDisplayList (m->surfaces + i); diff --git a/libs/video/renderer/r_cvar.c b/libs/video/renderer/r_cvar.c index f24be5b78..57c2a5118 100644 --- a/libs/video/renderer/r_cvar.c +++ b/libs/video/renderer/r_cvar.c @@ -55,7 +55,6 @@ cvar_t *gl_clear; cvar_t *gl_conalpha; cvar_t *gl_conspin; cvar_t *gl_constretch; -cvar_t *gl_dlight_lightmap; cvar_t *gl_dlight_polyblend; cvar_t *gl_dlight_smooth; cvar_t *gl_fb_bmodels; @@ -65,7 +64,6 @@ cvar_t *gl_keeptjunctions; cvar_t *gl_lerp_anim; cvar_t *gl_libgl; cvar_t *gl_lightmap_align; -cvar_t *gl_lightmap_components; cvar_t *gl_lightmap_subimage; cvar_t *gl_max_size; cvar_t *gl_nocolors; @@ -85,6 +83,7 @@ cvar_t *r_aliastransadj; cvar_t *r_aliastransbase; cvar_t *r_ambient; cvar_t *r_clearcolor; +cvar_t *r_dlight_lightmap; cvar_t *r_drawentities; cvar_t *r_drawflat; cvar_t *r_drawviewmodel; @@ -92,6 +91,7 @@ cvar_t *r_dspeeds; cvar_t *r_dynamic; cvar_t *r_firecolor; cvar_t *r_graphheight; +cvar_t *r_lightmap_components; cvar_t *r_maxedges; cvar_t *r_maxsurfs; cvar_t *r_mirroralpha; @@ -156,9 +156,6 @@ R_Init_Cvars (void) "speed at which the console spins"); gl_constretch = Cvar_Get ("gl_constretch", "0", CVAR_ARCHIVE, NULL, "toggle console between slide and stretch"); - gl_dlight_lightmap = Cvar_Get ("gl_dlight_lightmap", "1", CVAR_ARCHIVE, - NULL, "Set to 1 for high quality dynamic " - "lighting."); gl_dlight_polyblend = Cvar_Get ("gl_dlight_polyblend", "0", CVAR_ARCHIVE, NULL, "Set to 1 to use a dynamic light " "effect faster on GL"); @@ -181,9 +178,6 @@ R_Init_Cvars (void) "Workaround for nvidia slow path. Set to 4 " "or 16 if you have an nvidia 3d " "accelerator, set to 1 otherwise."); - gl_lightmap_components = Cvar_Get ("gl_lightmap_components", "4", CVAR_ROM, - NULL, "Lightmap texture components. 1 " - "is greyscale, 3 is RGB, 4 is RGBA."); gl_lightmap_subimage = Cvar_Get ("gl_lightmap_subimage", "1", CVAR_NONE, NULL, "Lightmap Update method. Default 2 " "updates a minimum 'dirty rectangle' " @@ -234,6 +228,9 @@ R_Init_Cvars (void) r_clearcolor = Cvar_Get ("r_clearcolor", "2", CVAR_NONE, NULL, "This sets the color for areas outside of the " "current map"); + r_dlight_lightmap = Cvar_Get ("r_dlight_lightmap", "1", CVAR_ARCHIVE, + NULL, "Set to 1 for high quality dynamic " + "lighting."); r_drawentities = Cvar_Get ("r_drawentities", "1", CVAR_NONE, NULL, "Toggles drawing of entities (almost " "everything but the world)"); @@ -250,6 +247,9 @@ R_Init_Cvars (void) r_graphheight = Cvar_Get ("r_graphheight", "32", CVAR_NONE, NULL, "Set the number of lines displayed in the " "various graphs"); + r_lightmap_components = Cvar_Get ("r_lightmap_components", "4", CVAR_ROM, + NULL, "Lightmap texture components. 1 " + "is greyscale, 3 is RGB, 4 is RGBA."); r_maxedges = Cvar_Get ("r_maxedges", "0", CVAR_NONE, NULL, "Sets the maximum number of edges"); r_maxsurfs = Cvar_Get ("r_maxsurfs", "0", CVAR_NONE, NULL, diff --git a/libs/video/renderer/sw/sw_rlight.c b/libs/video/renderer/r_light.c similarity index 82% rename from libs/video/renderer/sw/sw_rlight.c rename to libs/video/renderer/r_light.c index 387b7d870..70e98e404 100644 --- a/libs/video/renderer/sw/sw_rlight.c +++ b/libs/video/renderer/r_light.c @@ -1,7 +1,7 @@ /* r_light.c - (description) + common lightmap code. Copyright (C) 1996-1997 Id Software, Inc. @@ -29,10 +29,22 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#include +#include + +#include "QF/cvar.h" #include "QF/render.h" +#include "r_cvar.h" #include "r_local.h" +#include "r_shared.h" void @@ -55,10 +67,8 @@ R_AnimateLight (void) } } -/* - DYNAMIC LIGHTS -*/ - +// LordHavoc: heavily modified, to eliminate unnecessary texture uploads, +// and support bmodel lighting better void R_RecursiveMarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node) @@ -69,6 +79,7 @@ R_RecursiveMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int i; maxdist = light->radius * light->radius; + loc0: if (node->contents < 0) return; @@ -77,6 +88,7 @@ loc0: ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist; if (ndist > light->radius) { + // Save time by not pushing another stack frame. if (node->children[0]->contents >= 0) { node = node->children[0]; goto loc0; @@ -84,20 +96,56 @@ loc0: return; } if (ndist < -light->radius) { + // Save time by not pushing another stack frame. if (node->children[1]->contents >= 0) { node = node->children[1]; goto loc0; } return; } + // mark the polygons surf = r_worldentity.model->surfaces + node->firstsurface; for (i = 0; i < node->numsurfaces; i++, surf++) { - if (surf->dlightframe != r_framecount) { - surf->dlightbits = 0; - surf->dlightframe = r_framecount; + int s, t; + float l, dist, dist2; + vec3_t impact; + + dist = ndist; + + dist2 = dist * dist; + if (dist2 >= maxdist) + continue; + + impact[0] = light->origin[0] - surf->plane->normal[0] * dist; + impact[1] = light->origin[1] - surf->plane->normal[1] * dist; + impact[2] = light->origin[2] - surf->plane->normal[2] * dist; + + l = DotProduct (impact, surf->texinfo->vecs[0]) + + surf->texinfo->vecs[0][3] - surf->texturemins[0]; + s = l + 0.5; + if (s < 0) + s = 0; + else if (s > surf->extents[0]) + s = surf->extents[0]; + s = l - s; + l = DotProduct (impact, surf->texinfo->vecs[1]) + + surf->texinfo->vecs[1][3] - surf->texturemins[1]; + t = l + 0.5; + if (t < 0) + t = 0; + else if (t > surf->extents[1]) + t = surf->extents[1]; + t = l - t; + + if ((s * s + t * t + dist * dist) < maxdist) { + if (surf->dlightframe != r_framecount) { + surf->dlightframe = r_framecount; + surf->dlightbits = bit; + } else { + surf->dlightbits |= bit; + } } - surf->dlightbits |= bit; } if (node->children[0]->contents >= 0) { @@ -223,7 +271,6 @@ R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, model_t *model) } } - void R_PushDlights (vec3_t entorigin) { @@ -231,6 +278,9 @@ R_PushDlights (vec3_t entorigin) dlight_t *l; vec3_t lightorigin; + if (!r_dlight_lightmap->int_val) + return; + l = r_dlights; for (i = 0; i < MAX_DLIGHTS; i++, l++) { @@ -241,11 +291,12 @@ R_PushDlights (vec3_t entorigin) } } - /* - LIGHT SAMPLING + LIGHT SAMPLING */ +mplane_t *lightplane; +vec3_t lightspot; int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) @@ -266,7 +317,8 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) if (node->contents < 0) return -1; // didn't hit anything - // calculate mid point +// calculate mid point + // FIXME: optimize for axial plane = node->plane; front = DotProduct (start, plane->normal) - plane->dist; @@ -281,7 +333,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) mid[1] = start[1] + (end[1] - start[1]) * frac; mid[2] = start[2] + (end[2] - start[2]) * frac; - // go down front side +// go down front side r = RecursiveLightPoint (node->children[side], start, mid); if (r >= 0) return r; // hit something @@ -289,7 +341,10 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) if ((back < 0) == side) return -1; // didn't hit anything - // check for impact on this node +// check for impact on this node + VectorCopy (mid, lightspot); + lightplane = plane; + surf = r_worldentity.model->surfaces + node->firstsurface; for (i = 0; i < node->numsurfaces; i++, surf++) { if (surf->flags & SURF_DRAWTILED) @@ -335,11 +390,10 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) return r; } - // go down back side +// go down back side return RecursiveLightPoint (node->children[!side], mid, end); } - int R_LightPoint (vec3_t p) { @@ -358,8 +412,5 @@ R_LightPoint (vec3_t p) if (r == -1) r = 0; - if (r < r_refdef.ambientlight) - r = r_refdef.ambientlight; - return r; } diff --git a/libs/video/renderer/sw/Makefile.am b/libs/video/renderer/sw/Makefile.am index 073947c39..33c59124b 100644 --- a/libs/video/renderer/sw/Makefile.am +++ b/libs/video/renderer/sw/Makefile.am @@ -13,17 +13,14 @@ endif noinst_LTLIBRARIES = $(SW) $(ASM) -libasm_la_SOURCES = \ - d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S d_spr8.S \ - d_varsa.S surf16.S surf8.S sw_raclipa.S sw_raliasa.S sw_rdrawa.S \ - sw_redgea.S sw_rvarsa.S \ - transform.S +libasm_la_SOURCES = d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S \ + d_spr8.S d_varsa.S surf16.S surf8.S sw_raclipa.S sw_raliasa.S \ + sw_rdrawa.S sw_redgea.S sw_rvarsa.S transform.S libsw_la_LDFLAGS = -version-info 1:0:0 libsw_la_LIBADD = $(ASM) libsw_la_SOURCES = d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c \ - d_scan.c d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c draw.c \ - nonintel.c screen.c \ - sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c sw_rdraw.c sw_redge.c \ - sw_rlight.c sw_rmain.c sw_rmisc.c sw_rpart.c sw_rsky.c sw_rsprite.c \ - sw_rsurf.c sw_skin.c + d_scan.c d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c draw.c \ + nonintel.c screen.c sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c \ + sw_rdraw.c sw_redge.c sw_rmain.c sw_rmisc.c sw_rpart.c sw_rsky.c \ + sw_rsprite.c sw_rsurf.c sw_skin.c diff --git a/libs/video/renderer/sw32/Makefile.am b/libs/video/renderer/sw32/Makefile.am index d14fd2470..cba476ee4 100644 --- a/libs/video/renderer/sw32/Makefile.am +++ b/libs/video/renderer/sw32/Makefile.am @@ -11,7 +11,6 @@ noinst_LTLIBRARIES = $(SW32) libsw32_la_LDFLAGS = -version-info 1:0:0 libsw32_la_SOURCES = d_edge.c d_fill.c d_init.c d_modech.c d_part.c \ d_polyse.c d_scan.c d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c \ - draw.c screen.c sw32_graph.c sw32_raclip.c sw32_ralias.c \ - sw32_rbsp.c sw32_rdraw.c sw32_redge.c sw32_rlight.c sw32_rmain.c \ - sw32_rmisc.c sw32_rpart.c sw32_rsky.c sw32_rsprite.c sw32_rsurf.c \ - sw32_skin.c + draw.c screen.c sw32_graph.c sw32_raclip.c sw32_ralias.c sw32_rbsp.c \ + sw32_rdraw.c sw32_redge.c sw32_rmain.c sw32_rmisc.c sw32_rpart.c \ + sw32_rsky.c sw32_rsprite.c sw32_rsurf.c sw32_skin.c diff --git a/libs/video/renderer/sw32/sw32_rlight.c b/libs/video/renderer/sw32/sw32_rlight.c deleted file mode 100644 index 14efc6b06..000000000 --- a/libs/video/renderer/sw32/sw32_rlight.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - sw32_rlight.c - - (description) - - Copyright (C) 1996-1997 Id Software, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "QF/render.h" - -#include "r_local.h" - -//int r_dlightframecount; - - -void -R_AnimateLight (void) -{ - int i, j, k; - - // light animations - // 'm' is normal light, 'a' is no light, 'z' is double bright - i = (int) (r_realtime * 10); - for (j = 0; j < MAX_LIGHTSTYLES; j++) { - if (!r_lightstyle[j].length) { - d_lightstylevalue[j] = 256; - continue; - } - k = i % r_lightstyle[j].length; - k = r_lightstyle[j].map[k] - 'a'; - k = k * 22; - d_lightstylevalue[j] = k; - } -} - -/* - DYNAMIC LIGHTS -*/ - -void -R_RecursiveMarkLights (vec3_t lightorigin, dlight_t *light, int bit, - mnode_t *node) -{ - mplane_t *splitplane; - float ndist, maxdist; - msurface_t *surf; - int i; - - maxdist = light->radius * light->radius; -loc0: - if (node->contents < 0) - return; - - splitplane = node->plane; - ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist; - - if (ndist > light->radius) { - if (node->children[0]->contents >= 0) { - node = node->children[0]; - goto loc0; - } - return; - } - if (ndist < -light->radius) { - if (node->children[1]->contents >= 0) { - node = node->children[1]; - goto loc0; - } - return; - } - // mark the polygons - surf = r_worldentity.model->surfaces + node->firstsurface; - for (i = 0; i < node->numsurfaces; i++, surf++) { - if (surf->dlightframe != r_framecount) { - surf->dlightbits = 0; - surf->dlightframe = r_framecount; - } - surf->dlightbits |= bit; - } - - if (node->children[0]->contents >= 0) { - if (node->children[1]->contents >= 0) - R_RecursiveMarkLights (lightorigin, light, bit, node->children[1]); - node = node->children[0]; - goto loc0; - } else if (node->children[1]->contents >= 0) { - node = node->children[1]; - goto loc0; - } -} - -static void -mark_surfaces (msurface_t *surf, vec3_t lightorigin, dlight_t *light, - int bit) -{ - float dist; -#if 1 - float dist2, d; - float maxdist = light->radius * light->radius; - vec3_t impact; -#endif - - dist = PlaneDiff(lightorigin, surf->plane); - if (surf->flags & SURF_PLANEBACK) - dist = -dist; - if ((dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES)) - || dist > light->radius) - return; -#if 1 - dist2 = dist * dist; - dist = -dist; - VectorMA (light->origin, dist, surf->plane->normal, impact); - - d = DotProduct (impact, surf->texinfo->vecs[0]) - + surf->texinfo->vecs[0][3] - surf->texturemins[0]; - if (d < 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } else { - d -= surf->extents[0] + 16; - if (d > 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } - } - d = DotProduct (impact, surf->texinfo->vecs[1]) - + surf->texinfo->vecs[1][3] - surf->texturemins[1]; - if (d < 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } else { - d -= surf->extents[1] + 16; - if (d > 0) { - dist2 += d * d; - if (dist2 >= maxdist) - return; - } - } -#endif - if (surf->dlightframe != r_framecount) { - surf->dlightbits = 0; - surf->dlightframe = r_framecount; - } - surf->dlightbits |= bit; -} - - -void -R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, model_t *model) -{ - mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model); - - if (!pvsleaf->compressed_vis) { - mnode_t *node = model->nodes + model->hulls[0].firstclipnode; - R_RecursiveMarkLights (lightorigin, light, bit, node); - } else { - float radius = light->radius; - vec3_t mins, maxs; - int leafnum = 0; - byte *in = pvsleaf->compressed_vis; - byte vis_bits; - - mins[0] = lightorigin[0] - radius; - mins[1] = lightorigin[1] - radius; - mins[2] = lightorigin[2] - radius; - maxs[0] = lightorigin[0] + radius; - maxs[1] = lightorigin[1] + radius; - maxs[2] = lightorigin[2] + radius; - while (leafnum < model->numleafs) { - int i; - if (!(vis_bits = *in++)) { - leafnum += (*in++) * 8; - continue; - } - for (i = 0; i < 8 && leafnum < model->numleafs; i++, leafnum++) { - int m; - mleaf_t *leaf = &model->leafs[leafnum + 1]; - if (!(vis_bits & (1 << i))) - continue; - if (leaf->visframe != r_visframecount) - continue; - if (leaf->mins[0] > maxs[0] || leaf->maxs[0] < mins[0] - || leaf->mins[1] > maxs[1] || leaf->maxs[1] < mins[1] - || leaf->mins[2] > maxs[2] || leaf->maxs[2] < mins[2]) - continue; - if (leaf->dlightframe != r_framecount) { - leaf->dlightbits = 0; - leaf->dlightframe = r_framecount; - } - leaf->dlightbits |= bit; - for (m = 0; m < leaf->nummarksurfaces; m++) { - msurface_t *surf = leaf->firstmarksurface[m]; - if (surf->visframe != r_visframecount) - continue; - mark_surfaces (surf, lightorigin, light, bit); - } - } - } - } -} - -void -R_PushDlights (vec3_t entorigin) -{ - int i; - dlight_t *l; - vec3_t lightorigin; - - l = r_dlights; - - for (i = 0; i < MAX_DLIGHTS; i++, l++) { - if (l->die < r_realtime || !l->radius) - continue; - VectorSubtract (l->origin, entorigin, lightorigin); - R_MarkLights (lightorigin, l, 1 << i, r_worldentity.model); - } -} - -/* - LIGHT SAMPLING -*/ - -int -RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) -{ - int r; - float front, back, frac; - int side; - mplane_t *plane; - vec3_t mid; - msurface_t *surf; - int s, t, ds, dt; - int i; - mtexinfo_t *tex; - byte *lightmap; - unsigned int scale; - int maps; - - if (node->contents < 0) - return -1; // didn't hit anything - - // calculate mid point - // FIXME: optimize for axial - plane = node->plane; - front = DotProduct (start, plane->normal) - plane->dist; - back = DotProduct (end, plane->normal) - plane->dist; - side = front < 0; - - if ((back < 0) == side) - return RecursiveLightPoint (node->children[side], start, end); - - frac = front / (front - back); - mid[0] = start[0] + (end[0] - start[0]) * frac; - mid[1] = start[1] + (end[1] - start[1]) * frac; - mid[2] = start[2] + (end[2] - start[2]) * frac; - - // go down front side - r = RecursiveLightPoint (node->children[side], start, mid); - if (r >= 0) - return r; // hit something - - if ((back < 0) == side) - return -1; // didn't hit anything - - // check for impact on this node - - surf = r_worldentity.model->surfaces + node->firstsurface; - for (i = 0; i < node->numsurfaces; i++, surf++) { - if (surf->flags & SURF_DRAWTILED) - continue; // no lightmaps - - tex = surf->texinfo; - - s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; - t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];; - - if (s < surf->texturemins[0] || t < surf->texturemins[1]) - continue; - - ds = s - surf->texturemins[0]; - dt = t - surf->texturemins[1]; - - if (ds > surf->extents[0] || dt > surf->extents[1]) - continue; - - if (!surf->samples) - return 0; - - ds >>= 4; - dt >>= 4; - - lightmap = surf->samples; - r = 0; - if (lightmap) { - - lightmap += dt * ((surf->extents[0] >> 4) + 1) + ds; - - for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; - maps++) { - scale = d_lightstylevalue[surf->styles[maps]]; - r += *lightmap * scale; - lightmap += ((surf->extents[0] >> 4) + 1) * - ((surf->extents[1] >> 4) + 1); - } - - r >>= 8; - } - - return r; - } - - // go down back side - return RecursiveLightPoint (node->children[!side], mid, end); -} - -int -R_LightPoint (vec3_t p) -{ - vec3_t end; - int r; - - if (!r_worldentity.model->lightdata) - return 255; - - end[0] = p[0]; - end[1] = p[1]; - end[2] = p[2] - 2048; - - r = RecursiveLightPoint (r_worldentity.model->nodes, p, end); - - if (r == -1) - r = 0; - - if (r < r_refdef.ambientlight) - r = r_refdef.ambientlight; - - return r; -}