r_flare.c

Go to the documentation of this file.
00001 /*
00002  * Copyright(c) 1997-2001 Id Software, Inc.
00003  * Copyright(c) 2002 The Quakeforge Project.
00004  * Copyright(c) 2006 Quake2World.
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00014  *
00015  * See the GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 #include "r_local.h"
00023 
00024 void R_CreateSurfaceFlare (mBspSurface_t *surf)
00025 {
00026     material_t *m;
00027     const materialStage_t *s;
00028     vec3_t span;
00029 
00030     m = &surf->texinfo->image->material;
00031 
00032     if (!(m->flags & STAGE_FLARE)) /* surface is not flared */
00033         return;
00034 
00035     surf->flare = (mBspFlare_t *) Mem_PoolAlloc(sizeof(*surf->flare), vid_modelPool, 0);
00036 
00037     /* move the flare away from the surface, into the level */
00038     VectorMA(surf->center, 2, surf->normal, surf->flare->origin);
00039 
00040     /* calculate the flare radius based on surface size */
00041     VectorSubtract(surf->maxs, surf->mins, span);
00042     surf->flare->radius = VectorLength(span);
00043 
00044     s = m->stages; /* resolve the flare stage */
00045     for (;;) {
00046         if (s->flags & STAGE_FLARE)
00047             break;
00048         s = s->next;
00049     }
00050 
00051     /* resolve flare color */
00052     if (s->flags & STAGE_COLOR)
00053         VectorCopy(s->color, surf->flare->color);
00054     else
00055         VectorCopy(surf->color, surf->flare->color);
00056 
00057     /* and scaled radius */
00058     if (s->flags & (STAGE_SCALE_S | STAGE_SCALE_T))
00059         surf->flare->radius *= (s->scale.s ? s->scale.s : s->scale.t);
00060 
00061     /* and image */
00062     surf->flare->image = s->image;
00063 }
00064 
00072 void R_DrawFlareSurfaces (mBspSurfaces_t *surfs)
00073 {
00074     const image_t *image;
00075     int i, j, k, l, m;
00076     vec3_t view, verts[4];
00077     vec3_t right, up, upright, downright;
00078     float cos, dist, scale, alpha;
00079     qboolean visible;
00080 
00081     if (!r_flares->integer)
00082         return;
00083 
00084     if (!surfs->count)
00085         return;
00086 
00087     R_EnableColorArray(qtrue);
00088 
00089     R_ResetArrayState();
00090 
00091     glDisable(GL_DEPTH_TEST);
00092 
00093     image = r_flaretextures[0];
00094     R_BindTexture(image->texnum);
00095 
00096     j = k = l = 0;
00097     for (i = 0; i < surfs->count; i++) {
00098         mBspSurface_t *surf = surfs->surfaces[i];
00099         mBspFlare_t *f;
00100 
00101         if (surf->frame != r_locals.frame)
00102             continue;
00103 
00104         f = surf->flare;
00105 
00106         /* bind the flare's texture */
00107         if (f->image != image) {
00108             glDrawArrays(GL_QUADS, 0, l / 3);
00109             j = k = l = 0;
00110 
00111             image = f->image;
00112             R_BindTexture(image->texnum);
00113         }
00114 
00115         /* periodically test visibility to ramp alpha */
00116         if (refdef.time - f->time > 0.02) {
00117             if (refdef.time - f->time > 0.5) /* reset old flares */
00118                 f->alpha = 0;
00119 
00120             R_Trace(refdef.viewOrigin, f->origin, 0, MASK_SOLID);
00121             visible = refdef.trace.fraction == 1.0;
00122 
00123             f->alpha += (visible ? 0.03 : -0.15); /* ramp */
00124 
00125             if (f->alpha > 0.75) /* clamp */
00126                 f->alpha = 0.75;
00127             else if (f->alpha < 0)
00128                 f->alpha = 0.0;
00129 
00130             f->time = refdef.time;
00131         }
00132 
00133         VectorSubtract(f->origin, refdef.viewOrigin, view);
00134         dist = VectorNormalize(view);
00135 
00136         /* fade according to angle */
00137         cos = DotProduct(surf->normal, view);
00138         if (cos > 0)
00139             continue;
00140 
00141         alpha = 0.1 + -cos * r_flares->value;
00142 
00143         if (alpha > 1.0)
00144             alpha = 1.0;
00145 
00146         alpha = f->alpha * alpha;
00147 
00148         /* scale according to distance */
00149         scale = f->radius + (f->radius * dist * .0005);
00150 
00151         VectorScale(r_locals.right, scale, right);
00152         VectorScale(r_locals.up, scale, up);
00153 
00154         VectorAdd(up, right, upright);
00155         VectorSubtract(right, up, downright);
00156 
00157         VectorSubtract(f->origin, downright, verts[0]);
00158         VectorAdd(f->origin, upright, verts[1]);
00159         VectorAdd(f->origin, downright, verts[2]);
00160         VectorSubtract(f->origin, upright, verts[3]);
00161 
00162         for (m = 0; m < 4; m++) { /* duplicate color data to all 4 verts */
00163             memcpy(&r_state.color_array[j], f->color, sizeof(vec3_t));
00164             r_state.color_array[j + 3] = alpha;
00165             j += 4;
00166         }
00167 
00168         /* copy texcoord info */
00169         memcpy(&texunit_diffuse.texcoord_array[k], default_texcoords, sizeof(vec2_t) * 4);
00170         k += sizeof(vec2_t) / sizeof(vec_t) * 4;
00171 
00172         /* and lastly copy the 4 verts */
00173         memcpy(&r_state.vertex_array_3d[l], verts, sizeof(vec3_t) * 4);
00174         l += sizeof(vec3_t) / sizeof(vec_t) * 4;
00175     }
00176 
00177     glDrawArrays(GL_QUADS, 0, l / 3);
00178 
00179     glEnable(GL_DEPTH_TEST);
00180 
00181     R_EnableColorArray(qfalse);
00182 
00183     R_Color(NULL);
00184 }

Generated by  doxygen 1.6.2