Example #1
0
static inline void d3d_GetSpriteColor(LTObject *pObject, RGBColor *pColor)
{
	LTVector dynamicLightAdd, color;
	LTRGBColor theColor;


	pColor->rgb.a = (uint8)pObject->m_ColorA;
	
	if((pObject->m_Flags & FLAG_NOLIGHT) || !g_have_world || (!g_CV_DynamicLightSprites.m_Val))
	{
		// Default case if the other stuff doesn't work.
		pColor->rgb.r = pObject->m_ColorR;
		pColor->rgb.g = pObject->m_ColorG;
		pColor->rgb.b = pObject->m_ColorB;
	}
	else
	{
		w_DoLightLookup(world_bsp_shared->LightTable(), &pObject->GetPos(), &theColor);

		d3d_CalcLightAdd(pObject, &dynamicLightAdd);

		color.x = (float)pObject->m_ColorR + (float)theColor.rgb.r + dynamicLightAdd.x;
		color.x = LTCLAMP(color.x, 0.0f, 255.0f);

		color.y = (float)pObject->m_ColorG + (float)theColor.rgb.g + dynamicLightAdd.y;
		color.y = LTCLAMP(color.y, 0.0f, 255.0f);

		color.z = (float)pObject->m_ColorB + (float)theColor.rgb.b + dynamicLightAdd.z;
		color.z = LTCLAMP(color.z, 0.0f, 255.0f);

		pColor->rgb.r = (uint8)RoundFloatToInt(color.x);
		pColor->rgb.g = (uint8)RoundFloatToInt(color.y);
		pColor->rgb.b = (uint8)RoundFloatToInt(color.z);
	}
}
void CGroundLine::Paint( )
{
	vgui::Panel *pPanel = GetParent();
	int wide, tall;
	pPanel->GetSize( wide, tall );
	
	float tPrev = 0;
	float xPrev, yPrev;
	CMinimapPanel::MinimapPanel()->WorldToMinimap( MINIMAP_NOCLIP, m_vStart, xPrev, yPrev );

	int nSegs = 20;
	for( int iSeg=1; iSeg <= nSegs; iSeg++ )
	{
		float t = (float)iSeg / nSegs;

		Vector v3DPos;
		VectorLerp( m_vStart, m_vEnd, t, v3DPos );

		float x, y;
		CMinimapPanel::MinimapPanel()->WorldToMinimap( MINIMAP_NOCLIP, v3DPos, x, y );

		// Clip the line segment on X, then Y.
		if( ClipLine( xPrev, yPrev, x, y, 0,     1 ) &&
			ClipLine( xPrev, yPrev, x, y, wide, -1 ) &&
			ClipLine( yPrev, xPrev, y, x, 0,     1 ) &&
			ClipLine( yPrev, xPrev, y, x, tall, -1 ) )
		{
			Vector vColor;
			VectorLerp( m_vStartColor, m_vEndColor, t, vColor );
			vColor *= 255.9f;

			vgui::surface()->DrawSetColor( 
				(unsigned char)RoundFloatToInt( vColor.x ), 
				(unsigned char)RoundFloatToInt( vColor.y ), 
				(unsigned char)RoundFloatToInt( vColor.z ), 
				255 );

			vgui::surface()->DrawLine( xPrev, yPrev, x, y );
		}

		tPrev = t;
		xPrev = x;
		yPrev = y;
	}

	// Draw a marker at the endpoint.
	float xEnd, yEnd;
	if( CMinimapPanel::MinimapPanel()->WorldToMinimap( MINIMAP_NOCLIP, m_vEnd, xEnd, yEnd ) )
	{
		int ix = RoundFloatToInt( xEnd );
		int iy = RoundFloatToInt( yEnd );
		int rectSize=1;

		vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
		vgui::surface()->DrawOutlinedRect( ix-rectSize, iy-rectSize, ix+rectSize, iy+rectSize );
	}
}
void DrawRectangle(int x_in, int y_in, int width, int height, Framebuffer fbo, Vector4 color)
{
	if(x_in > fbo.width)
		width = 0;
	
	if((x_in + width) > fbo.width)
		width = fbo.width - x_in;
	
	if(y_in > fbo.height)
		height = 0;
	
	if((y_in + height) > fbo.height)
		height = fbo.height - y_in;
	
	if(x_in < 0)
	{
		width = width + x_in;
		x_in = 0;
	}
	
	if((x_in + width) < 0)
		width = 0;
	
	if(y_in < 0)
	{
		height = height + y_in;
		y_in = 0;
	}
	
	if((y_in + height) < 0)
		height = 0;
	
	for (int x = x_in; x < (x_in + width); x++)
	{
		for(int y = y_in; y < (y_in + height); y++)
		{
			uint32_t old_color = *(fbo.pixels + (y * fbo.width) + x);
			float oldr = ((float)((old_color & 0x00FF0000) >> 16)) / 255.0f;
			float oldg = ((float)((old_color & 0x0000FF00) >> 8)) / 255.0f;
			float oldb = ((float)((old_color & 0x000000FF) >> 0)) / 255.0f;
			
			float newr = color.a * color.r + (1 - color.a) * oldr;
			float newg = color.a * color.g + (1 - color.a) * oldg;
			float newb = color.a * color.b + (1 - color.a) * oldb;
			
			uint32_t color32 = (RoundFloatToInt(color.a * 255) < 24) |
							   (RoundFloatToInt(newr * 255) << 16) |
							   (RoundFloatToInt(newg * 255) << 8) |
							   (RoundFloatToInt(newb * 255) << 0);
			
			*(fbo.pixels + (y * fbo.width) + x) = color32;
		}
	}
}
Example #4
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();
}
void DmeFramerate_t::SetFramerate( float flFrameRate )
{
	if ( IsIntegralValue( flFrameRate ) )
	{
		SetFramerate( RoundFloatToInt( flFrameRate ) );
	}
	else if ( IsIntegralValue( flFrameRate * 1001.0f / 1000.0f ) ) // 1001 is the ntsc divisor (30*1000/1001 = 29.97, etc)
	{
		SetFramerateNTSC( RoundFloatToInt( flFrameRate * 1001.0f / 1000.0f ) );
	}
	else
	{
		Assert( 0 );
		SetFramerate( RoundFloatToInt( flFrameRate ) );
	}
}
Example #6
0
//-----------------------------------------------------------------------------
// Purpose: Input handler for changing volume.
// Input  : Float new volume, from 0 - 10.
//-----------------------------------------------------------------------------
void CAmbientGeneric::InputVolume( inputdata_t &inputdata )
{
	//
	// Multiply the input value by ten since volumes are expected to be from 0 - 100.
	//
	m_dpv.vol = clamp( RoundFloatToInt( inputdata.value.Float() * 10.f ), 0, 100 );
	m_dpv.volfrac = m_dpv.vol << 8;

	SendSound( SND_CHANGE_VOL );
}
float LinearToGamma( float linear )
{
	Assert( s_bMathlibInitialized );
	if ( linear < 0.0f )
	{
		return 0.0f;
	}
	if ( linear > 1.0f )
	{
		// Use LinearToGammaFullRange maybe if you trip this.
		Assert( 0 );
		return 1.0f;
	}

	int index = RoundFloatToInt( linear * 255.0f );
	Assert( index >= 0 && index < 256 );
	return g_Mathlib_LinearToGamma[index];
}
float GammaToLinear( float gamma )
{
	Assert( s_bMathlibInitialized );
	if ( gamma < 0.0f )
	{
		return 0.0f;
	}

	if ( gamma >= 0.95f )
	{
		// Use GammaToLinearFullRange maybe if you trip this.
// X360TEMP
//		Assert( gamma <= 1.0f );
		return 1.0f;
	}

	int index = RoundFloatToInt( gamma * 255.0f );
	Assert( index >= 0 && index < 256 );
	return g_Mathlib_GammaToLinear[index];
}
void DrawBitmap(int x_in, int y_in, int width, int height, Framebuffer fbo, LoadedBitmap bitmap)
{
	int x_offset = 0;
	int y_offset = 0;
	
	if(x_in > fbo.width)
		width = 0;
	
	if((x_in + width) > fbo.width)
		width = fbo.width - x_in;
	
	if(y_in > fbo.height)
		height = 0;
	
	if((y_in + height) > fbo.height)
		height = fbo.height - y_in;
	
	if(x_in < 0)
	{
		x_offset = -x_in;
		width = width + x_in;
		x_in = 0;
	}
	
	if((x_in + width) < 0)
		width = 0;
	
	if(y_in < 0)
	{
		y_offset = -y_in;
		height = height + y_in;
		y_in = 0;
	}
	
	if((y_in + height) < 0)
		height = 0;

	for (int x = 0; (x + x_in) < (x_in + width); x++)
	{
		for(int y = 0; (y + y_in) < (y_in + height); y++)
		{
			uint32_t old_color = *(fbo.pixels + ((y + y_in) * fbo.width) + (x + x_in));
			
			float oldr = ((float)((old_color & 0x00FF0000) >> 16)) / 255.0f;
			float oldg = ((float)((old_color & 0x0000FF00) >> 8)) / 255.0f;
			float oldb = ((float)((old_color & 0x000000FF) >> 0)) / 255.0f;
			
			uint32_t texel_color = *(bitmap.pixels + ((y + y_offset) * bitmap.width) + x + x_offset);
			
			float texelr = ((float)((texel_color & 0x00FF0000) >> 16)) / 255.0f;
			float texelg = ((float)((texel_color & 0x0000FF00) >> 8)) / 255.0f;
			float texelb = ((float)((texel_color & 0x000000FF) >> 0)) / 255.0f;
			float texela = ((float)((texel_color & 0xFF000000) >> 24)) / 255.0f;
			
			float newr = texela * texelr + (1 - texela) * oldr;
			float newg = texela * texelg + (1 - texela) * oldg;
			float newb = texela * texelb + (1 - texela) * oldb;
			
			uint32_t color32 = (RoundFloatToInt(texela * 255) < 24) |
							   (RoundFloatToInt(newr * 255) << 16) |
							   (RoundFloatToInt(newg * 255) << 8) |
							   (RoundFloatToInt(newb * 255) << 0);
			
			*(fbo.pixels + ((y + y_in) * fbo.width) + (x + x_in)) = color32;
		}
	}
}
void BuildGammaTable( float gamma, float texGamma, float brightness, int overbright )
{
	int		i, inf;
	float	g1, g3;

	// Con_Printf("BuildGammaTable %.1f %.1f %.1f\n", g, v_lightgamma.GetFloat(), v_texgamma.GetFloat() );

	float g = gamma;
	if (g > 3.0) 
	{
		g = 3.0;
	}

	g = 1.0 / g;
	g1 = texGamma * g; 

	if (brightness <= 0.0) 
	{
		g3 = 0.125;
	}
	else if (brightness > 1.0) 
	{
		g3 = 0.05;
	}
	else 
	{
		g3 = 0.125 - (brightness * brightness) * 0.075;
	}

	for (i=0 ; i<256 ; i++)
	{
		inf = static_cast<int>(255 * pow ( i/255.f, g1 )); 
		if (inf < 0)
			inf = 0;
		if (inf > 255)
			inf = 255;
		texgammatable[i] = inf;
	}

	for (i=0 ; i<1024 ; i++)
	{
		float f;

		f = i / 1023.0;

		// scale up
		if (brightness > 1.0)
			f = f * brightness;

		// shift up
		if (f <= g3)
			f = (f / g3) * 0.125;
		else 
			f = 0.125 + ((f - g3) / (1.0 - g3)) * 0.875;

		// convert linear space to desired gamma space
		inf = static_cast<int>(255 * pow ( f, g )); 

		if (inf < 0)
			inf = 0;
		if (inf > 255)
			inf = 255;
		lineartoscreen[i] = inf;
	}

	/*
	for (i=0 ; i<1024 ; i++)
	{
		// convert from screen gamma space to linear space
		lineargammatable[i] = 1023 * pow ( i/1023.0, v_gamma.GetFloat() );
		// convert from linear gamma space to screen space
		screengammatable[i] = 1023 * pow ( i/1023.0, 1.0 / v_gamma.GetFloat() );
	}
	*/

	for (i=0 ; i<256 ; i++)
	{
		// convert from nonlinear texture space (0..255) to linear space (0..1)
		texturetolinear[i] =  pow( i / 255.f, texGamma );

		// convert from linear space (0..1) to nonlinear (sRGB) space (0..1)
		g_Mathlib_LinearToGamma[i] =  LinearToGammaFullRange( i / 255.f );

		// convert from sRGB gamma space (0..1) to linear space (0..1)
		g_Mathlib_GammaToLinear[i] =  GammaToLinearFullRange( i / 255.f );
	}

	for (i=0 ; i<1024 ; i++)
	{
		// convert from linear space (0..1) to nonlinear texture space (0..255)
		lineartotexture[i] = static_cast<int>(pow( i / 1023.0, 1.0 / texGamma ) * 255);
	}

#if 0
	for (i=0 ; i<256 ; i++)
	{
		float f;

		// convert from nonlinear lightmap space (0..255) to linear space (0..4)
		// f =  (i / 255.0) * sqrt( 4 );
		f =  i * (2.0 / 255.0);
		f = f * f;

		texlighttolinear[i] = f;
	}
#endif

	{
		float f;
		float overbrightFactor = 1.0f;

		// Can't do overbright without texcombine
		// UNDONE: Add GAMMA ramp to rectify this
		if ( overbright == 2 )
		{
			overbrightFactor = 0.5;
		}
		else if ( overbright == 4 )
		{
			overbrightFactor = 0.25;
		}

		for (i=0 ; i<4096 ; i++)
		{
			// convert from linear 0..4 (x1024) to screen corrected vertex space (0..1?)
			f = pow ( i/1024.0, 1.0 / gamma );

			lineartovertex[i] = f * overbrightFactor;
			if (lineartovertex[i] > 1)
				lineartovertex[i] = 1;

			int nLightmap = RoundFloatToInt( f * 255 * overbrightFactor );
			nLightmap = clamp( nLightmap, 0, 255 );
			lineartolightmap[i] = (unsigned char)nLightmap;
		}
	}
}
Example #11
0
bool CEventLog::PrintPlayerEvent( IGameEvent *event )
{
	const char * eventName = event->GetName();
	const int userid = event->GetInt( "userid" );

	if ( !Q_strncmp( eventName, "player_connect", Q_strlen("player_connect") ) ) // player connect is before the CBasePlayer pointer is setup
	{
		const char *name = event->GetString( "name" );
		const char *address = event->GetString( "address" );
		const char *networkid = event->GetString("networkid" );
		UTIL_LogPrintf( "\"%s<%i><%s><>\" connected, address \"%s\"\n", name, userid, networkid, address);
		return true;
	}
	else if ( !Q_strncmp( eventName, "player_disconnect", Q_strlen("player_disconnect")  ) )
	{
		const char *reason = event->GetString("reason" );
		const char *name = event->GetString("name" );
		const char *networkid = event->GetString("networkid" );
		CTeam *team = NULL;
		CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );

		if ( pPlayer )
		{
			team = pPlayer->GetTeam();
		}

		UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected (reason \"%s\")\n", name, userid, networkid, team ? team->GetName() : "", reason );
		return true;
	}

	CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
	if ( !pPlayer)
	{
		DevMsg( "CEventLog::PrintPlayerEvent: Failed to find player (userid: %i, event: %s)\n", userid, eventName );
		return false;
	}

	if ( !Q_strncmp( eventName, "player_team", Q_strlen("player_team") ) )
	{
		const bool bDisconnecting = event->GetBool( "disconnect" );

		if ( !bDisconnecting )
		{
			const int newTeam = event->GetInt( "team" );
			const int oldTeam = event->GetInt( "oldteam" );
			CTeam *team = GetGlobalTeam( newTeam );
			CTeam *oldteam = GetGlobalTeam( oldTeam );
			
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", 
			pPlayer->GetPlayerName(),
			pPlayer->GetUserID(),
			pPlayer->GetNetworkIDString(),
			oldteam->GetName(),
			team->GetName() );
		}

		return true;
	}
	else if ( !Q_strncmp( eventName, "player_death", Q_strlen("player_death") ) )
	{
		const int attackerid = event->GetInt("attacker" );

#ifdef HL2MP
		const char *weapon = event->GetString( "weapon" );
#endif
		
		CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
		CTeam *team = pPlayer->GetTeam();
		CTeam *attackerTeam = NULL;
		
		if ( pAttacker )
		{
			attackerTeam = pAttacker->GetTeam();
		}
		if ( pPlayer == pAttacker && pPlayer )  
		{  
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",  
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : "",
							weapon
							);

		}
		else if ( pAttacker )
		{
			CTeam *attackerTeam = pAttacker->GetTeam();
			//BG2 - Display killer and victim positions in log files for HLStatsX support. -HairyPotter
			Vector APos = pAttacker->GetAbsOrigin(), VPos = pPlayer->GetAbsOrigin();

			UTIL_LogPrintf("\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\" (attacker_position \"%i %i %i\" ) (victim_position \"%i %i %i\" )\n",
							pAttacker->GetPlayerName(),
							attackerid,
							pAttacker->GetNetworkIDString(),
							attackerTeam ? attackerTeam->GetName() : "",
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : "",
							weapon,
							RoundFloatToInt(APos.x),
							RoundFloatToInt( APos.y ),
							RoundFloatToInt( APos.z ),
							RoundFloatToInt( VPos.x ),
							RoundFloatToInt( VPos.y ),
							RoundFloatToInt( VPos.z )
							);
		}
		else
		{  
			// killed by the world
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n",
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : ""
							);
		}
		return true;
	}
	else if ( !Q_strncmp( eventName, "player_activate", Q_strlen("player_activate") ) )
	{
		UTIL_LogPrintf( "\"%s<%i><%s><>\" entered the game\n",  
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString()
							);

		return true;
	}
	else if ( !Q_strncmp( eventName, "player_changename", Q_strlen("player_changename") ) )
	{
		const char *newName = event->GetString( "newname" );
		const char *oldName = event->GetString( "oldname" );
		CTeam *team = pPlayer->GetTeam();
		UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", 
					oldName,
					userid,
					pPlayer->GetNetworkIDString(),
					team ? team->GetName() : "",
					newName
					);
		return true;
	}
				   
// ignored events
//player_hurt
	return false;
}
Example #12
0
// Sets up pParams.
// pPos and pRotation are the view position and orientation.
// pRect is the rectangle on the screen that the viewing window maps into.
// pScale is an extra scale that scales all the coordinates up.
bool d3d_InitFrustum2(ViewParams *pParams, 
	ViewBoxDef *pViewBox, 
	float screenMinX, float screenMinY, float screenMaxX, float screenMaxY,
	const LTMatrix *pMat, const LTVector& vScale, ViewParams::ERenderMode eMode)
{
	LTMatrix mTempWorld, mRotation, mScale;
	LTMatrix mFOVScale, mBackTransform;
	LTMatrix mDevice, mBackTranslate;
	float leftX, rightX, topY, bottomY, normalZ;
	uint32 i;
	LTVector forwardVec, zPlanePos, vTrans;
	LTMatrix mProjectionTransform; //mUnit, mPerspective;
	
	pParams->m_mIdentity.Identity();
	pParams->m_mInvView = *pMat;


	// Here's how the viewing works:
	// The world to camera transformation rotates and translates
	// the world into camera space.
	// The camera to clip transformation just scales the sides so the
	// field of view is 90 degrees (faster to clip in).
	// Clipping takes place on NEARZ and g_ViewParams.m_FarZ.
	// In terms of Z buffer calculations, the maximum Z is MAX_FARZ (that way,
	// when the farZ clipping plane is changed, sz and rhw stay the same).



	/////// Copy stuff in and setup view limits.

	memcpy(&pParams->m_ViewBox, pViewBox, sizeof(pParams->m_ViewBox));
	pMat->GetTranslation(pParams->m_Pos);

	pParams->m_FarZ = pViewBox->m_FarZ;
	if(pParams->m_FarZ < 3.0f) pParams->m_FarZ = 3.0f;
	if(pParams->m_FarZ > MAX_FARZ) pParams->m_FarZ = MAX_FARZ;
	pParams->m_NearZ = pViewBox->m_NearZ;
	
	pParams->m_Rect.left = (int)RoundFloatToInt(screenMinX);
	pParams->m_Rect.top = (int)RoundFloatToInt(screenMinY);
	pParams->m_Rect.right = (int)RoundFloatToInt(screenMaxX);
	pParams->m_Rect.bottom = (int)RoundFloatToInt(screenMaxY);

	/////// Setup all the matrices.

	// Setup the rotation and translation transforms.
	mRotation = *pMat;
	mRotation.SetTranslation(0.0f, 0.0f, 0.0f);
	Mat_GetBasisVectors(&mRotation, &pParams->m_Right, &pParams->m_Up, &pParams->m_Forward);

	// We want to transpose (ie: when we're looking left, rotate the world to the right..)
	MatTranspose3x3(&mRotation);
	mBackTranslate.Init(
		1, 0, 0, -pParams->m_Pos.x,
		0, 1, 0, -pParams->m_Pos.y,
		0, 0, 1, -pParams->m_Pos.z,
		0, 0, 0, 1);
	MatMul(&mTempWorld, &mRotation, &mBackTranslate);
	
	// Scale it to get the full world transform.
	mScale.Init(
		vScale.x, 0, 0, 0,
		0, vScale.y, 0, 0,
		0, 0, vScale.z, 0,
		0, 0, 0, 1);
	MatMul(&pParams->m_mView, &mScale, &mTempWorld);

	// Shear so the center of projection is (0,0,COP.z)
	LTMatrix mShear;
	mShear.Init(
		1.0f, 0.0f, -pViewBox->m_COP.x/pViewBox->m_COP.z, 0.0f,
		0.0f, 1.0f, -pViewBox->m_COP.y/pViewBox->m_COP.z, 0.0f,
		0.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f);

	// Figure out X and Y scale to get frustum into unit slopes.
	float fFovXScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[0];
	float fFovYScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[1];

	// Squash the sides to 45 degree angles.
	mFOVScale.Init(
		fFovXScale, 0.0f, 0.0f, 0.0f,
		0.0f, fFovYScale, 0.0f, 0.0f,
		0.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f);

	// Setup the projection transform.
	d3d_SetupPerspectiveMatrix(&mProjectionTransform, pViewBox->m_NearZ, pParams->m_FarZ);

	// Setup the projection space (-1<x<1) to device space transformation.
	pParams->m_fScreenWidth = (screenMaxX - screenMinX);
	pParams->m_fScreenHeight = (screenMaxY - screenMinY);
	
	// Setup the device transform.  It subtracts 0.4 to account for the FP's tendency
	// to slip above and below 0.5.
	Mat_Identity(&mDevice);
	mDevice.m[0][0] = pParams->m_fScreenWidth * 0.5f - 0.0001f;
	mDevice.m[0][3] = screenMinX + pParams->m_fScreenWidth * 0.5f;
	mDevice.m[1][1] = -(pParams->m_fScreenHeight * 0.5f - 0.0001f);
	mDevice.m[1][3] = screenMinY + pParams->m_fScreenHeight * 0.5f;


	// Precalculate useful matrices.
	pParams->m_DeviceTimesProjection = mDevice * mProjectionTransform;
	pParams->m_FullTransform = pParams->m_DeviceTimesProjection * mFOVScale * mShear * pParams->m_mView;

	pParams->m_mProjection = mProjectionTransform * mFOVScale * mShear;
	
	/////// Setup the view frustum points in camera space.
	
	float xNearZ, yNearZ, xFarZ, yFarZ;
	xNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z;
	yNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z;
	xFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z;
	yFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z;

	pParams->m_ViewPoints[0].Init(-xNearZ, yNearZ,  pParams->m_NearZ);	// Near Top Left
	pParams->m_ViewPoints[1].Init(xNearZ,  yNearZ,  pParams->m_NearZ);	// Near Top Right
	pParams->m_ViewPoints[2].Init(-xNearZ, -yNearZ, pParams->m_NearZ);	// Near Bottom Left
	pParams->m_ViewPoints[3].Init(xNearZ,  -yNearZ, pParams->m_NearZ);	// Near Bottom Right

	pParams->m_ViewPoints[4].Init(-xFarZ, yFarZ,  pParams->m_FarZ);	// Far Top Left
	pParams->m_ViewPoints[5].Init(xFarZ,  yFarZ,  pParams->m_FarZ);	// Far Top Right
	pParams->m_ViewPoints[6].Init(-xFarZ, -yFarZ, pParams->m_FarZ);	// Far Bottom Left
	pParams->m_ViewPoints[7].Init(xFarZ,  -yFarZ, pParams->m_FarZ);	// Far Bottom Right

	// Transform them into world space.
	for(i=0; i < 8; i++)
	{
		MatVMul_InPlace_Transposed3x3(&pParams->m_mView, &pParams->m_ViewPoints[i]);
		pParams->m_ViewPoints[i] += pParams->m_Pos;
	}

	// Get the AABB of the view frustum
	pParams->m_ViewAABBMin = pParams->m_ViewPoints[0];
	pParams->m_ViewAABBMax = pParams->m_ViewPoints[0];
	for(i=1; i < 8; i++)
	{
		VEC_MIN(pParams->m_ViewAABBMin, pParams->m_ViewAABBMin, pParams->m_ViewPoints[i]);
		VEC_MAX(pParams->m_ViewAABBMax, pParams->m_ViewAABBMax, pParams->m_ViewPoints[i]);
	}

	/////// Setup the camera-space clipping planes.

	leftX = pViewBox->m_COP.x - pViewBox->m_WindowSize[0];
	rightX = pViewBox->m_COP.x + pViewBox->m_WindowSize[0];
	topY = pViewBox->m_COP.y + pViewBox->m_WindowSize[1];
	bottomY = pViewBox->m_COP.y - pViewBox->m_WindowSize[1];
	normalZ = pViewBox->m_COP.z;
	
	LTPlane CSClipPlanes[NUM_CLIPPLANES];
	CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Init(0.0f, 0.0f, 1.0f);		// Near Z
	CSClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 1.0f;

	CSClipPlanes[CPLANE_FAR_INDEX].m_Normal.Init(0.0f, 0.0f, -1.0f);			// Far Z
	CSClipPlanes[CPLANE_FAR_INDEX].m_Dist = -pParams->m_FarZ;
	
	CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Init(normalZ,  0.0f, -leftX);		// Left
	CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Init(-normalZ, 0.0f, rightX);		// Right
	CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Init(0.0f,  -normalZ, topY);		// Top
	CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Init(0.0f,  normalZ, -bottomY);	// Bottom

	CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Norm();

	CSClipPlanes[CPLANE_LEFT_INDEX].m_Dist = CSClipPlanes[CPLANE_RIGHT_INDEX].m_Dist = 0.0f;
	CSClipPlanes[CPLANE_TOP_INDEX].m_Dist = CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Dist = 0.0f;

	// Now setup the world space clipping planes.
	mBackTransform = pParams->m_mView;
	MatTranspose3x3(&mBackTransform);
	for(i=0; i < NUM_CLIPPLANES; i++)
	{
		if(i != CPLANE_NEAR_INDEX && i != CPLANE_FAR_INDEX)
		{
			MatVMul_3x3(&pParams->m_ClipPlanes[i].m_Normal, &mBackTransform, &CSClipPlanes[i].m_Normal);
			pParams->m_ClipPlanes[i].m_Dist = pParams->m_ClipPlanes[i].m_Normal.Dot(pParams->m_Pos);
		}
	}

	// The Z planes need to be handled a little differently.
	forwardVec.Init(mRotation.m[2][0], mRotation.m[2][1], mRotation.m[2][2]);

	zPlanePos = forwardVec * pViewBox->m_NearZ;
	zPlanePos += pParams->m_Pos;

	MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal, 
		&mBackTransform, &CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal);

	pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 
		pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Dot(zPlanePos);

	zPlanePos = forwardVec * pParams->m_FarZ;
	zPlanePos += pParams->m_Pos;
	
	MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal,
		&mBackTransform, &CSClipPlanes[CPLANE_FAR_INDEX].m_Normal);

	pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Dist = 
		pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal.Dot(zPlanePos);

	// Remember AABB Corners the planes are pointing at
	for (uint32 nPlaneLoop = 0; nPlaneLoop < NUM_CLIPPLANES; ++nPlaneLoop)
	{
		pParams->m_AABBPlaneCorner[nPlaneLoop] = 
			GetAABBPlaneCorner(pParams->m_ClipPlanes[nPlaneLoop].m_Normal);
	}

	// Default the world transform to identity
	pParams->m_mInvWorld.Identity();

	//setup the environment mapping info
	pParams->m_mWorldEnvMap.SetBasisVectors(&pParams->m_Right, &pParams->m_Up, &pParams->m_Forward);

	//turn off glowing by default
	pParams->m_eRenderMode = eMode;

	d3d_SetupSkyStuff(g_pSceneDesc->m_SkyDef, pParams);
	return true;
}
bool IsIntegralValue( float flValue, float flTolerance = 0.001f )
{
	return fabs( RoundFloatToInt( flValue ) - flValue ) < flTolerance;
}