00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "tr_local.h"
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 typedef struct flare_s {
00061 struct flare_s *next;
00062
00063 int addedFrame;
00064
00065 qboolean inPortal;
00066 int frameSceneNum;
00067 void *surface;
00068 int fogNum;
00069
00070 int fadeTime;
00071
00072 qboolean visible;
00073 float drawIntensity;
00074
00075 int windowX, windowY;
00076 float eyeZ;
00077
00078 vec3_t color;
00079 } flare_t;
00080
00081 #define MAX_FLARES 128
00082
00083 flare_t r_flareStructs[MAX_FLARES];
00084 flare_t *r_activeFlares, *r_inactiveFlares;
00085
00086
00087
00088
00089
00090
00091 void R_ClearFlares( void ) {
00092 int i;
00093
00094 Com_Memset( r_flareStructs, 0, sizeof( r_flareStructs ) );
00095 r_activeFlares = NULL;
00096 r_inactiveFlares = NULL;
00097
00098 for ( i = 0 ; i < MAX_FLARES ; i++ ) {
00099 r_flareStructs[i].next = r_inactiveFlares;
00100 r_inactiveFlares = &r_flareStructs[i];
00101 }
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t normal ) {
00113 int i;
00114 flare_t *f, *oldest;
00115 vec3_t local;
00116 float d;
00117 vec4_t eye, clip, normalized, window;
00118
00119 backEnd.pc.c_flareAdds++;
00120
00121
00122
00123 R_TransformModelToClip( point, backEnd.or.modelMatrix,
00124 backEnd.viewParms.projectionMatrix, eye, clip );
00125
00126
00127 for ( i = 0 ; i < 3 ; i++ ) {
00128 if ( clip[i] >= clip[3] || clip[i] <= -clip[3] ) {
00129 return;
00130 }
00131 }
00132
00133 R_TransformClipToWindow( clip, &backEnd.viewParms, normalized, window );
00134
00135 if ( window[0] < 0 || window[0] >= backEnd.viewParms.viewportWidth
00136 || window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight ) {
00137 return;
00138 }
00139
00140
00141 oldest = r_flareStructs;
00142 for ( f = r_activeFlares ; f ; f = f->next ) {
00143 if ( f->surface == surface && f->frameSceneNum == backEnd.viewParms.frameSceneNum
00144 && f->inPortal == backEnd.viewParms.isPortal ) {
00145 break;
00146 }
00147 }
00148
00149
00150 if (!f ) {
00151 if ( !r_inactiveFlares ) {
00152
00153 return;
00154 }
00155 f = r_inactiveFlares;
00156 r_inactiveFlares = r_inactiveFlares->next;
00157 f->next = r_activeFlares;
00158 r_activeFlares = f;
00159
00160 f->surface = surface;
00161 f->frameSceneNum = backEnd.viewParms.frameSceneNum;
00162 f->inPortal = backEnd.viewParms.isPortal;
00163 f->addedFrame = -1;
00164 }
00165
00166 if ( f->addedFrame != backEnd.viewParms.frameCount - 1 ) {
00167 f->visible = qfalse;
00168 f->fadeTime = backEnd.refdef.time - 2000;
00169 }
00170
00171 f->addedFrame = backEnd.viewParms.frameCount;
00172 f->fogNum = fogNum;
00173
00174 VectorCopy( color, f->color );
00175
00176
00177
00178 if ( normal ) {
00179 VectorSubtract( backEnd.viewParms.or.origin, point, local );
00180 VectorNormalizeFast( local );
00181 d = DotProduct( local, normal );
00182 VectorScale( f->color, d, f->color );
00183 }
00184
00185
00186 f->windowX = backEnd.viewParms.viewportX + window[0];
00187 f->windowY = backEnd.viewParms.viewportY + window[1];
00188
00189 f->eyeZ = eye[2];
00190 }
00191
00192
00193
00194
00195
00196
00197 void RB_AddDlightFlares( void ) {
00198 dlight_t *l;
00199 int i, j, k;
00200 fog_t *fog;
00201
00202 if ( !r_flares->integer ) {
00203 return;
00204 }
00205
00206 l = backEnd.refdef.dlights;
00207 fog = tr.world->fogs;
00208 for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) {
00209
00210
00211 for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
00212 fog = &tr.world->fogs[j];
00213 for ( k = 0 ; k < 3 ; k++ ) {
00214 if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) {
00215 break;
00216 }
00217 }
00218 if ( k == 3 ) {
00219 break;
00220 }
00221 }
00222 if ( j == tr.world->numfogs ) {
00223 j = 0;
00224 }
00225
00226 RB_AddFlare( (void *)l, j, l->origin, l->color, NULL );
00227 }
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 void RB_TestFlare( flare_t *f ) {
00244 float depth;
00245 qboolean visible;
00246 float fade;
00247 float screenZ;
00248
00249 backEnd.pc.c_flareTests++;
00250
00251
00252
00253 glState.finishCalled = qfalse;
00254
00255
00256 qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
00257
00258 screenZ = backEnd.viewParms.projectionMatrix[14] /
00259 ( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
00260
00261 visible = ( -f->eyeZ - -screenZ ) < 24;
00262
00263 if ( visible ) {
00264 if ( !f->visible ) {
00265 f->visible = qtrue;
00266 f->fadeTime = backEnd.refdef.time - 1;
00267 }
00268 fade = ( ( backEnd.refdef.time - f->fadeTime ) /1000.0f ) * r_flareFade->value;
00269 } else {
00270 if ( f->visible ) {
00271 f->visible = qfalse;
00272 f->fadeTime = backEnd.refdef.time - 1;
00273 }
00274 fade = 1.0f - ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
00275 }
00276
00277 if ( fade < 0 ) {
00278 fade = 0;
00279 }
00280 if ( fade > 1 ) {
00281 fade = 1;
00282 }
00283
00284 f->drawIntensity = fade;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 void RB_RenderFlare( flare_t *f ) {
00294 float size;
00295 vec3_t color;
00296 int iColor[3];
00297
00298 backEnd.pc.c_flareRenders++;
00299
00300 VectorScale( f->color, f->drawIntensity*tr.identityLight, color );
00301 iColor[0] = color[0] * 255;
00302 iColor[1] = color[1] * 255;
00303 iColor[2] = color[2] * 255;
00304
00305 size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / -f->eyeZ );
00306
00307 RB_BeginSurface( tr.flareShader, f->fogNum );
00308
00309
00310 tess.xyz[tess.numVertexes][0] = f->windowX - size;
00311 tess.xyz[tess.numVertexes][1] = f->windowY - size;
00312 tess.texCoords[tess.numVertexes][0][0] = 0;
00313 tess.texCoords[tess.numVertexes][0][1] = 0;
00314 tess.vertexColors[tess.numVertexes][0] = iColor[0];
00315 tess.vertexColors[tess.numVertexes][1] = iColor[1];
00316 tess.vertexColors[tess.numVertexes][2] = iColor[2];
00317 tess.vertexColors[tess.numVertexes][3] = 255;
00318 tess.numVertexes++;
00319
00320 tess.xyz[tess.numVertexes][0] = f->windowX - size;
00321 tess.xyz[tess.numVertexes][1] = f->windowY + size;
00322 tess.texCoords[tess.numVertexes][0][0] = 0;
00323 tess.texCoords[tess.numVertexes][0][1] = 1;
00324 tess.vertexColors[tess.numVertexes][0] = iColor[0];
00325 tess.vertexColors[tess.numVertexes][1] = iColor[1];
00326 tess.vertexColors[tess.numVertexes][2] = iColor[2];
00327 tess.vertexColors[tess.numVertexes][3] = 255;
00328 tess.numVertexes++;
00329
00330 tess.xyz[tess.numVertexes][0] = f->windowX + size;
00331 tess.xyz[tess.numVertexes][1] = f->windowY + size;
00332 tess.texCoords[tess.numVertexes][0][0] = 1;
00333 tess.texCoords[tess.numVertexes][0][1] = 1;
00334 tess.vertexColors[tess.numVertexes][0] = iColor[0];
00335 tess.vertexColors[tess.numVertexes][1] = iColor[1];
00336 tess.vertexColors[tess.numVertexes][2] = iColor[2];
00337 tess.vertexColors[tess.numVertexes][3] = 255;
00338 tess.numVertexes++;
00339
00340 tess.xyz[tess.numVertexes][0] = f->windowX + size;
00341 tess.xyz[tess.numVertexes][1] = f->windowY - size;
00342 tess.texCoords[tess.numVertexes][0][0] = 1;
00343 tess.texCoords[tess.numVertexes][0][1] = 0;
00344 tess.vertexColors[tess.numVertexes][0] = iColor[0];
00345 tess.vertexColors[tess.numVertexes][1] = iColor[1];
00346 tess.vertexColors[tess.numVertexes][2] = iColor[2];
00347 tess.vertexColors[tess.numVertexes][3] = 255;
00348 tess.numVertexes++;
00349
00350 tess.indexes[tess.numIndexes++] = 0;
00351 tess.indexes[tess.numIndexes++] = 1;
00352 tess.indexes[tess.numIndexes++] = 2;
00353 tess.indexes[tess.numIndexes++] = 0;
00354 tess.indexes[tess.numIndexes++] = 2;
00355 tess.indexes[tess.numIndexes++] = 3;
00356
00357 RB_EndSurface();
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 void RB_RenderFlares (void) {
00377 flare_t *f;
00378 flare_t **prev;
00379 qboolean draw;
00380
00381 if ( !r_flares->integer ) {
00382 return;
00383 }
00384
00385
00386
00387
00388 draw = qfalse;
00389 prev = &r_activeFlares;
00390 while ( ( f = *prev ) != NULL ) {
00391
00392 if ( f->addedFrame < backEnd.viewParms.frameCount - 1 ) {
00393 *prev = f->next;
00394 f->next = r_inactiveFlares;
00395 r_inactiveFlares = f;
00396 continue;
00397 }
00398
00399
00400 f->drawIntensity = 0;
00401 if ( f->frameSceneNum == backEnd.viewParms.frameSceneNum
00402 && f->inPortal == backEnd.viewParms.isPortal ) {
00403 RB_TestFlare( f );
00404 if ( f->drawIntensity ) {
00405 draw = qtrue;
00406 } else {
00407
00408 *prev = f->next;
00409 f->next = r_inactiveFlares;
00410 r_inactiveFlares = f;
00411 continue;
00412 }
00413 }
00414
00415 prev = &f->next;
00416 }
00417
00418 if ( !draw ) {
00419 return;
00420 }
00421
00422 if ( backEnd.viewParms.isPortal ) {
00423 qglDisable (GL_CLIP_PLANE0);
00424 }
00425
00426 qglPushMatrix();
00427 qglLoadIdentity();
00428 qglMatrixMode( GL_PROJECTION );
00429 qglPushMatrix();
00430 qglLoadIdentity();
00431 qglOrtho( backEnd.viewParms.viewportX, backEnd.viewParms.viewportX + backEnd.viewParms.viewportWidth,
00432 backEnd.viewParms.viewportY, backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight,
00433 -99999, 99999 );
00434
00435 for ( f = r_activeFlares ; f ; f = f->next ) {
00436 if ( f->frameSceneNum == backEnd.viewParms.frameSceneNum
00437 && f->inPortal == backEnd.viewParms.isPortal
00438 && f->drawIntensity ) {
00439 RB_RenderFlare( f );
00440 }
00441 }
00442
00443 qglPopMatrix();
00444 qglMatrixMode( GL_MODELVIEW );
00445 qglPopMatrix();
00446 }
00447