Beispiel #1
0
	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;
	}
Beispiel #2
0
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;
	}
}
Beispiel #3
0
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;
}
Beispiel #5
0
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;
	}
}
Beispiel #6
0
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
}
Beispiel #7
0
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() );
	}
}
Beispiel #8
0
// 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();
}
Beispiel #9
0
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;
}
Beispiel #11
0
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 &center, 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 );
	}
}
Beispiel #13
0
// 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 );
		}
	}
Beispiel #18
0
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();
}
Beispiel #19
0
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] );
	}
}
Beispiel #20
0
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() );
	}
}
Beispiel #23
0
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 );
	}
}
Beispiel #24
0
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 );
}
Beispiel #26
0
//-----------------------------------------------------------------------------
// 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();
}
Beispiel #27
0
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;
}