/* ================== RB_AddFlare This is called at surface tesselation time ================== */ void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t normal ) { int i; flare_t *f, *oldest; vec3_t local; float d = 1; vec4_t eye, clip, normalized, window; backEnd.pc.c_flareAdds++; if(normal && (normal[0] || normal[1] || normal[2])) { VectorSubtract( backEnd.viewParms.or.origin, point, local ); VectorNormalizeFast(local); d = DotProduct(local, normal); // If the viewer is behind the flare don't add it. if(d < 0) return; } // if the point is off the screen, don't bother adding it // calculate screen coordinates and depth R_TransformModelToClip( point, backEnd.or.modelMatrix, backEnd.viewParms.projectionMatrix, eye, clip ); // check to see if the point is completely off screen for ( i = 0 ; i < 3 ; i++ ) { if ( clip[i] >= clip[3] || clip[i] <= -clip[3] ) { return; } } R_TransformClipToWindow( clip, &backEnd.viewParms, normalized, window ); if ( window[0] < 0 || window[0] >= backEnd.viewParms.viewportWidth || window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight ) { return; // shouldn't happen, since we check the clip[] above, except for FP rounding } // see if a flare with a matching surface, scene, and view exists oldest = r_flareStructs; for ( f = r_activeFlares ; f ; f = f->next ) { if ( f->surface == surface && f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal ) { break; } } // allocate a new one if (!f ) { if ( !r_inactiveFlares ) { // the list is completely full return; } f = r_inactiveFlares; r_inactiveFlares = r_inactiveFlares->next; f->next = r_activeFlares; r_activeFlares = f; f->surface = surface; f->frameSceneNum = backEnd.viewParms.frameSceneNum; f->inPortal = backEnd.viewParms.isPortal; f->addedFrame = -1; } if ( f->addedFrame != backEnd.viewParms.frameCount - 1 ) { f->visible = qfalse; f->fadeTime = backEnd.refdef.time - 2000; } f->addedFrame = backEnd.viewParms.frameCount; f->fogNum = fogNum; VectorCopy(point, f->origin); VectorCopy( color, f->color ); // fade the intensity of the flare down as the // light surface turns away from the viewer VectorScale( f->color, d, f->color ); // save info needed to test f->windowX = backEnd.viewParms.viewportX + window[0]; f->windowY = backEnd.viewParms.viewportY + window[1]; f->eyeZ = eye[2]; }
/* ================== RB_AddFlare This is called at surface tesselation time ================== */ void RB_AddFlare(void *surface, vec3_t point, vec3_t color, vec3_t normal) { int i; flare_t *f, *oldest; vec3_t local; vec4_t eye, clip, normalized, window; float distBias = 512.0; float distLerp = 0.5; float d1 = 0.0f, d2 = 0.0f; backEnd.pc.c_flareAdds++; // if the point is off the screen, don't bother adding it // calculate screen coordinates and depth R_TransformModelToClip(point, backEnd.orientation.modelViewMatrix, backEnd.viewParms.projectionMatrix, eye, clip); // check to see if the point is completely off screen for(i = 0; i < 3; i++) { if(clip[i] >= clip[3] || clip[i] <= -clip[3]) { return; } } R_TransformClipToWindow(clip, &backEnd.viewParms, normalized, window); if(window[0] < 0 || window[0] >= backEnd.viewParms.viewportWidth || window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight) return; // shouldn't happen, since we check the clip[] above, except for FP rounding // see if a flare with a matching surface, scene, and view exists oldest = r_flareStructs; for(f = r_activeFlares; f; f = f->next) { if(f->surface == surface && f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal) break; } // allocate a new one if(!f) { if(!r_inactiveFlares) { // the list is completely full return; } f = r_inactiveFlares; r_inactiveFlares = r_inactiveFlares->next; f->next = r_activeFlares; r_activeFlares = f; f->surface = surface; f->frameSceneNum = backEnd.viewParms.frameSceneNum; f->inPortal = backEnd.viewParms.isPortal; f->addedFrame = -1; } if(f->addedFrame != backEnd.viewParms.frameCount - 1) { f->visible = qfalse; f->fadeTime = backEnd.refdef.time - 2000; } f->addedFrame = backEnd.viewParms.frameCount; VectorCopy(color, f->color); d2 = 0.0; d2 = -eye[2]; if(d2 > distBias) { if(d2 > (distBias * 2.0)) d2 = (distBias * 2.0); d2 -= distBias; d2 = 1.0 - (d2 * (1.0 / distBias)); d2 *= distLerp; } else { d2 = distLerp; } // fade the intensity of the flare down as the // light surface turns away from the viewer if(normal) { VectorSubtract(backEnd.viewParms.orientation.origin, point, local); VectorNormalize(local); d1 = DotProduct(local, normal); d1 *= (1.0 - distLerp); d1 += d2; } VectorScale(f->color, d1, f->color); // save info needed to test f->windowX = backEnd.viewParms.viewportX + window[0]; f->windowY = backEnd.viewParms.viewportY + window[1]; f->eyeZ = eye[2]; }
/* ================== RB_AddFlare This is called at surface tesselation time ================== */ void RB_AddFlare(void *surface, int fogNum, vec3_t point, vec3_t color, float scale, vec3_t normal, int id, qboolean cgvisible) // added scale. added id. added visible { int i; flare_t *f; vec3_t local; vec4_t eye, clip, normalized, window; backEnd.pc.c_flareAdds++; // if the point is off the screen, don't bother adding it // calculate screen coordinates and depth R_TransformModelToClip(point, backEnd.orientation.modelMatrix, backEnd.viewParms.projectionMatrix, eye, clip); //Ren_Print("src: %f %f %f \n", point[0], point[1], point[2]); //Ren_Print("eye: %f %f %f %f\n", eye[0], eye[1], eye[2], eye[3]); // check to see if the point is completely off screen for (i = 0 ; i < 3 ; i++) { if (clip[i] >= clip[3] || clip[i] <= -clip[3]) { return; } } R_TransformClipToWindow(clip, &backEnd.viewParms, normalized, window); //Ren_Print("window: %f %f %f \n", window[0], window[1], window[2]); if (window[0] < 0 || window[0] >= backEnd.viewParms.viewportWidth || window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight) { return; // shouldn't happen, since we check the clip[] above, except for FP rounding } // see if a flare with a matching surface, scene, and view exists for (f = r_activeFlares ; f ; f = f->next) { // added back in more checks for different scenes if (f->id == id && f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal) { break; } } // allocate a new one if (!f) { if (!r_inactiveFlares) { // the list is completely full return; } f = r_inactiveFlares; r_inactiveFlares = r_inactiveFlares->next; f->next = r_activeFlares; r_activeFlares = f; f->surface = surface; f->frameSceneNum = backEnd.viewParms.frameSceneNum; f->inPortal = backEnd.viewParms.isPortal; f->addedFrame = -1; f->id = id; } f->cgvisible = cgvisible; if (f->addedFrame != backEnd.viewParms.frameCount - 1) { f->visible = qfalse; f->fadeTime = backEnd.refdef.time - 2000; } f->addedFrame = backEnd.viewParms.frameCount; f->fogNum = fogNum; VectorCopy(color, f->color); f->scale = scale; // fade the intensity of the flare down as the // light surface turns away from the viewer if (normal) { float d; VectorSubtract(backEnd.viewParms.orientation.origin, point, local); VectorNormalizeFast(local); d = DotProduct(local, normal); VectorScale(f->color, d, f->color); } // save info needed to test f->windowX = backEnd.viewParms.viewportX + window[0]; f->windowY = backEnd.viewParms.viewportY + window[1]; f->eyeZ = eye[2]; }
void RB_AddFlare(srfFlare_t *surface, int fogNum, vec3_t point, vec3_t color, vec3_t normal, int radii, int efftype, float scaled, int type) { int i; flare_t *f, *oldest; vec3_t local; float d = 1; vec4_t eye, clip, normalized, window; backEnd.pc.c_flareAdds++; // fade the intensity of the flare down as the // light surface turns away from the viewer if(normal && (normal[0] || normal[1] || normal[2]) ) { VectorSubtract( backEnd.viewParms.or.origin, point, local ); VectorNormalizeFast(local); d = DotProduct(local, normal); // If the viewer is behind the flare don't add it. if(d < 0) return; } flaredsize = backEnd.viewParms.viewportHeight; R_TransformModelToClip( point, backEnd.or.modelMatrix, backEnd.viewParms.projectionMatrix, eye, clip ); // check to see if the point is completely off screen for ( i = 0 ; i < 3 ; i++ ) { if ( clip[i] >= clip[3] || clip[i] <= -clip[3] ) { return; } } R_TransformClipToWindow( clip, &backEnd.viewParms, normalized, window ); if ( window[0] < 0 || window[0] >= backEnd.viewParms.viewportWidth || window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight ) { return; // shouldn't happen, since we check the clip[] above, except for FP rounding } // see if a flare with a matching surface, scene, and view exists oldest = r_flareStructs; for ( f = r_activeFlares ; f ; f = f->next ) { if ( f->surface == surface && f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal ) { break; } } // allocate a new one if (!f ) { if ( !r_inactiveFlares ) { // the list is completely full return; } f = r_inactiveFlares; r_inactiveFlares = r_inactiveFlares->next; f->next = r_activeFlares; r_activeFlares = f; f->surface = surface; f->frameSceneNum = backEnd.viewParms.frameSceneNum; f->inPortal = backEnd.viewParms.isPortal; f->addedFrame = -1; } if ( f->addedFrame != backEnd.viewParms.frameCount - 1 ) { f->visible = qfalse; f->fadeTime = backEnd.refdef.time - 2000; } f->addedFrame = backEnd.viewParms.frameCount; f->fogNum = fogNum; f->ftype = efftype; VectorCopy(point, f->origin); VectorCopy( color, f->color ); if ( (r_flaresDlightFade->integer) && (type == 1) ) { // leilei - dynamic light flares fading instantly f->fadeTime = -666; } if (!pvrhack) // leilei - don't do this on powervr VectorScale( f->color, d, f->color ); // save info needed to test f->windowX = backEnd.viewParms.viewportX + window[0]; f->windowY = backEnd.viewParms.viewportY + window[1]; f->radius = radii * scaled * 0.17; f->eyeZ = eye[2]; f->theshader = tr.flareShader; f->type = type; if (f->type == 0) f->theshader = surface->shadder; else f->theshader = tr.flareShader; if ( (type == 1) && (r_flaresDlightScale->value) ) { // leilei - dynamic light flare scale float ef = r_flaresDlightScale->value; if (ef > 1.0f) ef = 1.0f; if (ef < 0.01f) ef = 0.01f; f->radius *= ef; } if ( (type == 1) && (r_flaresDlightOpacity->value) ) { // leilei - dynamic light flare scale float ef = r_flaresDlightOpacity->value; if (ef > 1.0f) ef = 1.0f; if (ef < 0.1f) ef = 0.1f; f->color[0] *= ef; f->color[1] *= ef; f->color[2] *= ef; } // if ( (r_flaresDlightShrink->integer) && (type == 1) ) // leilei - dynamic light flares shrinking when close // { // } }