bool TestPointAgainstSurface( Vector const& pt, dface_t* pFace, texinfo_t* pTex ) { // no lightmaps on this surface? punt... // FIXME: should be water surface? if (pTex->flags & SURF_NOLIGHT) return false; // See where in lightmap space our intersection point is float s, t; s = DotProduct (pt.Base(), pTex->lightmapVecsLuxelsPerWorldUnits[0]) + pTex->lightmapVecsLuxelsPerWorldUnits[0][3]; t = DotProduct (pt.Base(), pTex->lightmapVecsLuxelsPerWorldUnits[1]) + pTex->lightmapVecsLuxelsPerWorldUnits[1][3]; // Not in the bounds of our lightmap? punt... if( s < pFace->m_LightmapTextureMinsInLuxels[0] || t < pFace->m_LightmapTextureMinsInLuxels[1] ) return false; // assuming a square lightmap (FIXME: which ain't always the case), // lets see if it lies in that rectangle. If not, punt... float ds = s - pFace->m_LightmapTextureMinsInLuxels[0]; float dt = t - pFace->m_LightmapTextureMinsInLuxels[1]; if( ds > pFace->m_LightmapTextureSizeInLuxels[0] || dt > pFace->m_LightmapTextureSizeInLuxels[1] ) return false; m_LuxelCoord.x = ds; m_LuxelCoord.y = dt; return true; }
void CIntProxy::OnBind( void *pC_BaseEntity ) { Assert( m_pSrc1 && m_pResult ); MaterialVarType_t resultType; int vecSize; ComputeResultType( resultType, vecSize ); switch( resultType ) { case MATERIAL_VAR_TYPE_VECTOR: { Vector a; m_pSrc1->GetVecValue( a.Base(), vecSize ); a[0] = ( float )( int )a[0]; a[1] = ( float )( int )a[1]; a[2] = ( float )( int )a[2]; m_pResult->SetVecValue( a.Base(), vecSize ); } break; case MATERIAL_VAR_TYPE_FLOAT: { float a = m_pSrc1->GetFloatValue(); a = ( float )( int )a; SetFloatResult( a ); } break; case MATERIAL_VAR_TYPE_INT: // don't do anything besides assignment! m_pResult->SetIntValue( m_pSrc1->GetIntValue() ); break; } }
void CEqualsProxy::OnBind( void *pC_BaseEntity ) { Assert( m_pSrc1 && m_pResult ); MaterialVarType_t resultType; int vecSize; ComputeResultType( resultType, vecSize ); switch( resultType ) { case MATERIAL_VAR_TYPE_VECTOR: { Vector a; m_pSrc1->GetVecValue( a.Base(), vecSize ); m_pResult->SetVecValue( a.Base(), vecSize ); } break; case MATERIAL_VAR_TYPE_FLOAT: SetFloatResult( m_pSrc1->GetFloatValue() ); break; case MATERIAL_VAR_TYPE_INT: m_pResult->SetIntValue( m_pSrc1->GetIntValue() ); break; } if ( ToolsEnabled() ) { ToolFramework_RecordMaterialParams( GetMaterial() ); } }
bool CCamoMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { return false; // hack! Need to make sure that the TGA loader has a valid filesystem before trying // to load the camo pattern. #if 0 // set how big our instance data is. SetInstanceDataSize( sizeof( CamoInstanceData_t ) ); #endif // remember what material we belong to. m_pMaterial = pMaterial; // get pointers to material vars. bool found; m_pCamoTextureVar = m_pMaterial->FindVar( "$baseTexture", &found ); if( !found ) { m_pCamoTextureVar = NULL; return false; } ITexture *pCamoTexture = m_pCamoTextureVar->GetTextureValue(); if (pCamoTexture) pCamoTexture->SetTextureRegenerator( &m_TextureRegen ); // Need to get the palettized texture to create the procedural texture from // somewhere. m_pCamoPatternTextureVar = m_pMaterial->FindVar( "$camoPatternTexture", &found ); if( !found ) { m_pCamoTextureVar = NULL; return false; } IMaterialVar *subBoundingBoxMinVar, *subBoundingBoxMaxVar; subBoundingBoxMinVar = m_pMaterial->FindVar( "$camoBoundingBoxMin", &found, false ); if( !found ) { m_SubBoundingBoxMin = Vector( 0.0f, 0.0f, 0.0f ); } else { subBoundingBoxMinVar->GetVecValue( m_SubBoundingBoxMin.Base(), 3 ); } subBoundingBoxMaxVar = m_pMaterial->FindVar( "$camoBoundingBoxMax", &found, false ); if( !found ) { m_SubBoundingBoxMax = Vector( 1.0f, 1.0f, 1.0f ); } else { subBoundingBoxMaxVar->GetVecValue( m_SubBoundingBoxMax.Base(), 3 ); } LoadCamoPattern(); GenerateRandomPointsInNormalizedCube(); return true; }
void CClampProxy::OnBind( void *pC_BaseEntity ) { Assert( m_pSrc1 && m_pResult ); MaterialVarType_t resultType; int vecSize; ComputeResultType( resultType, vecSize ); float flMin = m_Min.GetFloat(); float flMax = m_Max.GetFloat(); if (flMin > flMax) { float flTemp = flMin; flMin = flMax; flMax = flTemp; } switch( resultType ) { case MATERIAL_VAR_TYPE_VECTOR: { Vector a; m_pSrc1->GetVecValue( a.Base(), vecSize ); for (int i = 0; i < vecSize; ++i) { if (a[i] < flMin) a[i] = flMin; else if (a[i] > flMax) a[i] = flMax; } m_pResult->SetVecValue( a.Base(), vecSize ); } break; case MATERIAL_VAR_TYPE_FLOAT: { float src = m_pSrc1->GetFloatValue(); if (src < flMin) src = flMin; else if (src > flMax) src = flMax; SetFloatResult( src ); } break; case MATERIAL_VAR_TYPE_INT: { int src = m_pSrc1->GetIntValue(); if (src < flMin) src = flMin; else if (src > flMax) src = flMax; m_pResult->SetIntValue( src ); } break; } }
static void DispInfo_DrawChainNormals( IDispInfo *pHead ) { #ifndef SWDS #ifdef _DEBUG // Only do it in debug because we're only storing the info then Vector p; materialSystemInterface->Bind( g_pMaterialWireframeVertexColor ); for( IDispInfo *pCur=pHead; pCur; pCur = pCur->GetNextInRenderChain() ) { CDispInfo *pDisp = static_cast<CDispInfo*>( pCur ); int nVerts = pDisp->NumVerts(); IMesh *pMesh = materialSystemInterface->GetDynamicMesh( ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_LINES, nVerts * 3 ); for( int iVert=0; iVert < nVerts; iVert++ ) { CDispRenderVert* pVert = pDisp->GetVertex(iVert); meshBuilder.Position3fv( pVert->m_vPos.Base() ); meshBuilder.Color3ub( 255, 0, 0 ); meshBuilder.AdvanceVertex(); VectorMA( pVert->m_vPos, 5.0f, pVert->m_vNormal, p ); meshBuilder.Position3fv( p.Base() ); meshBuilder.Color3ub( 255, 0, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( pVert->m_vPos.Base() ); meshBuilder.Color3ub( 0, 255, 0 ); meshBuilder.AdvanceVertex(); VectorMA( pVert->m_vPos, 5.0f, pVert->m_vSVector, p ); meshBuilder.Position3fv( p.Base() ); meshBuilder.Color3ub( 0, 255, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( pVert->m_vPos.Base() ); meshBuilder.Color3ub( 0, 0, 255 ); meshBuilder.AdvanceVertex(); VectorMA( pVert->m_vPos, 5.0f, pVert->m_vTVector, p ); meshBuilder.Position3fv( p.Base() ); meshBuilder.Color3ub( 0, 0, 255 ); meshBuilder.AdvanceVertex(); } meshBuilder.End(); pMesh->Draw(); } #endif #endif }
void CLessOrEqualProxy::OnBind( void *pC_BaseEntity ) { Assert( m_pSrc1 && m_pSrc2 && m_pLessVar && m_pGreaterVar && m_pResult ); IMaterialVar *pSourceVar; if (m_pSrc1->GetFloatValue() <= m_pSrc2->GetFloatValue()) { pSourceVar = m_pLessVar; } else { pSourceVar = m_pGreaterVar; } int vecSize = 0; MaterialVarType_t resultType = m_pResult->GetType(); if (resultType == MATERIAL_VAR_TYPE_VECTOR) { if (m_ResultVecComp >= 0) resultType = MATERIAL_VAR_TYPE_FLOAT; vecSize = m_pResult->VectorSize(); } else if (resultType == MATERIAL_VAR_TYPE_UNDEFINED) { resultType = pSourceVar->GetType(); if (resultType == MATERIAL_VAR_TYPE_VECTOR) { vecSize = pSourceVar->VectorSize(); } } switch( resultType ) { case MATERIAL_VAR_TYPE_VECTOR: { Vector src; pSourceVar->GetVecValue( src.Base(), vecSize ); m_pResult->SetVecValue( src.Base(), vecSize ); } break; case MATERIAL_VAR_TYPE_FLOAT: SetFloatResult( pSourceVar->GetFloatValue() ); break; case MATERIAL_VAR_TYPE_INT: m_pResult->SetFloatValue( pSourceVar->GetIntValue() ); break; } if ( ToolsEnabled() ) { ToolFramework_RecordMaterialParams( GetMaterial() ); } }
// Render a quad on the screen where you pass in color and size. // Normal is random and "flutters" inline void RenderParticle_ColorSizePerturbNormal( ParticleDraw* pDraw, const Vector &pos, const Vector &color, const float alpha, const float size ) { // Don't render totally transparent particles. if( alpha < 0.001f ) return; CMeshBuilder *pBuilder = pDraw->GetMeshBuilder(); if( !pBuilder ) return; unsigned char ubColor[4]; ubColor[0] = (unsigned char)RoundFloatToInt( color.x * 254.9f ); ubColor[1] = (unsigned char)RoundFloatToInt( color.y * 254.9f ); ubColor[2] = (unsigned char)RoundFloatToInt( color.z * 254.9f ); ubColor[3] = (unsigned char)RoundFloatToInt( alpha * 254.9f ); Vector vNorm; vNorm.Random( -1.0f, 1.0f ); // Add the 4 corner vertices. pBuilder->Position3f( pos.x-size, pos.y-size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 0, 1.0f ); pBuilder->AdvanceVertex(); pBuilder->Position3f( pos.x-size, pos.y+size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 0, 0 ); pBuilder->AdvanceVertex(); pBuilder->Position3f( pos.x+size, pos.y+size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 1.0f, 0 ); pBuilder->AdvanceVertex(); pBuilder->Position3f( pos.x+size, pos.y-size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 1.0f, 1.0f ); pBuilder->AdvanceVertex(); }
static void DrawExtrusionFace( const Vector& start, const Vector& end, Vector* pts, int idx1, int idx2, CMeshBuilder& meshBuilder ) { Vector temp; VectorAdd( pts[idx1], start, temp ); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); VectorAdd( pts[idx2], start, temp ); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); VectorAdd( pts[idx2], end, temp ); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); VectorAdd( pts[idx1], end, temp ); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); VectorAdd( pts[idx1], start, temp ); meshBuilder.Position3fv( temp.Base() ); meshBuilder.AdvanceVertex(); }
Activity CBaseHL2MPBludgeonWeapon::ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner ) { int i, j, k; float distance; const float *minmaxs[2] = {mins.Base(), maxs.Base()}; trace_t tmpTrace; Vector vecHullEnd = hitTrace.endpos; Vector vecEnd; distance = 1e6f; Vector vecSrc = hitTrace.startpos; vecHullEnd = vecSrc + ((vecHullEnd - vecSrc)*2); UTIL_TraceLine( vecSrc, vecHullEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &tmpTrace ); if ( tmpTrace.fraction == 1.0 ) { for ( i = 0; i < 2; i++ ) { for ( j = 0; j < 2; j++ ) { for ( k = 0; k < 2; k++ ) { vecEnd.x = vecHullEnd.x + minmaxs[i][0]; vecEnd.y = vecHullEnd.y + minmaxs[j][1]; vecEnd.z = vecHullEnd.z + minmaxs[k][2]; UTIL_TraceLine( vecSrc, vecEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &tmpTrace ); if ( tmpTrace.fraction < 1.0 ) { float thisDistance = (tmpTrace.endpos - vecSrc).Length(); if ( thisDistance < distance ) { hitTrace = tmpTrace; distance = thisDistance; } } } } } } else { hitTrace = tmpTrace; } return ACT_VM_HITCENTER; }
void HSV_Select_SV::Paint() { surface()->DrawSetTexture(m_iMat); surface()->DrawSetColor(Color(255, 255, 255, 255)); int x, y, sx, sy; GetBounds(x, y, sx, sy); Vertex_t points[4]; points[0].m_TexCoord.Init(0, 0); points[1].m_TexCoord.Init(1, 0); points[2].m_TexCoord.Init(1, 1); points[3].m_TexCoord.Init(0, 1); IMaterial *pMatColorpicker = materials->FindMaterial("vgui/colorpicker", TEXTURE_GROUP_OTHER); if (IsErrorMaterial(pMatColorpicker)) return; bool bFound = false; IMaterialVar *pVar_00 = pMatColorpicker->FindVar("$COLOR_00", &bFound); IMaterialVar *pVar_10 = pMatColorpicker->FindVar("$COLOR_10", &bFound); IMaterialVar *pVar_11 = pMatColorpicker->FindVar("$COLOR_11", &bFound); IMaterialVar *pVar_01 = pMatColorpicker->FindVar("$COLOR_01", &bFound); if (!bFound) return; Vector col; HSV2RGB(m_flH, 1, 1, col); pVar_00->SetVecValue(1, 1, 1); pVar_10->SetVecValue(col.Base(), 3); pVar_11->SetVecValue(0, 0, 0); pVar_01->SetVecValue(0, 0, 0); surface()->DrawTexturedRect(0, 0, sx, sy); }
void DrawFastSphere( CMeshBuilder &meshBuilder, const Vector ¢er, float radius, int r, int g, int b ) { int i; int offset = meshBuilder.GetCurrentVertex(); Vector pos; for (i = 0; i < 51; i++) { pos.x = g_FastSpherePosData[i][0] + center.x + g_FastSpherePosData[i][5] * radius; pos.y = g_FastSpherePosData[i][1] + center.y + g_FastSpherePosData[i][6] * radius; pos.z = g_FastSpherePosData[i][2] + center.z + g_FastSpherePosData[i][7] * radius; meshBuilder.Position3fv( pos.Base() ); meshBuilder.Normal3fv( &g_FastSpherePosData[i][5] ); meshBuilder.TexCoord2fv( 0, &g_FastSpherePosData[i][3] ); meshBuilder.Color3ub( 255, 255, 255 ); meshBuilder.AdvanceVertex(); } for (i = 0; i < 84; i++) { meshBuilder.FastIndex( g_FastSphereTriData[i][0] + offset ); meshBuilder.FastIndex( g_FastSphereTriData[i][1] + offset ); meshBuilder.FastIndex( g_FastSphereTriData[i][2] + offset ); } }
// Simple routine to visualize a vector // Assume a unit vector for direction void GL_DrawVector( Vector& origin, Vector& direction, float size, float arrowSize, int r, int g, int b ) { Vector up, right, end, tmp, dot; VectorMA( origin, size, direction, end ); VectorClear( up ); if ( GL_fabs(direction[2]) > 0.9 ) up[0] = 1; else up[2] = 1; CrossProduct( direction, up, right ); glDisable( GL_TEXTURE_2D ); glColor3ub( r, g, b ); glBegin( GL_LINES ); glVertex3fv( origin.Base() ); glVertex3fv( end.Base() ); VectorMA( end, -arrowSize, direction, tmp ); VectorMA( tmp, arrowSize, right, dot ); glVertex3fv( end.Base() ); glVertex3fv( dot.Base() ); VectorMA( tmp, -arrowSize, right, dot ); glVertex3fv( end.Base() ); glVertex3fv( dot.Base() ); glEnd(); glEnable( GL_TEXTURE_2D ); }
//------------------------------------------------------------------------------ // Purpose : Create leak effect if material requests it // Input : // Output : //------------------------------------------------------------------------------ void LeakEffect( trace_t &tr ) { Vector diffuseColor, baseColor; Vector vTraceDir = (tr.endpos - tr.startpos); VectorNormalize(vTraceDir); Vector vTraceStart = tr.endpos - 0.1*vTraceDir; Vector vTraceEnd = tr.endpos + 0.1*vTraceDir; IMaterial* pTraceMaterial = engine->TraceLineMaterialAndLighting( vTraceStart, vTraceEnd, diffuseColor, baseColor ); if (!pTraceMaterial) return; bool found; IMaterialVar *pLeakVar = pTraceMaterial->FindVar( "$leakamount", &found, false ); if( !found ) return; C_Splash* pLeak = new C_Splash(); if (!pLeak) return; ClientEntityList().AddNonNetworkableEntity( pLeak->GetIClientUnknown() ); IMaterialVar* pLeakColorVar = pTraceMaterial->FindVar( "$leakcolor", &found ); if (found) { Vector color; pLeakColorVar->GetVecValue(color.Base(),3); pLeak->m_vStartColor = pLeak->m_vEndColor = color; } IMaterialVar* pLeakNoiseVar = pTraceMaterial->FindVar( "$leaknoise", &found ); if (found) { pLeak->m_flNoise = pLeakNoiseVar->GetFloatValue(); } IMaterialVar* pLeakForceVar = pTraceMaterial->FindVar( "$leakforce", &found ); if (found) { float flForce = pLeakForceVar->GetFloatValue(); pLeak->m_flSpeed = flForce; pLeak->m_flSpeedRange = pLeak->m_flNoise * flForce; } pLeak->m_flSpawnRate = pLeakVar->GetFloatValue();; pLeak->m_flParticleLifetime = 10; pLeak->m_flWidthMin = 1; pLeak->m_flWidthMax = 5; pLeak->SetLocalOrigin( tr.endpos ); QAngle angles; VectorAngles( tr.plane.normal, angles ); pLeak->SetLocalAngles( angles ); pLeak->Start(&g_ParticleMgr, NULL); pLeak->m_flStopEmitTime = gpGlobals->curtime+5.0; pLeak->SetNextClientThink(gpGlobals->curtime+20.0); }
//=====================================================================================// // Purpose: This function will check if hit something along the swing animation // I'm not sure how it does it so I'll leave the explanation of this to VALVe ;) //=====================================================================================// void CTDPBludgeonWeaponBase::ChooseIntersectionPointAndActivity( trace_t &tr, const Vector &mins, const Vector &maxs, CTDPPlayer *pPlayer ) { int i, j, k; float lowerDistance = MAX_TRACE_LENGTH; const float *minmaxs[2] = {mins.Base(), maxs.Base()}; trace_t tmptr; Vector vecHullEnd = tr.endpos; Vector vecEnd; Vector vecSrc = tr.startpos; vecHullEnd = vecSrc + ((vecHullEnd - vecSrc)*2); UTIL_TraceLine( vecSrc, vecHullEnd, MASK_SHOT_HULL, pPlayer, COLLISION_GROUP_NONE, &tmptr ); if ( tmptr.fraction == 1.0 ) { for ( i = 0; i < 2; i++ ) { for ( j = 0; j < 2; j++ ) { for ( k = 0; k < 2; k++ ) { vecEnd.x = vecHullEnd.x + minmaxs[i][0]; vecEnd.y = vecHullEnd.y + minmaxs[j][1]; vecEnd.z = vecHullEnd.z + minmaxs[k][2]; UTIL_TraceLine( vecSrc, vecEnd, MASK_SHOT_HULL, pPlayer, COLLISION_GROUP_NONE, &tmptr ); if ( tmptr.fraction < 1.0 ) { float thisDistance = (tmptr.endpos - vecSrc).Length(); if ( thisDistance < lowerDistance ) { tr = tmptr; lowerDistance = thisDistance; } } } } } } else { tr = tmptr; } return; }
//----------------------------------------------------------------------------- // Draw sprite-card based materials //----------------------------------------------------------------------------- void CVMTPreviewPanel::RenderSpriteCard( const Vector &vCenter, float flRadius ) { CMatRenderContextPtr pRenderContext( MaterialSystem() ); IMesh *pMesh = pRenderContext->GetDynamicMesh(); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); // Draw a polygon the size of the panel meshBuilder.Position3fv( vCenter.Base() ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f ); meshBuilder.TexCoord2f( 3, 0, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( vCenter.Base() ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f ); meshBuilder.TexCoord2f( 3, 0, 1 ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( vCenter.Base() ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f ); meshBuilder.TexCoord2f( 3, 1, 1 ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( vCenter.Base() ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f ); meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f ); meshBuilder.TexCoord2f( 3, 1, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
virtual void OnBind( void *pvParticleMgr ) { if( !pvParticleMgr ) return; CParticleMgr *pMgr = (CParticleMgr*)pvParticleMgr; CParticleLightInfo info; pMgr->GetDirectionalLightInfo( info ); // Transform the light into camera space. Vector vTransformedPos = pMgr->GetModelView() * info.m_vPos; if ( m_pLightPosition ) m_pLightPosition->SetVecValue( vTransformedPos.Base(), 3 ); if ( m_pLightColor ) { Vector vTotalColor = info.m_vColor * info.m_flIntensity; m_pLightColor->SetVecValue( vTotalColor.Base(), 3 ); } }
void FX_DrawLine( const Vector &start, const Vector &end, float scale, IMaterial *pMaterial, const color32 &color ) { Vector lineDir, viewDir; //Get the proper orientation for the line VectorSubtract( end, start, lineDir ); VectorSubtract( end, CurrentViewOrigin(), viewDir ); Vector cross = lineDir.Cross( viewDir ); VectorNormalize( cross ); CMatRenderContextPtr pRenderContext( materials ); //Bind the material IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); CMeshBuilder meshBuilder; Vector tmp; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); VectorMA( start, -scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( start, scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( end, scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( end, -scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
void GetBumpNormals( const Vector& sVect, const Vector& tVect, const Vector& flatNormal, const Vector& phongNormal, Vector bumpNormals[NUM_BUMP_VECTS] ) { Vector tmpNormal; bool leftHanded; int i; assert( NUM_BUMP_VECTS == 3 ); // Are we left or right handed? CrossProduct( sVect, tVect, tmpNormal ); if( DotProduct( flatNormal, tmpNormal ) < 0.0f ) { leftHanded = true; } else { leftHanded = false; } // Build a basis for the face around the phong normal matrix3x4_t smoothBasis; CrossProduct( phongNormal.Base(), sVect.Base(), smoothBasis[1] ); VectorNormalize( smoothBasis[1] ); CrossProduct( smoothBasis[1], phongNormal.Base(), smoothBasis[0] ); VectorNormalize( smoothBasis[0] ); VectorCopy( phongNormal.Base(), smoothBasis[2] ); if( leftHanded ) { VectorNegate( smoothBasis[1] ); } // move the g_localBumpBasis into world space to create bumpNormals for( i = 0; i < 3; i++ ) { VectorIRotate( g_localBumpBasis[i], smoothBasis, bumpNormals[i] ); } }
bool Serialize( CUtlBuffer &buf, const Vector &src ) { if ( buf.IsText() ) { SerializeFloats( buf, 3, src.Base() ); } else { buf.PutFloat( src.x ); buf.PutFloat( src.y ); buf.PutFloat( src.z ); } return buf.IsValid(); }
void SEditModelRender::GetModelCenter( float *pFl3_ViewOffset ) { Q_memset( pFl3_ViewOffset, 0, sizeof(float) * 3 ); if ( IsModelReady() ) { MDLCACHE_CRITICAL_SECTION(); if ( pModelInstance->GetModelPtr() ) { const Vector &vecMin = pModelInstance->GetModelPtr()->hull_min(); const Vector &vecMax = pModelInstance->GetModelPtr()->hull_max(); Vector vecPos = ( vecMin + ( vecMax - vecMin ) * 0.5f ); if ( pFl3_ViewOffset ) Q_memcpy( pFl3_ViewOffset, vecPos.Base(), sizeof(float) * 3 ); } } }
void CPlayerPositionProxy::OnBind( void *pC_BaseEntity ) { // Find the player speed.... C_BaseEntity* pPlayer = C_BasePlayer::GetLocalPlayer(); if (!pPlayer) return; // This is actually a vector... Assert( m_pResult ); Vector res; VectorMultiply( pPlayer->WorldSpaceCenter(), m_Factor, res ); m_pResult->SetVecValue( res.Base(), 3 ); if ( ToolsEnabled() ) { ToolFramework_RecordMaterialParams( GetMaterial() ); } }
void GetMaterialReflectivity( MaterialSystemMaterial_t materialHandle, float *reflectivityVect ) { IMaterial *material = ( IMaterial * )materialHandle; const IMaterialVar *reflectivityVar; bool found; reflectivityVar = material->FindVar( "$reflectivity", &found, false ); if( !found ) { Vector tmp; material->GetReflectivity( tmp ); VectorCopy( tmp.Base(), reflectivityVect ); } else { reflectivityVar->GetVecValue( reflectivityVect, 3 ); } }
void CDeferredLight::ClientThink() { if ( m_pLight == NULL ) return; Vector curOrig = GetRenderOrigin(); QAngle curAng = GetRenderAngles(); if ( VectorCompare( curOrig.Base(), m_pLight->pos.Base() ) == 0 || VectorCompare( curAng.Base(), m_pLight->ang.Base() ) == 0 ) { ApplyDataToLight(); if ( m_pLight->flSpotCone_Outer != GetSpotCone_Outer() ) m_pLight->MakeDirtyAll(); else m_pLight->MakeDirtyXForms(); } }
void CMDLPanel::DrawCollisionModel() { vcollide_t *pCollide = MDLCache()->GetVCollide( m_hMDL->GetMDL() ); if ( !pCollide || pCollide->solidCount <= 0 ) return; static color32 color = {255,0,0,0}; IVPhysicsKeyParser *pParser = g_pPhysicsCollision->VPhysicsKeyParserCreate( pCollide->pKeyValues ); CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_hMDL->GetMDL() ), g_pMDLCache ); matrix3x4_t pBoneToWorld[MAXSTUDIOBONES]; matrix3x4_t shapeToWorld; m_pDag->GetTransform()->GetTransform( shapeToWorld ); m_hMDL->SetUpBones( shapeToWorld, MAXSTUDIOBONES, pBoneToWorld ); // PERFORMANCE: Just parse the script each frame. It's fast enough for tools. If you need // this to go faster then cache off the bone index mapping in an array like HLMV does while ( !pParser->Finished() ) { const char *pBlock = pParser->GetCurrentBlockName(); if ( !stricmp( pBlock, "solid" ) ) { solid_t solid; pParser->ParseSolid( &solid, NULL ); int boneIndex = Studio_BoneIndexByName( &studioHdr, solid.name ); Vector *outVerts; int vertCount = g_pPhysicsCollision->CreateDebugMesh( pCollide->solids[solid.index], &outVerts ); if ( vertCount ) { CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); pRenderContext->CullMode( MATERIAL_CULLMODE_CCW ); // NOTE: assumes these have been set up already by the model render code // So this is a little bit of a back door to a cache of the bones // this code wouldn't work unless you draw the model this frame before calling // this routine. CMDLPanel always does this, but it's worth noting. // A better solution would be to move the ragdoll visulization into the CDmeMdl // and either draw it there or make it queryable and query/draw here. matrix3x4_t xform; SetIdentityMatrix( xform ); if ( boneIndex >= 0 ) { MatrixCopy( pBoneToWorld[ boneIndex ], xform ); } IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_Wireframe ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, vertCount/3 ); for ( int j = 0; j < vertCount; j++ ) { Vector out; VectorTransform( outVerts[j].Base(), xform, out.Base() ); meshBuilder.Position3fv( out.Base() ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.TexCoord2f( 0, 0, 0 ); meshBuilder.AdvanceVertex(); } meshBuilder.End(); pMesh->Draw(); } g_pPhysicsCollision->DestroyDebugMesh( vertCount, outVerts ); } else { pParser->SkipBlock(); } } g_pPhysicsCollision->VPhysicsKeyParserDestroy( pParser ); }
//----------------------------------------------------------------------------- // Purpose: // Input : frametime - //----------------------------------------------------------------------------- void CFXLine::Draw( double frametime ) { // Update the effect Update( frametime ); Vector lineDir, viewDir; //Get the proper orientation for the line VectorSubtract( m_FXData.m_vecStart, m_FXData.m_vecEnd, lineDir ); VectorSubtract( m_FXData.m_vecEnd, CurrentViewOrigin(), viewDir ); Vector cross = lineDir.Cross( viewDir ); VectorNormalize( cross ); CMatRenderContextPtr pRenderContext( materials ); //Bind the material IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_FXData.m_pMaterial ); CMeshBuilder meshBuilder; Vector tmp; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); float scaleTimePerc = ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ); float scale = m_FXData.m_flStartScale + ( ( m_FXData.m_flEndScale - m_FXData.m_flStartScale ) * scaleTimePerc ); color32 color = {255,255,255,255}; float alpha = m_FXData.m_flStartAlpha + ( ( m_FXData.m_flEndAlpha - m_FXData.m_flStartAlpha ) * scaleTimePerc ); alpha = clamp( alpha, 0.0f, 1.0f ); color.a *= alpha; // Start VectorMA( m_FXData.m_vecStart, -scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( m_FXData.m_vecStart, scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // End VectorMA( m_FXData.m_vecEnd, scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( m_FXData.m_vecEnd, -scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
void DrawSpriteModel( IClientEntity *baseentity, CEngineSprite *psprite, const Vector &origin, float fscale, float frame, int rendermode, int r, int g, int b, int a, const Vector& forward, const Vector& right, const Vector& up, float flHDRColorScale ) { float scale; IMaterial *material; // don't even bother culling, because it's just a single // polygon without a surface cache if ( fscale > 0 ) scale = fscale; else scale = 1.0f; if ( rendermode == kRenderNormal ) { render->SetBlend( 1.0f ); } material = psprite->GetMaterial( (RenderMode_t)rendermode, frame ); if ( !material ) return; CMatRenderContextPtr pRenderContext( materials ); if ( ShouldDrawInWireFrameMode() || r_drawsprites.GetInt() == 2 ) { IMaterial *pMaterial = materials->FindMaterial( "debug/debugspritewireframe", TEXTURE_GROUP_OTHER ); pRenderContext->Bind( pMaterial, NULL ); } else { pRenderContext->Bind( material, (IClientRenderable*)baseentity ); } unsigned char color[4]; color[0] = r; color[1] = g; color[2] = b; color[3] = a; IMaterialVar *pHDRColorScaleVar = material->FindVarFast( "$HDRCOLORSCALE", &s_nHDRColorScaleCache ); if( pHDRColorScaleVar ) { pHDRColorScaleVar->SetVecValue( flHDRColorScale, flHDRColorScale, flHDRColorScale ); } Vector point; IMesh* pMesh = pRenderContext->GetDynamicMesh(); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vec_a; Vector vec_b; Vector vec_c; Vector vec_d; // isolate common terms VectorMA( origin, psprite->GetDown() * scale, up, vec_a ); VectorScale( right, psprite->GetLeft() * scale, vec_b ); VectorMA( origin, psprite->GetUp() * scale, up, vec_c ); VectorScale( right, psprite->GetRight() * scale, vec_d ); float flMinU, flMinV, flMaxU, flMaxV; psprite->GetTexCoordRange( &flMinU, &flMinV, &flMaxU, &flMaxV ); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMinU, flMaxV ); VectorAdd( vec_a, vec_b, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMinU, flMinV ); VectorAdd( vec_c, vec_b, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMaxU, flMinV ); VectorAdd( vec_c, vec_d, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMaxU, flMaxV ); VectorAdd( vec_a, vec_d, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
void CGlowObjectManager::RenderGlowModels( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext ) { //==========================================================================================// // This renders solid pixels with the correct coloring for each object that needs the glow. // // After this function returns, this image will then be blurred and added into the frame // // buffer with the objects stenciled out. // //==========================================================================================// pRenderContext->PushRenderTargetAndViewport(); // Save modulation color and blend Vector vOrigColor; render->GetColorModulation( vOrigColor.Base() ); float flOrigBlend = render->GetBlend(); // Get pointer to FullFrameFB ITexture *pRtFullFrame = NULL; pRtFullFrame = materials->FindTexture( FULL_FRAME_TEXTURE, TEXTURE_GROUP_RENDER_TARGET ); SetRenderTargetAndViewPort( pRtFullFrame, pSetup->width, pSetup->height ); pRenderContext->ClearColor3ub( 0, 0, 0 ); pRenderContext->ClearBuffers( true, false, false ); // Set override material for glow color IMaterial *pMatGlowColor = NULL; pMatGlowColor = materials->FindMaterial( "dev/glow_color", TEXTURE_GROUP_OTHER, true ); g_pStudioRender->ForcedMaterialOverride( pMatGlowColor ); ShaderStencilState_t stencilState; stencilState.m_bEnable = false; stencilState.m_nReferenceValue = 0; stencilState.m_nTestMask = 0xFF; stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS; stencilState.m_PassOp = STENCILOPERATION_KEEP; stencilState.m_FailOp = STENCILOPERATION_KEEP; stencilState.m_ZFailOp = STENCILOPERATION_KEEP; stencilState.SetStencilState( pRenderContext ); //==================// // Draw the objects // //==================// for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i ) { if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) ) continue; render->SetBlend( m_GlowObjectDefinitions[i].m_flGlowAlpha ); Vector vGlowColor = m_GlowObjectDefinitions[i].m_vGlowColor * m_GlowObjectDefinitions[i].m_flGlowAlpha; render->SetColorModulation( &vGlowColor[0] ); // This only sets rgb, not alpha m_GlowObjectDefinitions[i].DrawModel(); } if ( g_bDumpRenderTargets ) { DumpTGAofRenderTarget( pSetup->width, pSetup->height, "GlowModels" ); } g_pStudioRender->ForcedMaterialOverride( NULL ); render->SetColorModulation( vOrigColor.Base() ); render->SetBlend( flOrigBlend ); ShaderStencilState_t stencilStateDisable; stencilStateDisable.m_bEnable = false; stencilStateDisable.SetStencilState( pRenderContext ); pRenderContext->PopRenderTargetAndViewport(); }
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 ); } } }
float PixelVisibility_DrawProxy( IMatRenderContext *pRenderContext, OcclusionQueryObjectHandle_t queryHandle, Vector origin, float scale, float proxyAspect, IMaterial *pMaterial, bool screenspace ) { Vector point; // don't expand this with distance to fit pixels or the sprite will poke through // only expand the parts perpendicular to the view float forwardScale = scale; // draw a pyramid of points touching a sphere of radius "scale" at origin float pixelsPerUnit = pRenderContext->ComputePixelDiameterOfSphere( origin, 1.0f ); pixelsPerUnit = MAX( pixelsPerUnit, 1e-4f ); if ( screenspace ) { // Force this to be the size of a sphere of diameter "scale" at some reference distance (1.0 unit) float pixelsPerUnit2 = pRenderContext->ComputePixelDiameterOfSphere( CurrentViewOrigin() + CurrentViewForward()*1.0f, scale*0.5f ); // force drawing of "scale" pixels scale = pixelsPerUnit2 / pixelsPerUnit; } else { float pixels = scale * pixelsPerUnit; // make the radius larger to ensure a minimum screen space size of the proxy geometry if ( pixels < MIN_PROXY_PIXELS ) { scale = MIN_PROXY_PIXELS / pixelsPerUnit; } } // collapses the pyramid to a plane - so this could be a quad instead Vector dir = origin - CurrentViewOrigin(); VectorNormalize(dir); origin -= dir * forwardScale; forwardScale = 0.0f; // Vector verts[5]; const float sqrt2 = 0.707106781f; // sqrt(2) - keeps all vectors the same length from origin scale *= sqrt2; float scale45x = scale; float scale45y = scale / proxyAspect; verts[0] = origin - CurrentViewForward() * forwardScale; // the apex of the pyramid verts[1] = origin + CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // these four form the base verts[2] = origin + CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // the pyramid is a sprite with a point that verts[3] = origin - CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // pokes back toward the camera through any nearby verts[4] = origin - CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // geometry // get screen coords of edges Vector screen[4]; for ( int i = 0; i < 4; i++ ) { extern int ScreenTransform( const Vector& point, Vector& screen ); if ( ScreenTransform( verts[i+1], screen[i] ) ) return -1; } // compute area and screen-clipped area float w = screen[1].x - screen[0].x; float h = screen[0].y - screen[3].y; float ws = MIN(1.0f, screen[1].x) - MAX(-1.0f, screen[0].x); float hs = MIN(1.0f, screen[0].y) - MAX(-1.0f, screen[3].y); float area = w*h; // area can be zero when we ALT-TAB float areaClipped = ws*hs; float ratio = 0.0f; if ( area != 0 ) { // compute the ratio of the area not clipped by the frustum to total area ratio = areaClipped / area; ratio = clamp(ratio, 0.0f, 1.0f); } pRenderContext->BeginOcclusionQueryDrawing( queryHandle ); CMeshBuilder meshBuilder; IMesh* pMesh = pRenderContext->GetDynamicMesh( false, NULL, NULL, pMaterial ); meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 4 ); // draw a pyramid for ( int i = 0; i < 4; i++ ) { int a = i+1; int b = (a%4)+1; meshBuilder.Position3fv( verts[0].Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( verts[a].Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( verts[b].Base() ); meshBuilder.AdvanceVertex(); } meshBuilder.End(); pMesh->Draw(); // sprite/quad proxy #if 0 meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); VectorMA (origin, -scale, CurrentViewUp(), point); VectorMA (point, -scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); VectorMA (origin, scale, CurrentViewUp(), point); VectorMA (point, -scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); VectorMA (origin, scale, CurrentViewUp(), point); VectorMA (point, scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); VectorMA (origin, -scale, CurrentViewUp(), point); VectorMA (point, scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); #endif pRenderContext->EndOcclusionQueryDrawing( queryHandle ); // fraction clipped by frustum return ratio; }