00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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))
00033 return;
00034
00035 surf->flare = (mBspFlare_t *) Mem_PoolAlloc(sizeof(*surf->flare), vid_modelPool, 0);
00036
00037
00038 VectorMA(surf->center, 2, surf->normal, surf->flare->origin);
00039
00040
00041 VectorSubtract(surf->maxs, surf->mins, span);
00042 surf->flare->radius = VectorLength(span);
00043
00044 s = m->stages;
00045 for (;;) {
00046 if (s->flags & STAGE_FLARE)
00047 break;
00048 s = s->next;
00049 }
00050
00051
00052 if (s->flags & STAGE_COLOR)
00053 VectorCopy(s->color, surf->flare->color);
00054 else
00055 VectorCopy(surf->color, surf->flare->color);
00056
00057
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
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
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
00116 if (refdef.time - f->time > 0.02) {
00117 if (refdef.time - f->time > 0.5)
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);
00124
00125 if (f->alpha > 0.75)
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
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
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++) {
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
00169 memcpy(&texunit_diffuse.texcoord_array[k], default_texcoords, sizeof(vec2_t) * 4);
00170 k += sizeof(vec2_t) / sizeof(vec_t) * 4;
00171
00172
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 }