|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef PARTICLESPHERERENDERER_H
#define PARTICLESPHERERENDERER_H
#ifdef _WIN32
#pragma once
#endif
#include "particlemgr.h"
#include "particle_util.h"
class CParticleSphereRenderer { public:
CParticleSphereRenderer();
// Initialize and tell it the material you'll be using.
void Init( CParticleMgr *pParticleMgr, IMaterial *pMaterial ); // Pass this call through from your particle system too.
void StartRender( VMatrix &effectMatrix );
// Call this to render a spherical particle.
void RenderParticle( ParticleDraw *pDraw, const Vector &vOriginalPos, const Vector &vTransformedPos, float flAlpha, // value 0 - 255.4
float flParticleSize, float flAngle = 0.0f );
void RenderParticle_AddColor( ParticleDraw *pDraw, const Vector &vOriginalPos, const Vector &vTransformedPos, float flAlpha, // value 0 - 255.4
float flParticleSize, const Vector &vToAdd0to1 // Add this to the color (value 0-1)
);
// Lighting is (base color) + (ambient / dist^2) + bump(directional / dist^2)
const Vector& GetBaseColor() const; // Specified as 0-1
void SetBaseColor( const Vector &vColor ); const CParticleLightInfo& GetAmbientLight() const; void SetAmbientLight( const CParticleLightInfo &info ); const CParticleLightInfo& GetDirectionalLight() const; void SetDirectionalLight( const CParticleLightInfo &info );
private:
void AddLightColor( Vector const *pPos, Vector const *pLightPos, Vector const *pLightColor, float flLightIntensity, Vector *pOutColor );
inline void ClampColor( Vector &vColor );
private:
int m_iLastTickStartRenderCalled; // Used for debugging.
CParticleMgr *m_pParticleMgr; Vector m_vBaseColor; CParticleLightInfo m_AmbientLight; CParticleLightInfo m_DirectionalLight; bool m_bUsingPixelShaders; };
// ------------------------------------------------------------------------ //
// Inlines.
// ------------------------------------------------------------------------ //
inline void CParticleSphereRenderer::AddLightColor( Vector const *pPos, Vector const *pLightPos, Vector const *pLightColor, float flLightIntensity, Vector *pOutColor ) { if( flLightIntensity ) { float fDist = pPos->DistToSqr( *pLightPos ); float fAmt; if( fDist > 0.0001f ) fAmt = flLightIntensity / fDist; else fAmt = 1000.f;
*pOutColor += *pLightColor * fAmt; } }
inline void CParticleSphereRenderer::ClampColor( Vector &vColor ) { float flMax = MAX( vColor.x, MAX( vColor.y, vColor.z ) ); if( flMax > 1 ) { vColor *= 255.0f / flMax; } else { vColor *= 255.0; } }
inline const Vector& CParticleSphereRenderer::GetBaseColor() const { return m_vBaseColor; }
inline void CParticleSphereRenderer::SetBaseColor( const Vector &vColor ) { m_vBaseColor = vColor; }
inline const CParticleLightInfo& CParticleSphereRenderer::GetAmbientLight() const { return m_AmbientLight; }
inline void CParticleSphereRenderer::SetAmbientLight( const CParticleLightInfo &info ) { m_AmbientLight = info; }
inline const CParticleLightInfo& CParticleSphereRenderer::GetDirectionalLight() const { return m_DirectionalLight; }
inline void CParticleSphereRenderer::SetDirectionalLight( const CParticleLightInfo &info ) { m_DirectionalLight = info; }
inline void CParticleSphereRenderer::RenderParticle( ParticleDraw *pDraw, const Vector &vOriginalPos, const Vector &vTransformedPos, float flAlpha, float flParticleSize, float flAngle ) { // Make sure they called StartRender on us so we were able to set the directional light parameters.
#ifdef _DEBUG
if ( pDraw->GetMeshBuilder() ) { Assert( m_iLastTickStartRenderCalled == gpGlobals->tickcount ); } #endif
Vector vColor = m_vBaseColor; AddLightColor( &vOriginalPos, &m_AmbientLight.m_vPos, &m_AmbientLight.m_vColor, m_AmbientLight.m_flIntensity, &vColor ); // If the DX8 shader isn't going to handle the directional light color, then add its contribution here.
if( !m_bUsingPixelShaders ) { AddLightColor( &vOriginalPos, &m_DirectionalLight.m_vPos, &m_DirectionalLight.m_vColor, m_DirectionalLight.m_flIntensity, &vColor ); } ClampColor( vColor );
RenderParticle_Color255SizeNormalAngle( pDraw, vTransformedPos, vColor, // ambient color
flAlpha, // alpha
flParticleSize, vec3_origin, flAngle ); }
inline void CParticleSphereRenderer::RenderParticle_AddColor( ParticleDraw *pDraw, const Vector &vOriginalPos, const Vector &vTransformedPos, float flAlpha, float flParticleSize, const Vector &vToAdd0to1 ) { // Make sure they called StartRender on us so we were able to set the directional light parameters.
#ifdef _DEBUG
if ( pDraw->GetMeshBuilder() ) { Assert( m_iLastTickStartRenderCalled == gpGlobals->tickcount ); } #endif
Vector vColor = m_vBaseColor + vToAdd0to1; AddLightColor( &vOriginalPos, &m_AmbientLight.m_vPos, &m_AmbientLight.m_vColor, m_AmbientLight.m_flIntensity, &vColor ); // If the DX8 shader isn't going to handle the directional light color, then add its contribution here.
if( !m_bUsingPixelShaders ) { AddLightColor( &vOriginalPos, &m_DirectionalLight.m_vPos, &m_DirectionalLight.m_vColor, m_DirectionalLight.m_flIntensity, &vColor ); } ClampColor( vColor );
RenderParticle_Color255Size( pDraw, vTransformedPos, vColor, // ambient color
flAlpha, // alpha
flParticleSize ); }
#endif // PARTICLESPHERERENDERER_H
|