//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=====================================================================================//

#include "materialsystem/imesh.h"
#include "materialsystem/imaterialsystemhardwareconfig.h"
#include "materialsystem/imorph.h"
#include "materialsystem/imaterialsystemstub.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/itexture.h"
#include "materialsystem/imaterialvar.h"
#include "bitmap/imageformat.h"
#include "mathlib/vmatrix.h"
#include "utlvector.h"
// GR
#include "imaterialinternal.h"
#include "materialsystem/materialsystem_config.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#include "mat_stub.h"

CDummyTexture g_DummyTexture;

// ---------------------------------------------------------------------------------------- //
// IMaterialSystem and IMesh stub classes.
// ---------------------------------------------------------------------------------------- //
static unsigned short g_DummyIndices[6];

class CDummyMesh : public IMesh
{
public:
	// Locks/ unlocks the mesh, providing space for nVertexCount and nIndexCount.
	// nIndexCount of -1 means don't lock the index buffer...
	virtual void LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t& desc )
	{
		Lock( nVertexCount, false, *static_cast< VertexDesc_t* >( &desc ) );
		Lock( nIndexCount, false, *static_cast< IndexDesc_t* >( &desc ) );
	}

	virtual void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t& desc )
	{
	}

	virtual void ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t& desc )
	{
		ModifyBegin( bReadOnly, nFirstIndex, nIndexCount, *static_cast< IndexDesc_t* >( &desc ) );
	}

	virtual void ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t& desc )
	{
		ModifyBegin( false, nFirstIndex, nIndexCount, *static_cast< IndexDesc_t* >( &desc ) );
	}

	virtual void ModifyEnd( MeshDesc_t &desc )
	{
	}

	// FIXME: Make this work! Unsupported methods of IIndexBuffer
	virtual bool Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t& desc ) 
	{
		desc.m_pIndices = g_DummyIndices;
		desc.m_nIndexSize = 0;
		desc.m_nFirstIndex = 0;
		desc.m_nOffset = 0;
		return true;
	}

	virtual void Unlock( int nWrittenIndexCount, IndexDesc_t& desc ) {}

	virtual void ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t& desc ) 
	{
		desc.m_pIndices = g_DummyIndices;
		desc.m_nIndexSize = 0;
		desc.m_nFirstIndex = 0;
		desc.m_nOffset = 0;
	}

	virtual void ModifyEnd( IndexDesc_t &desc ) {}
	virtual void Spew( int nIndexCount, const IndexDesc_t & desc ) {} 
	virtual void ValidateData( int nIndexCount, const IndexDesc_t &desc ) {}
	virtual bool IsDynamic() const 
	{
		return false;
	}

	virtual void BeginCastBuffer( MaterialIndexFormat_t format ) {}
	virtual void BeginCastBuffer( VertexFormat_t format ) {}
	virtual void EndCastBuffer( ) {}

	// Returns the number of vertices that can still be written into the buffer
	virtual int GetRoomRemaining() const { return 0; }

	virtual int IndexCount() const
	{
		return 0;
	}

	// returns the # of vertices (static meshes only)
	virtual int VertexCount() const
	{
		return 0;
	}

	// returns the vertex format
	virtual bool Lock( int nVertexCount, bool bAppend, VertexDesc_t &desc )
	{
		static float dummyFloat[32];
		static unsigned char dummyChar[32];

		memset( &desc, 0, sizeof( desc ) );

		// Pointers to our current vertex data
		desc.m_pPosition = dummyFloat;
		desc.m_pBoneWeight = dummyFloat;
#ifdef NEW_SKINNING
		desc.m_pBoneMatrixIndex = dummyFloat;
#else
		desc.m_pBoneMatrixIndex = dummyChar;
#endif

		desc.m_pNormal = dummyFloat;
		desc.m_pColor = dummyChar;
		desc.m_pSpecular = dummyChar;
		for( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; i++ )
		{
			desc.m_pTexCoord[i] = dummyFloat;
		}

		desc.m_pTangentS = dummyFloat;
		desc.m_pTangentT = dummyFloat;
		desc.m_pWrinkle = dummyFloat;

		// user data
		desc.m_pUserData = dummyFloat;
		desc.m_nFirstVertex = 0;
		desc.m_nOffset = 0;
		return true;
	}

	virtual void Unlock( int nVertexCount, VertexDesc_t &desc ) {}
	virtual void Spew( int nVertexCount, const VertexDesc_t &desc ) {}
	virtual void ValidateData( int nVertexCount, const VertexDesc_t & desc ) {}

	// Sets/gets the primitive type
	virtual void SetPrimitiveType( MaterialPrimitiveType_t type )
	{
	}
	
	// Draws the mesh
	virtual void Draw( int nFirstIndex = -1, int nIndexCount = 0 )
	{
	}
	
	virtual void SetColorMesh( IMesh *pColorMesh, int nVertexOffset )
	{
	}

	virtual void SetFlexMesh( IMesh *pMesh, int nVertexOffset )
	{
	}

	virtual void DisableFlexMesh( )
	{
	}

	// Draw a list of (lists of) primitives. Batching your lists together that use
	// the same lightmap, material, vertex and index buffers with multipass shaders
	// can drastically reduce state-switching overhead.
	// NOTE: this only works with STATIC meshes.
	virtual void Draw( CPrimList *pLists, int nLists )
	{
	}

	// Copy verts and/or indices to a mesh builder. This only works for temp meshes!
	virtual void CopyToMeshBuilder( 
		int iStartVert,		// Which vertices to copy.
		int nVerts, 
		int iStartIndex,	// Which indices to copy.
		int nIndices, 
		int indexOffset,	// This is added to each index.
		CMeshBuilder &builder )
	{
	}

	// Spews the mesh data
	virtual void Spew( int nVertexCount, int nIndexCount, const MeshDesc_t& desc )
	{
	}

	// Call this in debug mode to make sure our data is good.
	virtual void ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t& desc )
	{
	}

	virtual void MarkAsDrawn() {}

	virtual unsigned ComputeMemoryUsed() { return 0; }

	virtual VertexFormat_t GetVertexFormat() const	
	{	
		return VERTEX_POSITION;
	}
	virtual MaterialIndexFormat_t IndexFormat() const	
	{	
		return MATERIAL_INDEX_FORMAT_16BIT;
	}
	virtual IMesh *GetMesh()
	{
		return this;
	}
};

// We allocate this dynamically because it uses a bunch of memory and we don't want to
// waste the memory unless we need to.
CDummyMesh *g_pDummyMesh = NULL;
CDummyMesh* GetDummyMesh()
{
	if ( !g_pDummyMesh )
	{
		g_pDummyMesh = new CDummyMesh;
	}

	return g_pDummyMesh;
}

// ---------------------------------------------------------------------------------------- //
// Dummy implementation of IMaterialVar.
// ---------------------------------------------------------------------------------------- //
static VMatrix g_DummyMatrix( 1,0,0,0,   0,1,0,0,   0,0,1,0,   0,0,0,1 );

class CDummyMaterialVar : public IMaterialVar
{
public:
	virtual char const *	GetName( void ) const { return "DummyMaterialVar"; }
	virtual MaterialVarSym_t	GetNameAsSymbol() const { return 0; }

	virtual void			SetFloatValue( float val ) {}
	virtual float			GetFloatValueInternal( void ) const { return 1; }
	
	virtual void			SetIntValue( int val ) {}
	virtual int				GetIntValueInternal( void ) const { return 1; }
	
	virtual void			SetStringValue( char const *val ) {}
	virtual char const *	GetStringValue( void ) const { return ""; }

	// Use FourCC values to pass app-defined data structures between
	// the proxy and the shader. The shader should ignore the data if
	// its FourCC type not correct.	
	virtual void			SetFourCCValue( FourCC type, void *pData ) {}
	virtual void			GetFourCCValue( FourCC *type, void **ppData ) {}

	// Vec (dim 2-4)
	virtual void			SetVecValue( float const* val, int numcomps ) {}
	virtual void			SetVecValue( float x, float y ) {}
	virtual void			SetVecValue( float x, float y, float z ) {}
	virtual void			SetVecValue( float x, float y, float z, float w ) {}
	virtual void			SetVecComponentValue( float fVal, int nComponent ) {}
	virtual void			GetVecValueInternal( float *val, int numcomps ) const
	{
		for ( int i=0; i < numcomps; i++ )
			val[i] = 1;
	}
	virtual void			GetLinearVecValue( float *val, int numcomps ) const
	{
		for ( int i=0; i < numcomps; i++ )
			val[i] = 1;
	}

	virtual float const*	GetVecValueInternal( ) const
	{
		static float val[4] = {1,1,1,1};
		return val;
	}

	virtual int				VectorSizeInternal() const
	{
		return 3;
	}

	// revisit: is this a good interface for textures?
	virtual ITexture *		GetTextureValue( void )
	{
		return &g_DummyTexture;
	}

	virtual void			SetTextureValue( ITexture * ) {}
	virtual					operator ITexture*()
	{
		return GetTextureValue();
	}

	virtual IMaterial *		GetMaterialValue( void )
	{
		extern IMaterial *g_pDummyMaterial;
		return g_pDummyMaterial;
	}

	virtual void			SetMaterialValue( IMaterial * ) {}

	virtual MaterialVarType_t	GetType() const { return MATERIAL_VAR_TYPE_INT; }
	virtual bool			IsDefined() const { return true; }
	virtual void			SetUndefined() {}

	// Matrix
	virtual void			SetMatrixValue( VMatrix const& matrix ) {}
	virtual const VMatrix  &GetMatrixValue( )
	{
		return g_DummyMatrix;
	}
	virtual bool			MatrixIsIdentity() const
	{
		return false;
	}

	// Copy....
	virtual void			CopyFrom( IMaterialVar *pMaterialVar ) {}

	virtual void			SetValueAutodetectType( char const *val ) {}

	virtual IMaterial *		GetOwningMaterial()
	{
		extern IMaterial *g_pDummyMaterial;
		return g_pDummyMaterial;
	}
};
CDummyMaterialVar g_DummyMaterialVar;


// ---------------------------------------------------------------------------------------- //
// Dummy implementation of IMaterialSystemHardwareConfig
// ---------------------------------------------------------------------------------------- //

class CDummyHardwareConfig : public IMaterialSystemHardwareConfig
{
public:
	virtual bool HasDestAlphaBuffer() const			{ return false; }
	virtual bool HasStencilBuffer() const			{ return false; }
	virtual int  StencilBufferBits() const			{ return 0;		}
	virtual int	 GetFrameBufferColorDepth() const	{ return 0; }
	virtual int  GetSamplerCount() const			{ return 0; }
	virtual bool HasSetDeviceGammaRamp() const		{ return false; }
	virtual bool SupportsCompressedTextures() const	{ return false; }
	virtual VertexCompressionType_t SupportsCompressedVertices() const { return VERTEX_COMPRESSION_NONE; }
	virtual bool SupportsVertexAndPixelShaders() const	{ return false; }
	virtual bool SupportsPixelShaders_1_4() const	{ return false; }
	virtual bool SupportsPixelShaders_2_0() const	{ return false; }
	virtual bool SupportsPixelShaders_2_b() const	{ return false; }
	virtual bool ActuallySupportsPixelShaders_2_b() const	{ return false; }
	virtual bool SupportsStaticControlFlow() const { return false; }
	virtual bool SupportsVertexShaders_2_0() const	{ return false; }
	virtual bool SupportsShaderModel_3_0() const	{ return false; }
	virtual int  MaximumAnisotropicLevel() const	{ return 1; }
	virtual int  MaxTextureWidth() const			{ return 0; }
	virtual int  MaxTextureHeight() const			{ return 0; }
	virtual int  MaxTextureDepth() const			{ return 0; }
	virtual int	 TextureMemorySize() const			{ return 0; }
	virtual bool SupportsOverbright() const			{ return false; }
	virtual bool SupportsCubeMaps() const			{ return false; }
	virtual bool SupportsMipmappedCubemaps() const	{ return false; }
	virtual bool SupportsNonPow2Textures() const	{ return false; }

	// The number of texture stages represents the number of computations
	// we can do in the pixel pipeline, it is *not* related to the
	// simultaneous number of textures we can use
	virtual int  GetTextureStageCount() const		{ return 0; }
	virtual int	 NumVertexShaderConstants() const	{ return 0; }
	virtual int	 NumBooleanVertexShaderConstants() const	{ return 0; }
	virtual int	 NumIntegerVertexShaderConstants() const	{ return 0; }
	virtual int	 NumPixelShaderConstants() const	{ return 0; }
	virtual int	 MaxNumLights() const				{ return 0; }
	virtual bool SupportsHardwareLighting() const	{ return false; }
	virtual int	 MaxBlendMatrices() const			{ return 0; }
	virtual int	 MaxBlendMatrixIndices() const		{ return 0; }
	virtual int	 MaxTextureAspectRatio() const		{ return 0; }
	virtual int	 MaxVertexShaderBlendMatrices() const	{ return 0; }
	virtual int	 MaxUserClipPlanes() const			{ return 0; }
	virtual bool UseFastClipping() const			{ return false; }
	virtual bool UseFastZReject() const				{ return false; }
	virtual bool PreferReducedFillrate() const		{ return false; }

	// This here should be the major item looked at when checking for compat
	// from anywhere other than the material system	shaders
	virtual int	 GetDXSupportLevel() const			{ return 90; }
	virtual const char *GetShaderDLLName() const	{ return NULL; }

	virtual bool ReadPixelsFromFrontBuffer() const	{ return false; }

	// Are dx dynamic textures preferred?
	virtual bool PreferDynamicTextures() const		{ return false; }

	virtual bool SupportsHDR() const				{ return false; }
	virtual HDRType_t GetHDRType() const			{ return HDR_TYPE_NONE; }
	virtual HDRType_t GetHardwareHDRType() const	{ return HDR_TYPE_NONE; }

	virtual bool HasProjectedBumpEnv() const		{ return false; }
	virtual bool SupportsSpheremapping() const		{ return false; }
	virtual bool NeedsAAClamp() const				{ return false; }
	virtual bool HasFastZReject() const				{ return false; }
	virtual bool NeedsATICentroidHack() const		{ return false; }
	virtual bool SupportsColorOnSecondStream() const{ return false; }
	virtual bool SupportsStaticPlusDynamicLighting() const{ return false; }
	virtual bool SupportsStreamOffset() const		{ return false; }
	virtual int	 GetMaxDXSupportLevel() const		{ return 90; }
	virtual bool SpecifiesFogColorInLinearSpace() const { return false; }
	virtual bool SupportsSRGB() const				{ return false; }
	virtual bool FakeSRGBWrite() const				{ return false; }
	virtual bool CanDoSRGBReadFromRTs() const		{ return true; }
	virtual bool SupportsGLMixedSizeTargets() const	{ return false; }
	virtual bool IsAAEnabled() const				{ return false; }
	virtual int GetVertexTextureCount() const		{ return 0; }
	virtual int GetMaxVertexTextureDimension() const { return 0; }
	virtual int MaxViewports() const { return 1; }
	virtual void OverrideStreamOffsetSupport( bool bOverrideEnabled, bool bEnableSupport ) {}
	virtual int GetShadowFilterMode() const { return 0; }
	virtual int NeedsShaderSRGBConversion() const { return 0; }
	bool UsesSRGBCorrectBlending() const { return false; }
	virtual bool HasFastVertexTextures() const { return false; }
	virtual int MaxHWMorphBatchCount() const { return 0; }
	virtual bool SupportsHDRMode( HDRType_t nMode ) const { return 0; }
	virtual bool IsDX10Card() const { return 0; }
	virtual bool GetHDREnabled( void ) const { return true; }
	virtual void SetHDREnabled( bool bEnable ) {}
	virtual bool SupportsBorderColor( void ) const { return true; }
	virtual bool SupportsFetch4( void ) const { return false; }
	virtual bool CanStretchRectFromTextures() const { return false; }
};
CDummyHardwareConfig g_DummyHardwareConfig;


// ---------------------------------------------------------------------------------------- //
// CDummyMaterial.
// ---------------------------------------------------------------------------------------- //

class CDummyMaterial : public IMaterial
{
public:
	virtual const char *	GetName() const { return "dummy material"; }
	virtual const char *	GetTextureGroupName() const { return "dummy group"; }

	virtual PreviewImageRetVal_t GetPreviewImageProperties( int *width, int *height, 
				 			ImageFormat *imageFormat, bool* isTranslucent ) const
	{
		if ( width )
			*width = 4;

		if ( height )
			*height = 4;

		if ( imageFormat )
			*imageFormat = IMAGE_FORMAT_RGBA8888;

		if ( isTranslucent )
			*isTranslucent = false;

		return MATERIAL_PREVIEW_IMAGE_OK;
	}
	
	virtual PreviewImageRetVal_t GetPreviewImage( unsigned char *data, 
												 int width, int height,
												 ImageFormat imageFormat ) const
	{
		return MATERIAL_PREVIEW_IMAGE_OK;
	}
											    
	// 
	virtual int				GetMappingWidth( )
	{
		return 512;
	}

	virtual int				GetMappingHeight( )
	{
		return 512;
	}

	virtual int				GetNumAnimationFrames( )
	{
		return 0;
	}

	virtual bool			InMaterialPage( void ) 
	{
		return false;
	}

	virtual void			GetMaterialOffset( float *pOffset  )
	{
		pOffset[0] = 0.0f;
		pOffset[1] = 0.0f;
	}

	virtual void			GetMaterialScale( float *pScale )
	{
		pScale[0] = 1.0f;
		pScale[1] = 1.0f;
	}

	virtual IMaterial			*GetMaterialPage( void )
	{
		return NULL;
	}

	virtual IMaterialVar *	FindVar( const char *varName, bool *found, bool complain = true )
	{
		if ( found )
			*found = true;

		return &g_DummyMaterialVar;
	}
	virtual IMaterialVar *	FindVarFast( const char *varName, unsigned int *pToken )
	{
		return NULL;
	}

	virtual void			IncrementReferenceCount( void )
	{
	}

	virtual void			DecrementReferenceCount( void )
	{
	}

	virtual int 			GetEnumerationID( void ) const
	{
		return 0;
	}

	virtual void			GetLowResColorSample( float s, float t, float *color ) const
	{
	}

	virtual void			RecomputeStateSnapshots()
	{
	}


	// Are we translucent?
	virtual bool			IsTranslucent()
	{
		return false;
	}

	// Are we alphatested?
	virtual bool			IsAlphaTested()
	{
		return false;
	}

	// Are we vertex lit?
	virtual bool			IsVertexLit()
	{
		return false;
	}

	// Gets the vertex format
	virtual VertexFormat_t	GetVertexFormat() const
	{
		return 0;
	}

	// returns true if this material uses a material proxy
	virtual bool			HasProxy( void ) const
	{
		return false;
	}
	virtual void			CallBindProxy( void* ) {}

	virtual IMaterial		*CheckProxyReplacement( void *proxyData ) 
	{ 
		return this; 
	}

	virtual bool			UsesEnvCubemap( void )
	{
		return false;
	}

	virtual bool			NeedsTangentSpace( void )
	{
		return false;
	}

	virtual bool			NeedsPowerOfTwoFrameBufferTexture( bool bCheckSpecificToThisFrame )
	{
		return false;
	}

	virtual bool			NeedsFullFrameBufferTexture( bool bCheckSpecificToThisFrame )
	{
		return false;
	}

	virtual bool			NeedsSoftwareSkinning( void )
	{
		return false;
	}

	// Apply constant color or alpha modulation
	virtual void			AlphaModulate( float alpha )
	{
	}

	virtual void			ColorModulate( float r, float g, float b )
	{
	}

	float					GetAlphaModulation( )
	{ 
		return 1;
	}

	void					GetColorModulation( float *r, float *g, float *b )
	{ 
		*r = *g = *b = 1;
	}

	// Material Var flags...
	virtual void			SetMaterialVarFlag( MaterialVarFlags_t flag, bool on )
	{
	}

	virtual bool			GetMaterialVarFlag( MaterialVarFlags_t flag ) const
	{
		return true;
	}


	// Gets material reflectivity
	virtual void			GetReflectivity( Vector& reflect )
	{
		reflect.Init(1,0,0);
	}


	// Gets material property flags
	virtual bool			GetPropertyFlag( MaterialPropertyTypes_t type )
	{
		return true;
	}

	// Is the material visible from both sides?
	virtual bool			IsTwoSided()
	{
		return false;
	}

	// Sets the shader associated with the material
	virtual void			SetShader( const char *pShaderName )
	{
	}

	// Can't be const because the material might have to precache itself.
	virtual int				GetNumPasses( void )
	{
		return 1;
	}

	// Can't be const because the material might have to precache itself.
	virtual int				GetTextureMemoryBytes( void )
	{
		return 64;
	}

	// Meant to be used with materials created using CreateMaterial
	// It updates the materials to reflect the current values stored in the material vars
	virtual void			Refresh()
	{
	}

	// GR - returns true is material uses lightmap alpha for blending
	virtual bool			NeedsLightmapBlendAlpha( void )
	{
		return false;
	}

	// returns true if the shader doesn't do lighting itself and requires
	// the data that is sent to it to be prelighted
	virtual bool			NeedsSoftwareLighting( void )
	{
		return false;
	}

	// Gets at the shader parameters
	virtual int				ShaderParamCount() const
	{
		return 0;
	}

	virtual IMaterialVar	**GetShaderParams( void )
	{
		return 0;
	}

	virtual bool IsErrorMaterial() const
	{
		return false;
	}
	virtual void SetUseFixedFunctionBakedLighting( bool bEnable ) 
	{ 
	}
	virtual MorphFormat_t GetMorphFormat() const
	{
		return 0;
	}
	virtual void SetShaderAndParams( KeyValues *pKeyValues )
	{
	}
	virtual const char *GetShaderName() const { return "Wireframe"; }
		
	virtual void		DeleteIfUnreferenced() {}
	virtual bool IsSpriteCard() { return false; }

	virtual void			RefreshPreservingMaterialVars() {};

	virtual bool			WasReloadedFromWhitelist() {return false;}

	virtual bool			IsPrecached() const {return true;}
};

CDummyMaterial g_DummyMaterial;
IMaterial *g_pDummyMaterial = &g_DummyMaterial;


void* DummyMaterialSystemFactory( const char *pName, int *pReturnCode )
{
	if ( stricmp( pName, MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION ) == 0 )
		return &g_DummyHardwareConfig;

	else
		return NULL;
}


// ---------------------------------------------------------------------------------------- //
// Dummy morph
// ---------------------------------------------------------------------------------------- //
class CDummyMorph : public IMorph
{
public:
	virtual void Lock( float flFloatToFixedScale ) {}
	virtual void AddMorph( const MorphVertexInfo_t &info ) {}
	virtual void Unlock(  ) {}
	virtual void AccumulateMorph( int nWeightCount, const MorphWeight_t* pWeights ) {}
};


// ---------------------------------------------------------------------------------------- //
// CDummyMaterialSystem.
// ---------------------------------------------------------------------------------------- //
class CDummyMaterialSystem : public IMaterialSystemStub, public CRefCounted1<IMatRenderContext, CRefCountServiceNull>
{
private:
	IMaterialSystem *m_pRealMaterialSystem;
public:
	CDummyMaterialSystem()
	{
		m_pRealMaterialSystem = 0;
	}

	virtual void	SetRealMaterialSystem( IMaterialSystem *pSys )
	{
		m_pRealMaterialSystem = pSys;
	}

	
	// Call this to initialize the material system
	// returns a method to create interfaces in the shader dll
	virtual CreateInterfaceFn	Init( char const* pShaderDLL, 
									  IMaterialProxyFactory *pMaterialProxyFactory,
									  CreateInterfaceFn fileSystemFactory,
									  CreateInterfaceFn cvarFactory )
	{
		return DummyMaterialSystemFactory;
	}

	virtual void				Shutdown( )
	{
	}

	virtual IMaterialSystemHardwareConfig *GetHardwareConfig( const char *pVersion, int *returnCode )
	{
		if ( returnCode )
			*returnCode = 1;

		return &g_DummyHardwareConfig;
	}

	// Gets the number of adapters...
	virtual int					GetDisplayAdapterCount() const
	{
		return 0;
	}

	// Returns info about each adapter
	virtual void				GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const
	{
	}

	// Returns the number of modes
	virtual int					GetModeCount( int adapter ) const
	{
		return 0;
	}

	// Returns mode information..
	virtual void				GetModeInfo( int adapter, int mode, MaterialVideoMode_t& info ) const
	{
	}

	// Returns the mode info for the current display device
	virtual void				GetDisplayMode( MaterialVideoMode_t& mode ) const
	{
	}
 
	// Sets the mode...
	virtual bool				SetMode( void* hwnd, const MaterialSystem_Config_t &config )
	{
		return true;
	}

	// Creates/ destroys a child window
	virtual bool				AddView( void* hwnd )
	{
		return false;
	}
	virtual void				RemoveView( void* hwnd )
	{
	}

	// Sets the view
	virtual void				SetView( void* hwnd )
	{
	}

	// return true if lightmaps need to be redownloaded
	// Call this before rendering each frame with the current config
	// for the material system.
	// Will do whatever is necessary to get the material system into the correct state
	// upon configuration change. .doesn't much else otherwise.
	virtual bool				UpdateConfig( bool forceUpdate )
	{
		return false;
	}
	
	virtual bool				OverrideConfig( const MaterialSystem_Config_t &config, bool bForceUpdate )
	{
		return false;
	}

	// This is the interface for knowing what materials are available
	// is to use the following functions to get a list of materials.  The
	// material names will have the full path to the material, and that is the 
	// only way that the directory structure of the materials will be seen through this
	// interface.
	// NOTE:  This is mostly for worldcraft to get a list of materials to put
	// in the "texture" browser.in Worldcraft
	virtual MaterialHandle_t	FirstMaterial() const
	{
		return 0;
	}

	// returns InvalidMaterial if there isn't another material.
	// WARNING: you must call GetNextMaterial until it returns NULL, 
	// otherwise there will be a memory leak.
	virtual MaterialHandle_t	NextMaterial( MaterialHandle_t h ) const
	{
		return 0;
	}

	// This is the invalid material
	virtual MaterialHandle_t	InvalidMaterial() const
	{
		if ( m_pRealMaterialSystem )
			return m_pRealMaterialSystem->InvalidMaterial();
		else
			return 0;
	}

	// Returns a particular material
	virtual IMaterial*			GetMaterial( MaterialHandle_t h ) const
	{
		if ( m_pRealMaterialSystem )
			return m_pRealMaterialSystem->GetMaterial( h );
		else
			return &g_DummyMaterial;
	}

	// Find a material by name.
	// The name of a material is a full path to 
	// the vmt file starting from "hl2/materials" (or equivalent) without
	// a file extension.
	// eg. "dev/dev_bumptest" refers to somethign similar to:
	// "d:/hl2/hl2/materials/dev/dev_bumptest.vmt"
	virtual IMaterial *FindMaterial( char const* pMaterialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL )
	{
		if ( m_pRealMaterialSystem )
			return m_pRealMaterialSystem->FindMaterial( pMaterialName, pTextureGroupName, complain, pComplainPrefix );
		return &g_DummyMaterial;
	}

	virtual bool IsMaterialLoaded( char const* pMaterialName )
	{
		if ( m_pRealMaterialSystem )
			return m_pRealMaterialSystem->IsMaterialLoaded( pMaterialName );
		return true;
	}

	virtual IMaterial *FindMaterialEx( char const* pMaterialName, const char *pTextureGroupName, int nContext, bool complain = true, const char *pComplainPrefix = NULL )
	{
		if ( m_pRealMaterialSystem )
			return m_pRealMaterialSystem->FindMaterialEx( pMaterialName, pTextureGroupName, nContext, complain, pComplainPrefix );
		return &g_DummyMaterial;
	}

	virtual IMaterial *FindProceduralMaterial( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues )
	{
		if ( m_pRealMaterialSystem )
			return m_pRealMaterialSystem->FindProceduralMaterial( pMaterialName, pTextureGroupName, pVMTKeyValues );
		return &g_DummyMaterial;
	}

	virtual ITexture *FindTexture( char const* pTextureName, const char *pTextureGroupName, bool complain = true, int nAdditionalCreationFlags = 0)
	{
		if ( m_pRealMaterialSystem )
			return m_pRealMaterialSystem->FindTexture( pTextureName, pTextureGroupName, complain, nAdditionalCreationFlags );
		return &g_DummyTexture;
	}

	virtual void SetAsyncTextureLoadCache( FileCacheHandle_t hFileCache )
	{
	}

	virtual void BindLocalCubemap( ITexture *pTexture )
	{
	}
	virtual ITexture *GetLocalCubemap( )
	{
		return &g_DummyTexture;
	}
	
	// pass in an ITexture (that is build with "rendertarget" "1") or
	// pass in NULL for the regular backbuffer.
	virtual void				SetRenderTarget( ITexture *pTexture )
	{
	}
	
	virtual ITexture *			GetRenderTarget( void )
	{
		return &g_DummyTexture;
	}
	
	virtual void				SetRenderTargetEx( int nRenderTargetID, ITexture *pTexture )
	{
	}
	
	virtual ITexture *			GetRenderTargetEx( int nRenderTargetID )
	{
		return &g_DummyTexture;
	}
	virtual void				GetRenderTargetDimensions( int &width, int &height) const
	{
		width = 256;
		height = 256;
	}
	
	// Get the total number of materials in the system.  These aren't just the used
	// materials, but the complete collection.
	virtual int					GetNumMaterials( ) const
	{
		return m_pRealMaterialSystem->GetNumMaterials();
	}

	// Remove any materials from memory that aren't in use as determined
	// by the IMaterial's reference count.
	virtual void				UncacheUnusedMaterials( bool bRecomputeStateSnapshots )
	{
		if ( m_pRealMaterialSystem )
		{
			m_pRealMaterialSystem->UncacheUnusedMaterials( bRecomputeStateSnapshots );
		}
	}

	virtual void				SuspendTextureStreaming( )
	{
		if ( m_pRealMaterialSystem )
			m_pRealMaterialSystem->SuspendTextureStreaming();
	}

	virtual void				ResumeTextureStreaming( )
	{
		if ( m_pRealMaterialSystem )
			m_pRealMaterialSystem->ResumeTextureStreaming();
	}

	// uncache all materials. .  good for forcing reload of materials.
	virtual void				UncacheAllMaterials( )
	{
		if ( m_pRealMaterialSystem )
			m_pRealMaterialSystem->UncacheAllMaterials();
	}

	// Load any materials into memory that are to be used as determined
	// by the IMaterial's reference count.
	virtual void				CacheUsedMaterials( )
	{
		if ( m_pRealMaterialSystem )
			m_pRealMaterialSystem->CacheUsedMaterials( );
	}
	
	// Force all textures to be reloaded from disk.
	virtual void				ReloadTextures( )
	{
	}
	
	// Allows us to override the depth buffer setting of a material
	virtual void	OverrideDepthEnable( bool bEnable, bool bEnableValue )
	{
	}

	virtual void	OverrideAlphaWriteEnable( bool bOverrideEnable, bool bAlphaWriteEnable )
	{
	}

	virtual void	OverrideColorWriteEnable( bool bOverrideEnable, bool bColorWriteEnable )
	{
	}

	//
	// lightmap allocation stuff
	//

	// To allocate lightmaps, sort the whole world by material twice.
	// The first time through, call AllocateLightmap for every surface.
	// that has a lightmap.
	// The second time through, call AllocateWhiteLightmap for every 
	// surface that expects to use shaders that expect lightmaps.
	virtual void				BeginLightmapAllocation( )
	{
	}
	// returns the sorting id for this surface
	virtual int 				AllocateLightmap( int width, int height, 
		                                          int offsetIntoLightmapPage[2],
												  IMaterial *pMaterial )
	{
		return 0;
	}
	// returns a lightmap page ID for this allocation, -1 if none available
	virtual int	AllocateDynamicLightmap( int lightmapSize[2], int *pOutOffsetIntoPage, int frameID )
	{
		return -1;
	}

	// returns the sorting id for this surface
	virtual int					AllocateWhiteLightmap( IMaterial *pMaterial )
	{
		return 0;
	}
	virtual void				EndLightmapAllocation( )
	{
	}

	// lightmaps are in linear color space
	// lightmapPageID is returned by GetLightmapPageIDForSortID
	// lightmapSize and offsetIntoLightmapPage are returned by AllocateLightmap.
	// You should never call UpdateLightmap for a lightmap allocated through
	// AllocateWhiteLightmap.
	virtual void				UpdateLightmap( int lightmapPageID, int lightmapSize[2],
												int offsetIntoLightmapPage[2], 
												float *pFloatImage, float *pFloatImageBump1,
												float *pFloatImageBump2, float *pFloatImageBump3 )
	{
	}
	// Force the lightmaps updated with UpdateLightmap to be sent to the hardware.
	virtual void				FlushLightmaps( )
	{
	}

	// fixme: could just be an array of ints for lightmapPageIDs since the material
	// for a surface is already known.
	virtual int					GetNumSortIDs( )
	{
		return 10;
	}
//	virtual int					GetLightmapPageIDForSortID( int sortID ) = 0;
	virtual void				GetSortInfo( MaterialSystem_SortInfo_t *pSortInfoArray )
	{
	}

	virtual void				BeginFrame( float )
	{
	}
	virtual void				EndFrame( )
	{
	}
	virtual bool				IsInFrame() const { return false; }

	// Bind a material is current for rendering.
	virtual void				Bind( IMaterial *material, void *proxyData = 0 )
	{
	}
	// Bind a lightmap page current for rendering.  You only have to 
	// do this for materials that require lightmaps.
	virtual void				BindLightmapPage( int lightmapPageID )
	{
	}

	// inputs are between 0 and 1
	virtual void				DepthRange( float zNear, float zFar )
	{
	}

	virtual void				ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil )
	{
	}

	virtual void				ClearBuffersObeyStencil( bool bClearColor, bool bClearDepth )
	{
	}

	virtual void				ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth )
	{
	}

	virtual void				PerformFullScreenStencilOperation( void )
	{
	}

	// read to a unsigned char rgb image.
	virtual void				ReadPixels( int x, int y, int width, int height, unsigned char *data, ImageFormat dstFormat )
	{
	}

	// Read w/ stretch to a host-memory buffer
	virtual void				ReadPixelsAndStretch( Rect_t *pSrcRect, Rect_t *pDstRect, unsigned char *pBuffer, ImageFormat dstFormat, int nDstStride )
	{
	}

	// Sets lighting
	virtual void				SetAmbientLight( float r, float g, float b )
	{
	}
	virtual void				SetLight( int lightNum, const LightDesc_t& desc )
	{
	}
	virtual void				SetLightingOrigin( Vector vLightingOrigin )
	{
	}

	// The faces of the cube are specified in the same order as cubemap textures
	virtual void				SetAmbientLightCube( Vector4D cube[6] )
	{
	}
	
	// Blit the backbuffer to the framebuffer texture
	virtual void				CopyRenderTargetToTexture( ITexture * )
	{
	}
	
	virtual void				SetFrameBufferCopyTexture( ITexture *pTexture, int textureIndex )
	{
	}

	virtual	ITexture *          GetFrameBufferCopyTexture( int textureIndex )
	{
		return &g_DummyTexture;
	}

	// do we need this?
	virtual void				Flush( bool flushHardware = false )
	{
	}

	//
	// end vertex array api
	//

	//
	// Debugging tools
	//
	virtual void				DebugPrintUsedMaterials( const char *pSearchSubString, bool bVerbose )
	{
	}
	virtual void				DebugPrintUsedTextures( void )
	{
	}
	virtual void				ToggleSuppressMaterial( char const* pMaterialName )
	{
	}
	virtual void				ToggleDebugMaterial( char const* pMaterialName )
	{
	}

	// matrix api
	virtual void				MatrixMode( MaterialMatrixMode_t matrixMode )
	{
	}
	virtual void				PushMatrix( void )
	{
	}
	virtual void				PopMatrix( void )
	{
	}
/*
	virtual void				LoadMatrix( float * )
	{
	}
*/
	// Methods that use VMatrix
	virtual void		LoadMatrix( const VMatrix& matrix )
	{
	}

	virtual void		LoadMatrix( const matrix3x4_t& matrix )
	{
	}

	virtual void		LoadBoneMatrix( int boneIndex, const matrix3x4_t& matrix )
	{
	}

	virtual void		MultMatrix( const VMatrix& matrix )
	{
	}

	virtual void		MultMatrix( const matrix3x4_t& matrix )
	{
	}
	virtual void		MultMatrixLocal( const VMatrix& matrix )
	{
	}

	virtual void		MultMatrixLocal( const matrix3x4_t& matrix )
	{
	}
	virtual void				GetMatrix( MaterialMatrixMode_t matrixMode, VMatrix *pMatrix )
	{
		pMatrix->Identity();
	}
	virtual void				GetMatrix( MaterialMatrixMode_t matrixMode, matrix3x4_t *pMatrix )
	{
		SetIdentityMatrix( *pMatrix );
	}
	virtual void				LoadIdentity( void )
	{
	}
	virtual void				Ortho( double left, double top, double right, double bottom, double zNear, double zFar )
	{
	}
	virtual void				PerspectiveX( double fovx, double aspect, double zNear, double zFar )
	{
	}
	virtual void				PickMatrix( int x, int y, int width, int height )
	{
	}
	virtual void				Rotate( float angle, float x, float y, float z )
	{
	}
	virtual void				Translate( float x, float y, float z )
	{
	}
	virtual void				Scale( float x, float y, float z )
	{
	}
	// end matrix api

	// Sets/gets the viewport
	virtual void				Viewport( int x, int y, int width, int height )
	{
	}
	virtual void				GetViewport( int& x, int& y, int& width, int& height ) const
	{
		x = y = 0;
		width = height = 640;
	}

	// The cull mode
	virtual void				CullMode( MaterialCullMode_t cullMode )
	{
	}

	// end matrix api

	// Force writes only when z matches. . . useful for stenciling things out
	// by rendering the desired Z values ahead of time.
//	virtual void				ForceDepthFuncEquals( bool bEnable ) = 0;
//	virtual void				RenderZOnlyWithHeightClip( bool bEnable ) = 0;
	// This could easily be extended to a general user clip plane
	virtual void				SetHeightClipMode( MaterialHeightClipMode_t nClipMode )
	{
	}
	virtual MaterialHeightClipMode_t GetHeightClipMode( )
	{
		return MATERIAL_HEIGHTCLIPMODE_DISABLE;
	}
	// garymcthack : fog z is always used for heightclipz for now.
	virtual void				SetHeightClipZ( float z )
	{
	}
	
	// Fog methods...
	virtual void				FogMode( MaterialFogMode_t fogMode )
	{
	}
	MaterialFogMode_t			GetFogMode( void )
	{
		return MATERIAL_FOG_NONE;
	}
	virtual void				FogStart( float fStart )
	{
	}
	virtual void				FogEnd( float fEnd )
	{
	}
	virtual void				FogMaxDensity( float flMaxDensity )
	{
	}

	virtual void				SetFogZ( float fogZ )
	{
	}
	virtual void				GetFogDistances( float *fStart, float *fEnd, float *fFogZ )
	{
	}

	virtual void				FogColor3f( float r, float g, float b )
	{
	}
	virtual void				FogColor3fv( float const* rgb )
	{
	}
	virtual void				FogColor3ub( unsigned char r, unsigned char g, unsigned char b )
	{
	}
	virtual void				FogColor3ubv( unsigned char const* rgb )
	{
	}

	virtual void				GetFogColor( unsigned char *rgb )
	{
	}

	// Sets the number of bones for skinning
	virtual void				SetNumBoneWeights( int numBones ) 
	{
	}
	virtual IMaterialProxyFactory *GetMaterialProxyFactory()
	{
		return NULL;
	}
	
	virtual void	SetMaterialProxyFactory( IMaterialProxyFactory* pFactory )
	{
	}

	// Read the page size of an existing lightmap by sort id (returned from AllocateLightmap())
	virtual void				GetLightmapPageSize( int lightmap, int *width, int *height ) const
	{
		if ( m_pRealMaterialSystem )
			m_pRealMaterialSystem->GetLightmapPageSize( lightmap, width, height );
		else
			*width = *height = 32;
	}
	
	/// FIXME: This stuff needs to be cleaned up and abstracted.
	// Stuff that gets exported to the launcher through the engine
	virtual void				SwapBuffers( )
	{
	}

	// Use this to spew information about the 3D layer 
	virtual void				SpewDriverInfo() const
	{
	}

	// Creates/destroys Mesh
	virtual IMesh* CreateStaticMesh( VertexFormat_t fmt, const char *pTextureBudgetGroup, IMaterial * pMaterial )
	{
		return GetDummyMesh();
	}
	virtual void DestroyStaticMesh( IMesh* mesh )
	{
	}

	// Gets the dynamic mesh associated with the currently bound material
	// note that you've got to render the mesh before calling this function 
	// a second time. Clients should *not* call DestroyStaticMesh on the mesh 
	// returned by this call.
	// Use buffered = false if you want to not have the mesh be buffered,
	// but use it instead in the following pattern:
	//		meshBuilder.Begin
	//		meshBuilder.End
	//		Draw partial
	//		Draw partial
	//		Draw partial
	//		meshBuilder.Begin
	//		meshBuilder.End
	//		etc
	// Use Vertex or Index Override to supply a static vertex or index buffer
	// to use in place of the dynamic buffers.
	//
	// If you pass in a material in pAutoBind, it will automatically bind the
	// material. This can be helpful since you must bind the material you're
	// going to use BEFORE calling GetDynamicMesh.
	virtual IMesh* GetDynamicMesh( bool bBuffered = true, IMesh* pVertexOverride = 0,	
		IMesh* pIndexOverride = 0, IMaterial *pAutoBind = 0 )
	{
		return GetDummyMesh();
	}

	virtual IMesh* GetDynamicMeshEx( VertexFormat_t vertexFormat, bool bBuffered = true, 
		IMesh* pVertexOverride = 0,	IMesh* pIndexOverride = 0, IMaterial *pAutoBind = 0 )
	{
		return GetDummyMesh();
	}

	virtual IMesh *GetFlexMesh()
	{
		return GetDummyMesh();
	}
		
	// Selection mode methods
	virtual int  SelectionMode( bool selectionMode )
	{
		return 0;
	}
	virtual void SelectionBuffer( unsigned int* pBuffer, int size )
	{
	}
	virtual void ClearSelectionNames( )
	{
	}
	virtual void LoadSelectionName( int name )
	{
	}
	virtual void PushSelectionName( int name )
	{
	}
	virtual void PopSelectionName()
	{
	}
	
	// Installs a function to be called when we need to release vertex buffers + textures
	virtual void AddReleaseFunc( MaterialBufferReleaseFunc_t func )
	{
	}
	virtual void RemoveReleaseFunc( MaterialBufferReleaseFunc_t func )
	{
	}

	// Installs a function to be called when we need to restore vertex buffers
	virtual void AddRestoreFunc( MaterialBufferRestoreFunc_t func )
	{
	}
	virtual void RemoveRestoreFunc( MaterialBufferRestoreFunc_t func )
	{
	}

	// Stuff for probing properties of shaders.
	virtual int					GetNumShaders( void ) const 
	{
		return 0;
	}
	virtual const char *		GetShaderName( int shaderID ) const
	{
		return NULL;
	}
	virtual int					GetNumShaderParams( int shaderID ) const
	{
		return 0;
	}
	virtual const char *		GetShaderParamName( int shaderID, int paramID ) const
	{
		return NULL;
	}
	virtual const char *		GetShaderParamHelp( int shaderID, int paramID ) const
	{
		return NULL;
	}
	virtual ShaderParamType_t	GetShaderParamType( int shaderID, int paramID ) const
	{
		return ( enum ShaderParamType_t )0;
	}
	virtual const char *		GetShaderParamDefault( int shaderID, int paramID ) const
	{
		return NULL;
	}

	// Reloads materials
	virtual void	ReloadMaterials( const char *pSubString = NULL )
	{
	}

	virtual void	ResetMaterialLightmapPageInfo()
	{
	}

	virtual ITexture* CreateRenderTargetTexture( 
		int w, 
		int h, 
		RenderTargetSizeMode_t sizeMode,	// Controls how size is generated (and regenerated on video mode change).
		ImageFormat format, 
		MaterialRenderTargetDepth_t depth )
	{
		return &g_DummyTexture;
	}

	virtual ITexture *CreateProceduralTexture( 
		const char			*pTextureName, 
		const char			*pTextureGroupName, 
		int					w, 
		int					h, 
		ImageFormat			fmt, 
		int					nFlags )
	{
		return &g_DummyTexture;
	}

	// Sets the Clear Color for ClearBuffer....
	virtual void ClearColor3ub( unsigned char r, unsigned char g, unsigned char b )
	{
	}
	virtual void ClearColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
	{
	}
	virtual void SetInStubMode( bool b )
	{
	}

	// Create new materials
	virtual IMaterial	*CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues )
	{
		return &g_DummyMaterial;
	}

	void GetBackBufferDimensions( int &w, int &h ) const
	{
		w = 1024;
		h = 768;
	}
	
	ImageFormat GetBackBufferFormat( void ) const
	{
		return IMAGE_FORMAT_RGBA8888;
	}
	
	// FIXME: This is a hack required for NVidia/XBox, can they fix in drivers?
	virtual void	DrawScreenSpaceQuad( IMaterial* pMaterial ) {}

	// FIXME: Test interface
	virtual bool Connect( CreateInterfaceFn factory ) { return true; }
	virtual void Disconnect() {}
	virtual void *QueryInterface( const char *pInterfaceName ) { return NULL; }
	virtual InitReturnVal_t Init() { return INIT_OK; }
	virtual void SetShaderAPI( const char *pShaderAPIDLL ) {}
	virtual void SetAdapter( int nAdapter, int nFlags ) {}

	// Release temporary HW memory...
	virtual void ResetTempHWMemory( bool bExitingLevel ) {}
	virtual ITexture*	CreateNamedRenderTargetTextureEx( 
		const char *pRTName,				// Pass in NULL here for an unnamed render target.
		int w, 
		int h, 
		RenderTargetSizeMode_t sizeMode,	// Controls how size is generated (and regenerated on video mode change).
		ImageFormat format, 
		MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, 
		unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
		unsigned int renderTargetFlags = 0
		)
	{
		return &g_DummyTexture;
	}
	virtual ITexture* CreateNamedRenderTargetTexture( 
		const char *pRTName, 
		int w, 
		int h, 
		RenderTargetSizeMode_t sizeMode,	// Controls how size is generated (and regenerated on video mode change).
		ImageFormat format, 
		MaterialRenderTargetDepth_t depth,
		bool bClampTexCoords, 
		bool bAutoMipMap
		)
	{
		return &g_DummyTexture;
	}
	virtual void SyncToken( const char *pToken ) {}
	virtual float	ComputePixelWidthOfSphere( const Vector& origin, float flRadius )
	{
		return 1.0f;
	}
	virtual float	ComputePixelDiameterOfSphere( const Vector& origin, float flRadius )
	{
		return 1.0f;
	}

	OcclusionQueryObjectHandle_t CreateOcclusionQueryObject( void )
	{
		return INVALID_OCCLUSION_QUERY_OBJECT_HANDLE;
	}

	void DestroyOcclusionQueryObject( OcclusionQueryObjectHandle_t handle )
	{
	}

	void ResetOcclusionQueryObject( OcclusionQueryObjectHandle_t hOcclusionQuery ) {}

	void BeginOcclusionQueryDrawing( OcclusionQueryObjectHandle_t handle )
	{
	}

	void EndOcclusionQueryDrawing( OcclusionQueryObjectHandle_t handle )
	{
	}

	int OcclusionQuery_GetNumPixelsRendered( OcclusionQueryObjectHandle_t handle )
	{
		return 0;
	}
	virtual void SetFlashlightMode( bool )
	{
	}
	virtual bool GetFlashlightMode( void ) const
	{
		return false;
	}
	virtual bool InFlashlightMode( void ) const
	{
		return false;
	}
	virtual void SetFlashlightState( const FlashlightState_t &state, const VMatrix &worldToTexture )
	{
	}
	virtual void SetFlashlightStateEx( const FlashlightState_t &state, const VMatrix &worldToTexture, ITexture *pFlashlightDepthTexture )
	{
	}

	virtual void SetScissorRect( const int nLeft, const int nTop, const int nRight, const int nBottom, const bool bEnableScissor )
	{
	}

	virtual void PushDeformation( DeformationBase_t const *Deformation )
	{
	}

	virtual void PopDeformation( )
	{
	}

	virtual int GetNumActiveDeformations() const
	{
		return 0;
	}



	// Get the current config for this video card (as last set by control panel or the default if not)
	virtual const MaterialSystem_Config_t &GetCurrentConfigForVideoCard() const
	{
		static MaterialSystem_Config_t dummy;
		return dummy;
	}

	// Get video card identitier
	virtual const MaterialSystemHardwareIdentifier_t &GetVideoCardIdentifier( void ) const
	{
		static MaterialSystemHardwareIdentifier_t dummy;
		return dummy;
	}
	virtual void AddModeChangeCallBack( ModeChangeCallbackFunc_t func )
	{
	}
	virtual void RemoveModeChangeCallBack( ModeChangeCallbackFunc_t func )
	{
	}
	virtual bool GetRecommendedConfigurationInfo( int nDxLevel, KeyValues *pKeyValues )
	{
		return false;
	}

	virtual void EnableUserClipTransformOverride( bool bEnable )
	{
	}

	virtual void UserClipTransform( const VMatrix &worldToProjection )
	{
	}

	// Used to iterate over all shaders for editing purposes
	virtual int	 ShaderCount() const
	{
		return 0;
	}

	virtual int  GetShaders( int nFirstShader, int nCount, IShader **ppShaderList ) const
	{
		return 0;
	}

	// Used to enable editor materials. Must be called before Init.
	virtual void	EnableEditorMaterials()
	{
	}

	// Used to enable editor materials. Must be called before Init.
	virtual int		GetCurrentAdapter()	const
	{
		return 0;
	}

	virtual char *GetDisplayDeviceName() const OVERRIDE
	{
		return "";
	}

	// Creates/destroys morph data associated w/ a particular material
	IMorph *CreateMorph( MorphFormat_t, const char *pDebugName )
	{
		static CDummyMorph s_DummyMorph;
		return &s_DummyMorph;
	}

	void DestroyMorph( IMorph *pMorph )
	{
	}

	void BindMorph( IMorph *pMorph )
	{
	}

	// Sets morph target factors
	virtual void SetMorphTargetFactors( int nTargetId, float *pValue, int nCount )
	{
	}

	virtual void SetToneMappingScaleLinear( const Vector &scale )
	{
	}

	virtual void EvictManagedResources()
	{
	}

	// Gets the window size
	virtual void	GetWindowSize( int &width, int &height ) const
	{
		width = height = 0;
		if ( m_pRealMaterialSystem )
		{
			CMatRenderContextPtr pRenderContext( m_pRealMaterialSystem );
			pRenderContext->GetWindowSize(width, height);
		}
	}

	// For dealing with device lost in cases where SwapBuffers isn't called all the time (Hammer)
	virtual void HandleDeviceLost()
	{
	}

	virtual void AppUsesRenderTargets()
	{
	}

	virtual void DrawScreenSpaceRectangle( 
		IMaterial *pMaterial,
		int destx, int desty,
		int width, int height,
		float src_texture_x0, float src_texture_y0,
		float src_texture_x1, float src_texture_y1,	
		int src_texture_width, int src_texture_height,
		void *pClientRenderable = NULL,
		int nXDice = 1,
		int nYDice = 1 )
	{
	}

	virtual void BeginRenderTargetAllocation()
	{
	}

	// Simulate an Alt-Tab in here, which causes a release/restore of all resources
	virtual void EndRenderTargetAllocation()
	{
	}

	ITexture *CreateNamedRenderTargetTextureEx2( 
		const char *pRTName,				// Pass in NULL here for an unnamed render target.
		int w, 
		int h, 
		RenderTargetSizeMode_t sizeMode,	// Controls how size is generated (and regenerated on video mode change).
		ImageFormat format, 
		MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, 
		unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
		unsigned int renderTargetFlags = 0
		)
	{
		return NULL;
	};

	void PushRenderTargetAndViewport( )
	{
	}

	void PushRenderTargetAndViewport( ITexture *pTexture )
	{
	}

	void PushRenderTargetAndViewport( ITexture *pTexture, int nViewX, int nViewY, int nViewW, int nViewH )
	{
	}

	void PushRenderTargetAndViewport( ITexture *pTexture, ITexture *pDepthTexture, int nViewX, int nViewY, int nViewW, int nViewH )
	{
	}

	void PopRenderTargetAndViewport( void )
	{
	}

	virtual int ShaderFlagCount() const
	{
		return 0;
	}

	virtual const char *ShaderFlagName( int nIndex ) const
	{
		return "";
	}

	virtual void BindLightmapTexture( ITexture *pLightmapTexture )
	{
	}

	// Returns the currently active shader fallback for a particular shader
	virtual void GetShaderFallback( const char *pShaderName, char *pFallbackShader, int nFallbackLength )
	{
		pFallbackShader[0] = 0;
	}

#ifdef DX_TO_GL_ABSTRACTION
	virtual void DoStartupShaderPreloading( void )
	{
	}
#endif

	// Blit a subrect of the current render target to another texture
	virtual void CopyRenderTargetToTextureEx( ITexture *pTexture, int nRenderTargetID, Rect_t *pSrcRect, Rect_t *pDstRect = NULL )
	{
	}

	virtual void CopyTextureToRenderTargetEx( int nRenderTargetID, ITexture *pTexture, Rect_t *pSrcRect, Rect_t *pDstRect = NULL )
	{
	}

	bool IsTextureLoaded( char const* pTextureName ) const
	{
		return false;
	}

	void PerspectiveOffCenterX( double fovx, double aspect, double zNear, double zFar, double bottom, double top, double left, double right )
	{
	}

	void SetFloatRenderingParameter(int parm_number, float value)
	{
	}

	void SetIntRenderingParameter(int parm_number, int value)
	{
	}
	void SetVectorRenderingParameter(int parm_number, Vector const &value)
	{
	}

	float GetFloatRenderingParameter(int parm_number) const
	{
		return 0;
	}

	int GetIntRenderingParameter(int parm_number) const
	{
		return 0;
	}

	Vector GetVectorRenderingParameter(int parm_number) const
	{
		return Vector(0,0,0);
	}
	
	void ReleaseResources(void)
	{
	}

	void ReacquireResources(void)
	{
	}

	Vector GetToneMappingScaleLinear( void )
	{
		return Vector(1,1,1);
	}

	virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices )
	{
		*pMaxVerts = 32768;
		*pMaxIndices = 32768;
	}

	// Returns the max possible vertices + indices to render in a single draw call
	virtual int GetMaxVerticesToRender( IMaterial *pMaterial )
	{
		return 32768;
	}

	virtual int GetMaxIndicesToRender( )
	{
		return 32768;
	}

	// stencil buffer operations.
	virtual void SetStencilEnable(bool onoff)
	{
	}

	virtual void SetStencilFailOperation(StencilOperation_t op)
	{
	}

	virtual void SetStencilZFailOperation(StencilOperation_t op)
	{
	}

	virtual void SetStencilPassOperation(StencilOperation_t op)
	{
	}

	virtual void SetStencilCompareFunction(StencilComparisonFunction_t cmpfn)
	{
	}

	virtual void SetStencilReferenceValue(int ref)
	{
	}

	virtual void SetStencilTestMask(uint32 msk)
	{
	}

	virtual void SetStencilWriteMask(uint32 msk) 
	{
	}

	virtual void ClearStencilBufferRectangle(int xmin, int ymin, int xmax, int ymax, int value)
	{
	}

	virtual void ModInit()
	{
	}

	virtual void ModShutdown()
	{
	}

	virtual void EnableColorCorrection( bool bEnable ) {}
	virtual ColorCorrectionHandle_t AddLookup( const char *pName ) { return 0; }
	virtual bool RemoveLookup( ColorCorrectionHandle_t handle ) { return true; }
	virtual void LockLookup( ColorCorrectionHandle_t handle ) {}
	virtual void LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ) {}
	virtual void UnlockLookup( ColorCorrectionHandle_t handle ) {}
	virtual void SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ) {}
	virtual void ResetLookupWeights( ) {}
	virtual void SetResetable( ColorCorrectionHandle_t handle, bool bResetable ) {}

	virtual void PushCustomClipPlane( const float *pPlane )
	{
	}

	virtual void PopCustomClipPlane( void )
	{
	}

	virtual bool EnableClipping( bool bEnable )
	{
		return true;
	}

	virtual void PushHeightClipPlane( void )
	{
	}
	void ResetToneMappingScale( float sc)
	{
	}
	void TurnOnToneMapping()
	{
	}

	virtual void GetDXLevelDefaults(uint &max_dxlevel,uint &recommended_dxlevel)
	{
		max_dxlevel=recommended_dxlevel=90;
	}

	virtual bool UsingFastClipping( void )
	{
		return true; //true for "crappier" hardware, so true is safer than false
	}

	virtual int StencilBufferBits( void )
	{
		return 0;
	}

	virtual void DisableAllLocalLights() {}
	virtual int CompareMaterialCombos( IMaterial *pMaterial1, IMaterial *pMaterial2, int lightmapID1, int lightmapID2 ) { return 0; }

	virtual bool SupportsMSAAMode( int nMSAAMode ) { return false; }
	virtual bool SupportsCSAAMode( int nNumSamples, int nQualityLevel ) { return false; }
	virtual bool SupportsHDRMode( HDRType_t nHDRModede ) { return false; }
	virtual bool IsDX10Card() { return false; }

	// Hooks for firing PIX events from outside the Material System...
	virtual void BeginPIXEvent( unsigned long color, const char *szName ) {};
	virtual void EndPIXEvent() {};
	virtual void SetPIXMarker( unsigned long color, const char *szName ) {};

	virtual IMatRenderContext *GetRenderContext() { return this; }

	void BeginRender() {}
	void BeginRender( float ) {}
	void EndRender() {}

	virtual void							SetThreadMode( MaterialThreadMode_t, int ) {}
	virtual MaterialThreadMode_t			GetThreadMode( ) { return MATERIAL_SINGLE_THREADED; }
	virtual bool							IsRenderThreadSafe( ) { return true; }
	virtual bool							AllowThreading( bool bAllow, int nServiceThread ) { return false; }
	virtual void							ExecuteQueued() {}

	virtual void BeginBatch( IMesh* pIndices ) {}
	virtual void BindBatch( IMesh* pVertices, IMaterial *pAutoBind = NULL ) {}
	virtual void DrawBatch(int nFirstIndex, int nIndexCount )  {}
	virtual void EndBatch()  {}

	virtual void SetGoalToneMappingScale(float) {}

	virtual bool SupportsShadowDepthTextures( void ) { return false; }

	virtual bool SupportsFetch4( void ) { return false; }


	virtual void SetShadowDepthBiasFactors( float fShadowSlopeScaleDepthBias, float fShadowDepthBias ) {}

	virtual ICallQueue *GetCallQueue() { return NULL; }
	virtual void GetWorldSpaceCameraPosition( Vector *pCameraPos )
	{
		pCameraPos->Init();
	}
	virtual void GetWorldSpaceCameraVectors( Vector *pVecForward, Vector *pVecRight, Vector *pVecUp )
	{
		if ( pVecForward )
		{
			pVecForward->Init( 1, 0, 0 );
		}
		if ( pVecRight )
		{
			pVecRight->Init( 0, -1, 0 );
		}
		if ( pVecUp )
		{
			pVecUp->Init( 0, 0, 1 );
		}
	}

	virtual void BeginUpdateLightmaps() {}
	virtual void EndUpdateLightmaps() {}

	virtual MaterialLock_t		Lock() { return NULL; }
	virtual void				Unlock( MaterialLock_t ) {}

	virtual ImageFormat GetShadowDepthTextureFormat() { return IMAGE_FORMAT_UNKNOWN; }

	virtual IMatRenderContext *CreateRenderContext( MaterialContextType_t type )
	{
		return RetAddRef( (IMatRenderContext *)this );
	}

	virtual IMatRenderContext *SetRenderContext( IMatRenderContext *pContext )
	{
		SafeRelease( pContext );
		return RetAddRef( this );
	}
	virtual IVertexBuffer *		GetDynamicVertexBuffer( /*VertexFormat_t vertexFormat, */bool buffered = true )
	{
		Assert( 0 );
		return NULL;
//		return GetDummyMesh();
	}
	virtual IIndexBuffer *		GetDynamicIndexBuffer( /*MaterialIndexFormat_t fmt, */bool buffered = true )
	{
		Assert( 0 );
		return NULL;
//		return GetDummyMesh();
	}

// ------------ New Vertex/Index Buffer interface ----------------------------
	virtual IVertexBuffer *CreateStaticVertexBuffer( VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroup )
	{
		Assert( 0 );
		return NULL;
	}
	virtual IIndexBuffer *CreateStaticIndexBuffer( MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroup )
	{
		Assert( 0 );
		return NULL;
	}
	virtual void DestroyVertexBuffer( IVertexBuffer * )
	{
	}
	virtual void DestroyIndexBuffer( IIndexBuffer * )
	{
	}
	// Do we need to specify the stream here in the case of locking multiple dynamic VBs on different streams?
	virtual IVertexBuffer *GetDynamicVertexBuffer( int streamID, VertexFormat_t vertexFormat, bool bBuffered = true )
	{
		Assert( 0 );
		return NULL;
	}
	virtual IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true )
	{
		Assert( 0 );
		return NULL;
	}
	virtual void BindVertexBuffer( int streamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, int nFirstVertex, int nVertexCount, VertexFormat_t fmt, int nRepetitions = 1 )
	{
	}
	virtual void BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes )
	{
	}
	virtual void Draw( MaterialPrimitiveType_t primitiveType, int nFirstIndex, int nIndexCount )
	{
	}
	virtual void BeginMorphAccumulation()
	{
	}
	virtual void EndMorphAccumulation()
	{
	}
	virtual void AccumulateMorph( IMorph* pMorph, int nMorphCount, const MorphWeight_t* pWeights )
	{
	}
	virtual bool GetMorphAccumulatorTexCoord( Vector2D *pTexCoord, IMorph *pMorph, int nVertex )
	{
		pTexCoord->Init();
		return false;
	}
// ------------ End ----------------------------

	virtual ImageFormat GetNullTextureFormat() { return IMAGE_FORMAT_UNKNOWN; }

	virtual void AddTextureAlias( const char *pAlias, const char *pRealName ) {}
	virtual void RemoveTextureAlias( const char *pAlias ) {}

	virtual void SetExcludedTextures( const char *pScriptName ) {}
	virtual void UpdateExcludedTextures( void ) {}

	virtual void SetFlexWeights( int nFirstWeight, int nCount, const MorphWeight_t* pWeights ) {}

	virtual bool SupportsBorderColor() { return false; }

	virtual IMaterial *GetCurrentMaterial() { return NULL; }
	virtual int  GetCurrentNumBones() const { return 0; }
	virtual void *GetCurrentProxy() { return NULL; }

	virtual void SetFullScreenDepthTextureValidityFlag( bool bIsValid ) {}

	// A special path used to tick the front buffer while loading on the 360
	virtual void SetNonInteractivePacifierTexture( ITexture *pTexture, float flNormalizedX, float flNormalizedY, float flNormalizedSize ) {}
	virtual void SetNonInteractiveTempFullscreenBuffer( ITexture *pTexture, MaterialNonInteractiveMode_t mode ) {}
	virtual void EnableNonInteractiveMode( MaterialNonInteractiveMode_t mode ) {}
	virtual void RefreshFrontBufferNonInteractive() {}

	virtual void *			LockRenderData( int nSizeInBytes ) { return NULL; }
	virtual void			UnlockRenderData( void *pData ) {}
	virtual bool			IsRenderData( const void *pData ) const { return false; }
	virtual void			AddRefRenderData() {}
	virtual void			ReleaseRenderData() {}
#if defined( _X360 )
	virtual void				ListUsedMaterials( void ) {}
	virtual HXUIFONT			OpenTrueTypeFont( const char *pFontname, int tall, int style )
	{
		return (HXUIFONT)0;
	}
	virtual void				CloseTrueTypeFont( HXUIFONT hFont ) {}
	virtual bool				GetTrueTypeFontMetrics( HXUIFONT hFont, XUIFontMetrics *pFontMetrics, XUICharMetrics charMetrics[256] ) 
	{
		pFontMetrics->fLineHeight = 0.0f;
		pFontMetrics->fMaxAscent = 0.0f;
		pFontMetrics->fMaxDescent = 0.0f;
		pFontMetrics->fMaxWidth = 0.0f;
		pFontMetrics->fMaxHeight = 0.0f;
		pFontMetrics->fMaxAdvance = 0.0f;
		return true;
	}

	virtual bool				GetTrueTypeGlyphs( HXUIFONT hFont, int numChars, wchar_t *pWch, int *pOffsetX, int *pOffsetY, int *pWidth, int *pHeight, unsigned char *pRGBA, int *pRGBAOffset )
	{
		return false;
	}

	virtual void				PersistDisplay() {}
	virtual void				*GetD3DDevice() { return NULL; }

	virtual void				PushVertexShaderGPRAllocation( int iVertexShaderCount = 64 ) { };
	virtual void				PopVertexShaderGPRAllocation( void ) { };

	virtual bool				OwnGPUResources( bool bEnable ) { return false; }
#endif

	virtual void				CompactMemory() {}

	// For sv_pure mode. The filesystem figures out which files the client needs to reload to be "pure" ala the server's preferences.
	virtual void ReloadFilesInList( IFileList *pFilesToReload )
	{
	}

	virtual void				PrintfVA( char *fmt, va_list vargs ) {}
	virtual void				Printf( const char *fmt, ... ) {}
	virtual float				Knob( char *knobname, float *setvalue=NULL ) { return 0.0f; }

	virtual void				SetRenderTargetFrameBufferSizeOverrides( int nWidth, int nHeight ) OVERRIDE
	{
		// Nope.
	}
	virtual void				GetRenderTargetFrameBufferDimensions( int & nWidth, int & nHeight ) OVERRIDE
	{
		GetBackBufferDimensions( nWidth, nHeight );
	}

	virtual ITexture*			CreateTextureFromBits(int w, int h, int mips, ImageFormat fmt, int srcBufferSize, byte* srcBits)
	{
		return NULL;	
	}

	virtual void OverrideRenderTargetAllocation( bool )
	{
		// anda
	
	}

	virtual ITextureCompositor*	NewTextureCompositor( int w, int h, const char* pCompositeName, int nTeamNum, uint64 randomSeed, KeyValues* stageDesc, uint texCompositeCreateFlags ) OVERRIDE
	{
		return NULL;	
	}

	virtual void AsyncFindTexture( const char* pFilename, const char *pTextureGroupName, IAsyncTextureOperationReceiver* pRecipient, void* pExtraArgs, bool bComplain = true, int nAdditionalCreationFlags = 0 )
	{

	}

	virtual void AsyncCreateTextureFromRenderTarget( ITexture* pSrcRt, const char* pDstName, ImageFormat dstFmt, bool bGenMips, int nAdditionalCreationFlags, IAsyncTextureOperationReceiver* pRecipient, void* pExtraArgs )
	{

	}
	
	virtual ITexture*			CreateNamedTextureFromBitsEx( const char* pName, const char *pTextureGroupName, int w, int h, int mips, ImageFormat fmt, int srcBufferSize, byte* srcBits, int nFlags )
	{
		return NULL;
	}

	virtual bool				AddTextureCompositorTemplate( const char* pName, KeyValues* pTmplDesc, int nTexCompositeTemplateFlags ) OVERRIDE
	{
		return false;
	}

	virtual bool VerifyTextureCompositorTemplates() OVERRIDE
	{
		return false;	
	}

};


static CDummyMaterialSystem g_DummyMaterialSystem;

EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CDummyMaterialSystem, IMaterialSystemStub, 
						MATERIAL_SYSTEM_STUB_INTERFACE_VERSION, g_DummyMaterialSystem );