/* * R_CullModel */ int R_CullModel( entity_t *e, vec3_t mins, vec3_t maxs, float radius ) { if( e->flags & RF_WEAPONMODEL ) { if( ri.params & RP_NONVIEWERREF ) return 1; return 0; } if( e->flags & RF_VIEWERMODEL ) { //if( !(ri.params & RP_NONVIEWERREF) ) if( !( ri.params & ( RP_MIRRORVIEW|RP_SHADOWMAPVIEW ) ) ) return 1; } // account for possible outlines #ifdef HARDWARE_OUTLINES if( e->outlineHeight ) radius += e->outlineHeight * r_outlines_scale->value * 1.73/*sqrt(3)*/; #endif if( R_CullSphere( e->origin, radius, ri.clipFlags ) ) return 1; if( ri.params & RP_PVSCULL ) { if( R_VisCullSphere( e->origin, radius ) ) return 2; } return 0; }
bool C_Func_LOD::LODTest() { if(!lod_Enable.GetInt()) return true; float transitionDist = m_fDisappearDist; float disappearDist = m_fDisappearDist + lod_TransitionDist.GetFloat(); float dist = (CurrentViewOrigin() - WorldSpaceCenter()).Length(); if(dist < transitionDist) { // Always visible between 0 and transitionDist. m_LastRegion = Visible; m_bLastDrawn = true; } else if(dist < disappearDist) { // In the transition range. First, figure out if we want to transition at all. bool bTransition = false; // See if they're rotating their view fast enough. if(r_DoCovertTransitions.GetInt()) { bTransition = true; } else { // FIXME: Should we use the surrounding box here? // Since this is a brushmodel which isn't rotating, it should be close enough... Vector vCenter = (WorldSpaceSurroundingMins() + WorldSpaceSurroundingMaxs()) * 0.5f; float radius = (WorldSpaceSurroundingMaxs() - vCenter).Length(); bTransition = R_CullSphere(view->GetFrustum(), 5, &vCenter, radius); } if(bTransition) { // Ok, do the transition while they're not looking. if(m_LastRegion == Visible && m_bLastDrawn) { // Make it invisible. m_bLastDrawn = false; } else if(m_LastRegion == Invisible && !m_bLastDrawn) { // Make it visible. m_bLastDrawn = true; } } } else { // Never visible from disappearDist+. m_LastRegion = Invisible; m_bLastDrawn = false; } return m_bLastDrawn; }
/* * R_CullModelEntity */ int R_CullModelEntity( const entity_t *e, vec3_t mins, vec3_t maxs, float radius, bool sphereCull, bool pvsCull ) { if( e->flags & RF_NOSHADOW ) { if( rn.renderFlags & RF_SHADOWMAPVIEW ) return 3; } if( e->flags & RF_WEAPONMODEL ) { if( rn.renderFlags & RF_NONVIEWERREF ) return 1; return 0; } if( e->flags & RF_VIEWERMODEL ) { //if( !(rn.renderFlags & RF_NONVIEWERREF) ) if( !( rn.renderFlags & ( RF_MIRRORVIEW|RF_SHADOWMAPVIEW ) ) ) return 1; } if( e->flags & RF_NODEPTHTEST ) return 0; // account for possible outlines if( e->outlineHeight ) radius += e->outlineHeight * r_outlines_scale->value * 1.73/*sqrt(3)*/; if( sphereCull ) { if( R_CullSphere( e->origin, radius, rn.clipFlags ) ) return 1; } else { if( R_CullBox( mins, maxs, rn.clipFlags ) ) return 1; } if( pvsCull ) { if( sphereCull ) { if( R_VisCullSphere( e->origin, radius ) ) return 2; } else { if( R_VisCullBox( mins, maxs ) ) return 2; } } return 0; }
/* ============= R_CullModel ============= */ bool R_CullModel( cl_entity_t *e, const Vector &origin, const Vector &mins, const Vector &maxs, float radius ) { if( e == GET_VIEWMODEL( )) { if( RI.params & RP_NONVIEWERREF ) return true; return false; } // don't reflect this entity in mirrors if( e->curstate.effects & EF_NOREFLECT && RI.params & RP_MIRRORVIEW ) return true; // draw only in mirrors if( e->curstate.effects & EF_REFLECTONLY && !( RI.params & RP_MIRRORVIEW )) return true; // never draw playermodel for himself flashlight while shadowpass is active if( RI.params & RP_SHADOWVIEW && RI.currentlight != NULL ) { if( UTIL_IsLocal( e->index ) && UTIL_IsLocal( RI.currentlight->key )) return true; } if( RP_LOCALCLIENT( e )) { if( RI.params & RP_FORCE_NOPLAYER ) return true; if( !RI.thirdPerson && UTIL_IsLocal( RI.refdef.viewentity )) { // player can view himself from the portal camera if(!( RI.params & ( RP_MIRRORVIEW|RP_PORTALVIEW|RP_SCREENVIEW|RP_SHADOWVIEW ))) return true; } } if( R_CullSphere( origin, radius, RI.clipFlags )) return true; if( RI.params & ( RP_SKYPORTALVIEW|RP_PORTALVIEW )) { if( R_VisCullSphere( e->origin, radius )) return true; } return false; }
/* * R_CullBrushModel */ qboolean R_CullBrushModel( entity_t *e ) { qboolean rotated; vec3_t mins, maxs; float radius; model_t *model = e->model; mbrushmodel_t *bmodel = ( mbrushmodel_t * )model->extradata; if( bmodel->nummodelsurfaces == 0 ) return qtrue; radius = R_BrushModelBBox( e, mins, maxs, &rotated ); if( rotated ) { if( R_CullSphere( e->origin, radius, ri.clipFlags ) ) return qtrue; } else { if( R_CullBox( mins, maxs, ri.clipFlags ) ) return qtrue; } if( ri.params & RP_PVSCULL ) { if( rotated ) { if( R_VisCullSphere( e->origin, radius ) ) return qtrue; } else { if( R_VisCullBox( mins, maxs ) ) return qtrue; } } return qfalse; }
void CGlowOverlay::Draw( bool bCacheFullSceneState ) { extern ConVar r_drawsprites; if( !r_drawsprites.GetBool() ) return; // Get the vector to the sun. Vector vToGlow; if( m_bDirectional ) vToGlow = m_vDirection; else vToGlow = m_vPos - CurrentViewOrigin(); VectorNormalize( vToGlow ); float flDot = vToGlow.Dot( CurrentViewForward() ); UpdateGlowObstruction( vToGlow, bCacheFullSceneState ); if( m_flGlowObstructionScale == 0 ) return; bool bWireframe = ShouldDrawInWireFrameMode() || (r_drawsprites.GetInt() == 2); CMatRenderContextPtr pRenderContext( materials ); for( int iSprite=0; iSprite < m_nSprites; iSprite++ ) { CGlowSprite *pSprite = &m_Sprites[iSprite]; // Figure out the color and size to draw it. float flHorzSize, flVertSize; Vector vColor; CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor ); // If we're alpha'd out, then don't bother if ( vColor.LengthSqr() < 0.00001f ) continue; // Setup the basis to draw the sprite. Vector vBasePt, vUp, vRight; CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight ); //Get our diagonal radius float radius = (vRight+vUp).Length(); if ( R_CullSphere( view->GetFrustum(), 5, &vBasePt, radius ) ) continue; // Get our material (deferred default load) if ( m_Sprites[iSprite].m_pMaterial == NULL ) { m_Sprites[iSprite].m_pMaterial = materials->FindMaterial( "sprites/light_glow02_add_noz", TEXTURE_GROUP_CLIENT_EFFECTS ); } Assert( m_Sprites[iSprite].m_pMaterial ); static unsigned int nHDRColorScaleCache = 0; IMaterialVar *pHDRColorScaleVar = m_Sprites[iSprite].m_pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache ); if( pHDRColorScaleVar ) { pHDRColorScaleVar->SetFloatValue( m_flHDRColorScale ); } // Draw the sprite. IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, m_Sprites[iSprite].m_pMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 0 ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 0 ); builder.AdvanceVertex(); builder.End( false, true ); if( bWireframe ) { IMaterial *pWireframeMaterial = materials->FindMaterial( "debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER ); pRenderContext->Bind( pWireframeMaterial ); // Draw the sprite. IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pWireframeMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); builder.End( false, true ); } } }
bool CParticleSystem :: ParticleIsVisible( CParticle *part ) { if( R_CullSphere( part->origin, part->m_fSize + 1, RI.clipFlags )) return false; return true; }
/* * R_DrawWorld */ void R_DrawWorld( void ) { unsigned int i; int clipFlags, msec = 0; unsigned int dlightBits; unsigned int shadowBits; bool worldOutlines; if( !r_drawworld->integer ) return; if( !rsh.worldModel ) return; if( rn.renderFlags & RF_SHADOWMAPVIEW ) return; VectorCopy( rn.refdef.vieworg, modelOrg ); worldOutlines = mapConfig.forceWorldOutlines || ( rn.refdef.rdflags & RDF_WORLDOUTLINES ); if( worldOutlines && (rf.viewcluster != -1) && r_outlines_scale->value > 0 ) rsc.worldent->outlineHeight = max( 0.0f, r_outlines_world->value ); else rsc.worldent->outlineHeight = 0; Vector4Copy( mapConfig.outlineColor, rsc.worldent->outlineColor ); clipFlags = rn.clipFlags; dlightBits = 0; shadowBits = 0; if( r_nocull->integer ) clipFlags = 0; // cull dynamic lights if( !( rn.renderFlags & RF_ENVVIEW ) ) { if( r_dynamiclight->integer == 1 && !r_fullbright->integer ) { for( i = 0; i < rsc.numDlights; i++ ) { if( R_CullSphere( rsc.dlights[i].origin, rsc.dlights[i].intensity, clipFlags ) ) { continue; } dlightBits |= 1<<i; } } } // cull shadowmaps if( !( rn.renderFlags & RF_ENVVIEW ) ) { for( i = 0; i < rsc.numShadowGroups; i++ ) { shadowGroup_t *grp = rsc.shadowGroups + i; if( R_CullBox( grp->visMins, grp->visMaxs, clipFlags ) ) { continue; } shadowBits |= grp->bit; } } rn.dlightBits = dlightBits; rn.shadowBits = shadowBits; if( r_speeds->integer ) msec = ri.Sys_Milliseconds(); R_RecursiveWorldNode( rsh.worldBrushModel->nodes, clipFlags, dlightBits, shadowBits ); if( r_speeds->integer ) rf.stats.t_world_node += ri.Sys_Milliseconds() - msec; }
void SCR_SetupAutoID (void) { int i, view[4]; float model[16], project[16], winz, *origin; entity_t *state; autoid_player_t *id; vec3_t OurViewPoint; vec3_t ThisClientPoint; vec3_t stop; vec3_t edist; void TraceLine (vec3_t start, vec3_t end, vec3_t impact); autoid_count = 0; if (!scr_autoid.value || cls.state != ca_connected || !cls.demoplayback) return; glGetFloatv (GL_MODELVIEW_MATRIX, model); glGetFloatv (GL_PROJECTION_MATRIX, project); glGetIntegerv (GL_VIEWPORT, view); for (i = 0 ; i < cl.maxclients ; i++) { state = &cl_entities[1+i]; if (!state->model->name) // NULL model continue; if (!(state->modelindex == cl_modelindex[mi_player])) // Not a player model continue; if (ISDEAD(state->frame)) // Dead continue; // if (strcmp(state->model->name, "progs/player.mdl")) // continue; if (R_CullSphere(state->origin, 0)) continue; // Logic // Fill in one value with our viewpoint and the next value with target // Do traceline VectorCopy (r_refdef.vieworg, OurViewPoint); VectorCopy (state->origin, ThisClientPoint); TraceLine (OurViewPoint, ThisClientPoint, stop); if (stop[0] != 0 || stop[1] != 0 || stop[2] != 0) // Quick and dirty traceline continue; #if 1 if (!CL_Visible_To_Client(OurViewPoint, ThisClientPoint)) { // We can't see it //Con_Printf("Cannot see it\n"); continue; } #endif id = &autoids[autoid_count]; id->player = &cl.scores[i]; #if 0 Con_Printf("Player %s\n", id->player->name); // Print name of seen player Con_Printf("Client num %i\n", i); Con_Printf("modelname is %s\n", state->model->name); Con_Printf("modelindex is %i\n", state->modelindex); //Con_Printf("modelname char one is %i\n", state->model->name[0]); Con_Printf("playermodel index is %i\n", cl_modelindex[mi_player]); #endif origin = state->origin; if (qglProject(origin[0], origin[1], origin[2] + 28, model, project, view, &id->x, &id->y, &winz)) autoid_count++; } }