diff options
| author | Narendra Umate <[email protected]> | 2013-12-02 23:36:05 -0800 |
|---|---|---|
| committer | Narendra Umate <[email protected]> | 2013-12-02 23:36:05 -0800 |
| commit | 8737f191f3b59f001a77bf6c08091109211c1c9f (patch) | |
| tree | dbbf05c004d9b026f2c1f23f06600fe0add82c36 /mp/src/public/materialsystem | |
| parent | Update .gitignore. (diff) | |
| parent | Make .xcconfigs text files too. (diff) | |
| download | source-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.tar.xz source-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'mp/src/public/materialsystem')
22 files changed, 8833 insertions, 8833 deletions
diff --git a/mp/src/public/materialsystem/IColorCorrection.h b/mp/src/public/materialsystem/IColorCorrection.h index b3bcbb98..1aa0c246 100644 --- a/mp/src/public/materialsystem/IColorCorrection.h +++ b/mp/src/public/materialsystem/IColorCorrection.h @@ -1,73 +1,73 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//===========================================================================//
-
-#ifndef ICOLORCORRECTION_H
-#define ICOLORCORRECTION_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier1/interface.h"
-#include "bitmap/imageformat.h"
-
-typedef unsigned int ColorCorrectionHandle_t;
-struct ShaderColorCorrectionInfo_t;
-
-#define COLORCORRECTION_INTERFACE_VERSION "COLORCORRECTION_VERSION_1"
-
-abstract_class IColorCorrectionSystem
-{
-public:
- virtual void Init() = 0;
- virtual void Shutdown() = 0;
-
- virtual ColorCorrectionHandle_t AddLookup( const char *pName ) = 0;
- virtual bool RemoveLookup( ColorCorrectionHandle_t handle ) = 0;
-
- virtual void SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ) = 0;
- virtual float GetLookupWeight( ColorCorrectionHandle_t handle ) = 0;
- virtual float GetLookupWeight( int i ) = 0;
-
- virtual void LockLookup() = 0;
- virtual void LockLookup( ColorCorrectionHandle_t handle ) = 0;
-
- virtual void UnlockLookup() = 0;
- virtual void UnlockLookup( ColorCorrectionHandle_t handle ) = 0;
-
- virtual void SetLookup( RGBX5551_t inColor, color24 outColor ) = 0;
- virtual void SetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor, color24 outColor ) = 0;
-
- virtual color24 GetLookup( RGBX5551_t inColor ) = 0;
- virtual color24 GetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor ) = 0;
-
- virtual void LoadLookup( const char *pLookupName ) = 0;
- virtual void LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ) = 0;
-
- virtual void CopyLookup( const color24 *pSrcColorCorrection ) = 0;
- virtual void CopyLookup( ColorCorrectionHandle_t handle, const color24 *pSrcColorCorrection ) = 0;
-
- virtual void ResetLookup( ColorCorrectionHandle_t handle ) = 0;
- virtual void ResetLookup( ) = 0;
-
- virtual void ReleaseTextures( ) = 0;
- virtual void RestoreTextures( ) = 0;
-
- virtual void ResetLookupWeights( ) = 0;
-
- virtual int GetNumLookups( ) = 0;
-
- virtual color24 ConvertToColor24( RGBX5551_t inColor ) = 0;
-
- virtual void SetResetable( ColorCorrectionHandle_t handle, bool bResetable ) = 0;
-
- virtual void EnableColorCorrection( bool bEnable ) = 0;
-
- // FIXME: Move this to a private interface only the material system can see?
- virtual void GetCurrentColorCorrection( ShaderColorCorrectionInfo_t* pInfo ) = 0;
-};
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef ICOLORCORRECTION_H +#define ICOLORCORRECTION_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "bitmap/imageformat.h" + +typedef unsigned int ColorCorrectionHandle_t; +struct ShaderColorCorrectionInfo_t; + +#define COLORCORRECTION_INTERFACE_VERSION "COLORCORRECTION_VERSION_1" + +abstract_class IColorCorrectionSystem +{ +public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + + virtual ColorCorrectionHandle_t AddLookup( const char *pName ) = 0; + virtual bool RemoveLookup( ColorCorrectionHandle_t handle ) = 0; + + virtual void SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ) = 0; + virtual float GetLookupWeight( ColorCorrectionHandle_t handle ) = 0; + virtual float GetLookupWeight( int i ) = 0; + + virtual void LockLookup() = 0; + virtual void LockLookup( ColorCorrectionHandle_t handle ) = 0; + + virtual void UnlockLookup() = 0; + virtual void UnlockLookup( ColorCorrectionHandle_t handle ) = 0; + + virtual void SetLookup( RGBX5551_t inColor, color24 outColor ) = 0; + virtual void SetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor, color24 outColor ) = 0; + + virtual color24 GetLookup( RGBX5551_t inColor ) = 0; + virtual color24 GetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor ) = 0; + + virtual void LoadLookup( const char *pLookupName ) = 0; + virtual void LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ) = 0; + + virtual void CopyLookup( const color24 *pSrcColorCorrection ) = 0; + virtual void CopyLookup( ColorCorrectionHandle_t handle, const color24 *pSrcColorCorrection ) = 0; + + virtual void ResetLookup( ColorCorrectionHandle_t handle ) = 0; + virtual void ResetLookup( ) = 0; + + virtual void ReleaseTextures( ) = 0; + virtual void RestoreTextures( ) = 0; + + virtual void ResetLookupWeights( ) = 0; + + virtual int GetNumLookups( ) = 0; + + virtual color24 ConvertToColor24( RGBX5551_t inColor ) = 0; + + virtual void SetResetable( ColorCorrectionHandle_t handle, bool bResetable ) = 0; + + virtual void EnableColorCorrection( bool bEnable ) = 0; + + // FIXME: Move this to a private interface only the material system can see? + virtual void GetCurrentColorCorrection( ShaderColorCorrectionInfo_t* pInfo ) = 0; +}; + +#endif diff --git a/mp/src/public/materialsystem/IShader.h b/mp/src/public/materialsystem/IShader.h index 5d6b22d2..27bf91e3 100644 --- a/mp/src/public/materialsystem/IShader.h +++ b/mp/src/public/materialsystem/IShader.h @@ -1,205 +1,205 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-
-#ifndef ISHADER_H
-#define ISHADER_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-//==================================================================================================
-// **this goes into both platforms which run the translator, either the real Mac client or
-// the Windows client running with r_emulategl mode **
-//
-// size of the VS register bank in ARB / GLSL we expose
-// it's not 256, because you can't use all 256 slots in 10.5.x.
-// use this constant everywhere you might normally use "256" in reference to a parameter array size.
-// The highest shader constant is c218, plus we allocate c219 and c220 for two clip planes
-#define DXABSTRACT_VS_PARAM_SLOTS 219
-#define DXABSTRACT_VS_FIRST_BONE_SLOT VERTEX_SHADER_MODEL
-
-// user clip plane 0 goes in DXABSTRACT_VS_CLIP_PLANE_BASE... plane 1 goes in the slot after that
-// dxabstract uses these constants to check plane index limit and to deliver planes to shader for DP4 -> oCLP[n]
-#define DXABSTRACT_VS_CLIP_PLANE_BASE (DXABSTRACT_VS_PARAM_SLOTS-2)
-
-//==================================================================================================
-
-
-#include "materialsystem/imaterialsystem.h"
-#include "materialsystem/ishaderapi.h"
-
-//-----------------------------------------------------------------------------
-// forward declarations
-//-----------------------------------------------------------------------------
-class IMaterialVar;
-class IShaderShadow;
-class IShaderDynamicAPI;
-class IShaderInit;
-class CBasePerMaterialContextData;
-
-//-----------------------------------------------------------------------------
-// Shader flags
-//-----------------------------------------------------------------------------
-enum ShaderFlags_t
-{
- SHADER_NOT_EDITABLE = 0x1
-};
-
-
-//-----------------------------------------------------------------------------
-// Shader parameter flags
-//-----------------------------------------------------------------------------
-enum ShaderParamFlags_t
-{
- SHADER_PARAM_NOT_EDITABLE = 0x1
-};
-
-
-//-----------------------------------------------------------------------------
-// Information about each shader parameter
-//-----------------------------------------------------------------------------
-struct ShaderParamInfo_t
-{
- const char *m_pName;
- const char *m_pHelp;
- ShaderParamType_t m_Type;
- const char *m_pDefaultValue;
- int m_nFlags;
-};
-
-
-//-----------------------------------------------------------------------------
-// Standard vertex shader constants
-//-----------------------------------------------------------------------------
-enum
-{
- // Standard vertex shader constants
- VERTEX_SHADER_MATH_CONSTANTS0 = 0,
- VERTEX_SHADER_MATH_CONSTANTS1 = 1,
- VERTEX_SHADER_CAMERA_POS = 2,
- VERTEX_SHADER_FLEXSCALE = 3, // used by DX9 only!
- VERTEX_SHADER_LIGHT_INDEX = 3, // used by DX8 only!
- VERTEX_SHADER_MODELVIEWPROJ = 4,
- VERTEX_SHADER_VIEWPROJ = 8,
- VERTEX_SHADER_MODELVIEWPROJ_THIRD_ROW = 12,
- VERTEX_SHADER_VIEWPROJ_THIRD_ROW = 13,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_10 = 14,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_11 = 15,
- VERTEX_SHADER_FOG_PARAMS = 16,
- VERTEX_SHADER_VIEWMODEL = 17,
- VERTEX_SHADER_AMBIENT_LIGHT = 21,
- VERTEX_SHADER_LIGHTS = 27,
- VERTEX_SHADER_LIGHT0_POSITION = 29,
- VERTEX_SHADER_MODULATION_COLOR = 47,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 = 48,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_1 = 49,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 = 50,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 = 51,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_4 = 52,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 = 53,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 = 54,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_7 = 55,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_8 = 56,
- VERTEX_SHADER_SHADER_SPECIFIC_CONST_9 = 57,
- VERTEX_SHADER_MODEL = 58,
-
- //
- // We reserve up through 216 for the 53 bones
- //
-
- // 219 ClipPlane0 |------ OpenGL will jam clip planes into these two
- // 220 ClipPlane1 |
-
- VERTEX_SHADER_FLEX_WEIGHTS = 1024,
- VERTEX_SHADER_MAX_FLEX_WEIGHT_COUNT = 512,
-};
-
-#define VERTEX_SHADER_BONE_TRANSFORM( k ) ( VERTEX_SHADER_MODEL + 3 * (k) )
-
-//-----------------------------------------------------------------------------
-// Standard vertex shader constants
-//-----------------------------------------------------------------------------
-enum
-{
- // Standard vertex shader constants
- VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST = 0,
- VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST_COUNT = 4,
-
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_0 = 4,
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_1 = 5,
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_2 = 6,
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_3 = 7,
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_4 = 8,
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_5 = 9,
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_6 = 10,
- VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_7 = 11,
-};
-// The public methods exposed by each shader
-//-----------------------------------------------------------------------------
-abstract_class IShader
-{
-public:
- // Returns the shader name
- virtual char const* GetName( ) const = 0;
-
- // returns the shader fallbacks
- virtual char const* GetFallbackShader( IMaterialVar** params ) const = 0;
-
- // Shader parameters
- virtual int GetNumParams( ) const = 0;
-
- // These functions must be implemented by the shader
- virtual void InitShaderParams( IMaterialVar** ppParams, const char *pMaterialName ) = 0;
- virtual void InitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName, const char *pTextureGroupName ) = 0;
- virtual void DrawElements( IMaterialVar **params, int nModulationFlags,
- IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) = 0;
-
- virtual char const* GetParamName( int paramIndex ) const = 0;
- virtual char const* GetParamHelp( int paramIndex ) const = 0;
- virtual ShaderParamType_t GetParamType( int paramIndex ) const = 0;
- virtual char const* GetParamDefault( int paramIndex ) const = 0;
-
- // FIXME: Figure out a better way to do this?
- virtual int ComputeModulationFlags( IMaterialVar** params, IShaderDynamicAPI* pShaderAPI ) = 0;
- virtual bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame = true ) const = 0;
- virtual bool NeedsFullFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const = 0;
- virtual bool IsTranslucent( IMaterialVar **params ) const = 0;
-
- virtual int GetParamFlags( int paramIndex ) const = 0;
-
- virtual int GetFlags() const = 0;
-
- // FIXME: Remove GetParamName, etc. above
-// virtual const ShaderParamInfo_t& GetParamInfo( int paramIndex ) const = 0;
-};
-
-
-//-----------------------------------------------------------------------------
-// Shader dictionaries defined in DLLs
-//-----------------------------------------------------------------------------
-enum PrecompiledShaderType_t
-{
- PRECOMPILED_VERTEX_SHADER = 0,
- PRECOMPILED_PIXEL_SHADER,
-
- PRECOMPILED_SHADER_TYPE_COUNT,
-};
-
-
-//-----------------------------------------------------------------------------
-// Flags field of PrecompiledShader_t
-//-----------------------------------------------------------------------------
-enum
-{
- // runtime flags
- SHADER_DYNAMIC_COMPILE_IS_HLSL = 0x1,
- SHADER_FAILED_LOAD = 0x2,
-};
-
-#endif // ISHADER_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef ISHADER_H +#define ISHADER_H + +#ifdef _WIN32 +#pragma once +#endif + +//================================================================================================== +// **this goes into both platforms which run the translator, either the real Mac client or +// the Windows client running with r_emulategl mode ** +// +// size of the VS register bank in ARB / GLSL we expose +// it's not 256, because you can't use all 256 slots in 10.5.x. +// use this constant everywhere you might normally use "256" in reference to a parameter array size. +// The highest shader constant is c218, plus we allocate c219 and c220 for two clip planes +#define DXABSTRACT_VS_PARAM_SLOTS 219 +#define DXABSTRACT_VS_FIRST_BONE_SLOT VERTEX_SHADER_MODEL + +// user clip plane 0 goes in DXABSTRACT_VS_CLIP_PLANE_BASE... plane 1 goes in the slot after that +// dxabstract uses these constants to check plane index limit and to deliver planes to shader for DP4 -> oCLP[n] +#define DXABSTRACT_VS_CLIP_PLANE_BASE (DXABSTRACT_VS_PARAM_SLOTS-2) + +//================================================================================================== + + +#include "materialsystem/imaterialsystem.h" +#include "materialsystem/ishaderapi.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterialVar; +class IShaderShadow; +class IShaderDynamicAPI; +class IShaderInit; +class CBasePerMaterialContextData; + +//----------------------------------------------------------------------------- +// Shader flags +//----------------------------------------------------------------------------- +enum ShaderFlags_t +{ + SHADER_NOT_EDITABLE = 0x1 +}; + + +//----------------------------------------------------------------------------- +// Shader parameter flags +//----------------------------------------------------------------------------- +enum ShaderParamFlags_t +{ + SHADER_PARAM_NOT_EDITABLE = 0x1 +}; + + +//----------------------------------------------------------------------------- +// Information about each shader parameter +//----------------------------------------------------------------------------- +struct ShaderParamInfo_t +{ + const char *m_pName; + const char *m_pHelp; + ShaderParamType_t m_Type; + const char *m_pDefaultValue; + int m_nFlags; +}; + + +//----------------------------------------------------------------------------- +// Standard vertex shader constants +//----------------------------------------------------------------------------- +enum +{ + // Standard vertex shader constants + VERTEX_SHADER_MATH_CONSTANTS0 = 0, + VERTEX_SHADER_MATH_CONSTANTS1 = 1, + VERTEX_SHADER_CAMERA_POS = 2, + VERTEX_SHADER_FLEXSCALE = 3, // used by DX9 only! + VERTEX_SHADER_LIGHT_INDEX = 3, // used by DX8 only! + VERTEX_SHADER_MODELVIEWPROJ = 4, + VERTEX_SHADER_VIEWPROJ = 8, + VERTEX_SHADER_MODELVIEWPROJ_THIRD_ROW = 12, + VERTEX_SHADER_VIEWPROJ_THIRD_ROW = 13, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_10 = 14, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_11 = 15, + VERTEX_SHADER_FOG_PARAMS = 16, + VERTEX_SHADER_VIEWMODEL = 17, + VERTEX_SHADER_AMBIENT_LIGHT = 21, + VERTEX_SHADER_LIGHTS = 27, + VERTEX_SHADER_LIGHT0_POSITION = 29, + VERTEX_SHADER_MODULATION_COLOR = 47, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 = 48, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_1 = 49, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 = 50, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 = 51, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_4 = 52, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 = 53, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 = 54, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_7 = 55, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_8 = 56, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_9 = 57, + VERTEX_SHADER_MODEL = 58, + + // + // We reserve up through 216 for the 53 bones + // + + // 219 ClipPlane0 |------ OpenGL will jam clip planes into these two + // 220 ClipPlane1 | + + VERTEX_SHADER_FLEX_WEIGHTS = 1024, + VERTEX_SHADER_MAX_FLEX_WEIGHT_COUNT = 512, +}; + +#define VERTEX_SHADER_BONE_TRANSFORM( k ) ( VERTEX_SHADER_MODEL + 3 * (k) ) + +//----------------------------------------------------------------------------- +// Standard vertex shader constants +//----------------------------------------------------------------------------- +enum +{ + // Standard vertex shader constants + VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST = 0, + VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST_COUNT = 4, + + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_0 = 4, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_1 = 5, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_2 = 6, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_3 = 7, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_4 = 8, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_5 = 9, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_6 = 10, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_7 = 11, +}; +// The public methods exposed by each shader +//----------------------------------------------------------------------------- +abstract_class IShader +{ +public: + // Returns the shader name + virtual char const* GetName( ) const = 0; + + // returns the shader fallbacks + virtual char const* GetFallbackShader( IMaterialVar** params ) const = 0; + + // Shader parameters + virtual int GetNumParams( ) const = 0; + + // These functions must be implemented by the shader + virtual void InitShaderParams( IMaterialVar** ppParams, const char *pMaterialName ) = 0; + virtual void InitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName, const char *pTextureGroupName ) = 0; + virtual void DrawElements( IMaterialVar **params, int nModulationFlags, + IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) = 0; + + virtual char const* GetParamName( int paramIndex ) const = 0; + virtual char const* GetParamHelp( int paramIndex ) const = 0; + virtual ShaderParamType_t GetParamType( int paramIndex ) const = 0; + virtual char const* GetParamDefault( int paramIndex ) const = 0; + + // FIXME: Figure out a better way to do this? + virtual int ComputeModulationFlags( IMaterialVar** params, IShaderDynamicAPI* pShaderAPI ) = 0; + virtual bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame = true ) const = 0; + virtual bool NeedsFullFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const = 0; + virtual bool IsTranslucent( IMaterialVar **params ) const = 0; + + virtual int GetParamFlags( int paramIndex ) const = 0; + + virtual int GetFlags() const = 0; + + // FIXME: Remove GetParamName, etc. above +// virtual const ShaderParamInfo_t& GetParamInfo( int paramIndex ) const = 0; +}; + + +//----------------------------------------------------------------------------- +// Shader dictionaries defined in DLLs +//----------------------------------------------------------------------------- +enum PrecompiledShaderType_t +{ + PRECOMPILED_VERTEX_SHADER = 0, + PRECOMPILED_PIXEL_SHADER, + + PRECOMPILED_SHADER_TYPE_COUNT, +}; + + +//----------------------------------------------------------------------------- +// Flags field of PrecompiledShader_t +//----------------------------------------------------------------------------- +enum +{ + // runtime flags + SHADER_DYNAMIC_COMPILE_IS_HLSL = 0x1, + SHADER_FAILED_LOAD = 0x2, +}; + +#endif // ISHADER_H diff --git a/mp/src/public/materialsystem/MaterialSystemUtil.cpp b/mp/src/public/materialsystem/MaterialSystemUtil.cpp index 669de23b..ba63f007 100644 --- a/mp/src/public/materialsystem/MaterialSystemUtil.cpp +++ b/mp/src/public/materialsystem/MaterialSystemUtil.cpp @@ -1,255 +1,255 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $Workfile: $
-// $NoKeywords: $
-//===========================================================================//
-
-#include "materialsystem/MaterialSystemUtil.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/itexture.h"
-#include "materialsystem/imaterialsystem.h"
-#include "tier1/KeyValues.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Little utility class to deal with material references
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// constructor, destructor
-//-----------------------------------------------------------------------------
-CMaterialReference::CMaterialReference( char const* pMaterialName, const char *pTextureGroupName, bool bComplain ) : m_pMaterial( 0 )
-{
- if ( pMaterialName )
- {
- Assert( pTextureGroupName );
- Init( pMaterialName, pTextureGroupName, bComplain );
- }
-}
-
-CMaterialReference::~CMaterialReference()
-{
- Shutdown();
-}
-
-//-----------------------------------------------------------------------------
-// Attach to a material
-//-----------------------------------------------------------------------------
-void CMaterialReference::Init( char const* pMaterialName, const char *pTextureGroupName, bool bComplain )
-{
- IMaterial *pMaterial = materials->FindMaterial( pMaterialName, pTextureGroupName, bComplain);
- if( IsErrorMaterial( pMaterial ) )
- {
- if (IsOSX())
- {
- printf("\n ##### CMaterialReference::Init got error material for %s in tex group %s", pMaterialName, pTextureGroupName );
- }
- }
-
- Assert( pMaterial );
- Init( pMaterial );
-}
-
-void CMaterialReference::Init( const char *pMaterialName, KeyValues *pVMTKeyValues )
-{
- // CreateMaterial has a refcount of 1
- Shutdown();
- m_pMaterial = materials->CreateMaterial( pMaterialName, pVMTKeyValues );
-}
-
-void CMaterialReference::Init( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues )
-{
- IMaterial *pMaterial = materials->FindProceduralMaterial( pMaterialName, pTextureGroupName, pVMTKeyValues );
- Assert( pMaterial );
- Init( pMaterial );
-}
-
-void CMaterialReference::Init( IMaterial* pMaterial )
-{
- if ( m_pMaterial != pMaterial )
- {
- Shutdown();
- m_pMaterial = pMaterial;
- if ( m_pMaterial )
- {
- m_pMaterial->IncrementReferenceCount();
- }
- }
-}
-
-void CMaterialReference::Init( CMaterialReference& ref )
-{
- if ( m_pMaterial != ref.m_pMaterial )
- {
- Shutdown();
- m_pMaterial = ref.m_pMaterial;
- if (m_pMaterial)
- {
- m_pMaterial->IncrementReferenceCount();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Detach from a material
-//-----------------------------------------------------------------------------
-void CMaterialReference::Shutdown( )
-{
- if ( m_pMaterial && materials )
- {
- m_pMaterial->DecrementReferenceCount();
- m_pMaterial = NULL;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Little utility class to deal with texture references
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// constructor, destructor
-//-----------------------------------------------------------------------------
-CTextureReference::CTextureReference( ) : m_pTexture(NULL)
-{
-}
-
-CTextureReference::CTextureReference( const CTextureReference &ref )
-{
- m_pTexture = ref.m_pTexture;
- if ( m_pTexture )
- {
- m_pTexture->IncrementReferenceCount();
- }
-}
-
-void CTextureReference::operator=( CTextureReference &ref )
-{
- m_pTexture = ref.m_pTexture;
- if ( m_pTexture )
- {
- m_pTexture->IncrementReferenceCount();
- }
-}
-
-CTextureReference::~CTextureReference( )
-{
- Shutdown();
-}
-
-//-----------------------------------------------------------------------------
-// Attach to a texture
-//-----------------------------------------------------------------------------
-void CTextureReference::Init( char const* pTextureName, const char *pTextureGroupName, bool bComplain )
-{
- Shutdown();
- m_pTexture = materials->FindTexture( pTextureName, pTextureGroupName, bComplain );
- if ( m_pTexture )
- {
- m_pTexture->IncrementReferenceCount();
- }
-}
-
-void CTextureReference::Init( ITexture* pTexture )
-{
- Shutdown();
-
- m_pTexture = pTexture;
- if (m_pTexture)
- {
- m_pTexture->IncrementReferenceCount();
- }
-}
-
-void CTextureReference::InitProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags )
-{
- Shutdown();
-
- m_pTexture = materials->CreateProceduralTexture( pTextureName, pTextureGroupName, w, h, fmt, nFlags );
-
- // NOTE: The texture reference is already incremented internally above!
- /*
- if ( m_pTexture )
- {
- m_pTexture->IncrementReferenceCount();
- }
- */
-}
-
-void CTextureReference::InitRenderTarget( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName /* = NULL */ )
-{
- Shutdown();
-
- int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT;
- if ( depth == MATERIAL_RT_DEPTH_ONLY )
- textureFlags |= TEXTUREFLAGS_POINTSAMPLE;
-
- int renderTargetFlags = bHDR ? CREATERENDERTARGETFLAGS_HDR : 0;
-
- // NOTE: Refcount returned by CreateRenderTargetTexture is 1
- m_pTexture = materials->CreateNamedRenderTargetTextureEx( pStrOptionalName, w, h, sizeMode, fmt,
- depth, textureFlags, renderTargetFlags );
-
- Assert( m_pTexture );
-}
-
-//-----------------------------------------------------------------------------
-// Detach from a texture
-//-----------------------------------------------------------------------------
-void CTextureReference::Shutdown( bool bDeleteIfUnReferenced )
-{
- if ( m_pTexture && materials )
- {
- m_pTexture->DecrementReferenceCount();
- if ( bDeleteIfUnReferenced )
- {
- m_pTexture->DeleteIfUnreferenced();
- }
- m_pTexture = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Builds ONLY the system ram render target. Used when caller is explicitly managing.
-// The paired EDRAM surface can be built in an alternate format.
-//-----------------------------------------------------------------------------
-#if defined( _X360 )
-void CTextureReference::InitRenderTargetTexture( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName )
-{
- // other variants not implemented yet
- Assert( depth == MATERIAL_RT_DEPTH_NONE || depth == MATERIAL_RT_DEPTH_SHARED );
- Assert( !bHDR );
-
- int renderTargetFlags = CREATERENDERTARGETFLAGS_NOEDRAM;
-
- m_pTexture = materials->CreateNamedRenderTargetTextureEx(
- pStrOptionalName,
- w,
- h,
- sizeMode,
- fmt,
- depth,
- TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
- renderTargetFlags );
- Assert( m_pTexture );
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// Builds ONLY the EDRAM render target surface. Used when caller is explicitly managing.
-// The paired system memory texture can be built in an alternate format.
-//-----------------------------------------------------------------------------
-#if defined( _X360 )
-void CTextureReference::InitRenderTargetSurface( int width, int height, ImageFormat fmt, bool bSameAsTexture )
-{
- // texture has to be created first
- Assert( m_pTexture && m_pTexture->IsRenderTarget() );
-
- m_pTexture->CreateRenderTargetSurface( width, height, fmt, bSameAsTexture );
-}
-#endif
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $NoKeywords: $ +//===========================================================================// + +#include "materialsystem/MaterialSystemUtil.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/itexture.h" +#include "materialsystem/imaterialsystem.h" +#include "tier1/KeyValues.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Little utility class to deal with material references +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CMaterialReference::CMaterialReference( char const* pMaterialName, const char *pTextureGroupName, bool bComplain ) : m_pMaterial( 0 ) +{ + if ( pMaterialName ) + { + Assert( pTextureGroupName ); + Init( pMaterialName, pTextureGroupName, bComplain ); + } +} + +CMaterialReference::~CMaterialReference() +{ + Shutdown(); +} + +//----------------------------------------------------------------------------- +// Attach to a material +//----------------------------------------------------------------------------- +void CMaterialReference::Init( char const* pMaterialName, const char *pTextureGroupName, bool bComplain ) +{ + IMaterial *pMaterial = materials->FindMaterial( pMaterialName, pTextureGroupName, bComplain); + if( IsErrorMaterial( pMaterial ) ) + { + if (IsOSX()) + { + printf("\n ##### CMaterialReference::Init got error material for %s in tex group %s", pMaterialName, pTextureGroupName ); + } + } + + Assert( pMaterial ); + Init( pMaterial ); +} + +void CMaterialReference::Init( const char *pMaterialName, KeyValues *pVMTKeyValues ) +{ + // CreateMaterial has a refcount of 1 + Shutdown(); + m_pMaterial = materials->CreateMaterial( pMaterialName, pVMTKeyValues ); +} + +void CMaterialReference::Init( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ) +{ + IMaterial *pMaterial = materials->FindProceduralMaterial( pMaterialName, pTextureGroupName, pVMTKeyValues ); + Assert( pMaterial ); + Init( pMaterial ); +} + +void CMaterialReference::Init( IMaterial* pMaterial ) +{ + if ( m_pMaterial != pMaterial ) + { + Shutdown(); + m_pMaterial = pMaterial; + if ( m_pMaterial ) + { + m_pMaterial->IncrementReferenceCount(); + } + } +} + +void CMaterialReference::Init( CMaterialReference& ref ) +{ + if ( m_pMaterial != ref.m_pMaterial ) + { + Shutdown(); + m_pMaterial = ref.m_pMaterial; + if (m_pMaterial) + { + m_pMaterial->IncrementReferenceCount(); + } + } +} + +//----------------------------------------------------------------------------- +// Detach from a material +//----------------------------------------------------------------------------- +void CMaterialReference::Shutdown( ) +{ + if ( m_pMaterial && materials ) + { + m_pMaterial->DecrementReferenceCount(); + m_pMaterial = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Little utility class to deal with texture references +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CTextureReference::CTextureReference( ) : m_pTexture(NULL) +{ +} + +CTextureReference::CTextureReference( const CTextureReference &ref ) +{ + m_pTexture = ref.m_pTexture; + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } +} + +void CTextureReference::operator=( CTextureReference &ref ) +{ + m_pTexture = ref.m_pTexture; + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } +} + +CTextureReference::~CTextureReference( ) +{ + Shutdown(); +} + +//----------------------------------------------------------------------------- +// Attach to a texture +//----------------------------------------------------------------------------- +void CTextureReference::Init( char const* pTextureName, const char *pTextureGroupName, bool bComplain ) +{ + Shutdown(); + m_pTexture = materials->FindTexture( pTextureName, pTextureGroupName, bComplain ); + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } +} + +void CTextureReference::Init( ITexture* pTexture ) +{ + Shutdown(); + + m_pTexture = pTexture; + if (m_pTexture) + { + m_pTexture->IncrementReferenceCount(); + } +} + +void CTextureReference::InitProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags ) +{ + Shutdown(); + + m_pTexture = materials->CreateProceduralTexture( pTextureName, pTextureGroupName, w, h, fmt, nFlags ); + + // NOTE: The texture reference is already incremented internally above! + /* + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } + */ +} + +void CTextureReference::InitRenderTarget( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName /* = NULL */ ) +{ + Shutdown(); + + int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT; + if ( depth == MATERIAL_RT_DEPTH_ONLY ) + textureFlags |= TEXTUREFLAGS_POINTSAMPLE; + + int renderTargetFlags = bHDR ? CREATERENDERTARGETFLAGS_HDR : 0; + + // NOTE: Refcount returned by CreateRenderTargetTexture is 1 + m_pTexture = materials->CreateNamedRenderTargetTextureEx( pStrOptionalName, w, h, sizeMode, fmt, + depth, textureFlags, renderTargetFlags ); + + Assert( m_pTexture ); +} + +//----------------------------------------------------------------------------- +// Detach from a texture +//----------------------------------------------------------------------------- +void CTextureReference::Shutdown( bool bDeleteIfUnReferenced ) +{ + if ( m_pTexture && materials ) + { + m_pTexture->DecrementReferenceCount(); + if ( bDeleteIfUnReferenced ) + { + m_pTexture->DeleteIfUnreferenced(); + } + m_pTexture = NULL; + } +} + +//----------------------------------------------------------------------------- +// Builds ONLY the system ram render target. Used when caller is explicitly managing. +// The paired EDRAM surface can be built in an alternate format. +//----------------------------------------------------------------------------- +#if defined( _X360 ) +void CTextureReference::InitRenderTargetTexture( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName ) +{ + // other variants not implemented yet + Assert( depth == MATERIAL_RT_DEPTH_NONE || depth == MATERIAL_RT_DEPTH_SHARED ); + Assert( !bHDR ); + + int renderTargetFlags = CREATERENDERTARGETFLAGS_NOEDRAM; + + m_pTexture = materials->CreateNamedRenderTargetTextureEx( + pStrOptionalName, + w, + h, + sizeMode, + fmt, + depth, + TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, + renderTargetFlags ); + Assert( m_pTexture ); +} +#endif + +//----------------------------------------------------------------------------- +// Builds ONLY the EDRAM render target surface. Used when caller is explicitly managing. +// The paired system memory texture can be built in an alternate format. +//----------------------------------------------------------------------------- +#if defined( _X360 ) +void CTextureReference::InitRenderTargetSurface( int width, int height, ImageFormat fmt, bool bSameAsTexture ) +{ + // texture has to be created first + Assert( m_pTexture && m_pTexture->IsRenderTarget() ); + + m_pTexture->CreateRenderTargetSurface( width, height, fmt, bSameAsTexture ); +} +#endif + diff --git a/mp/src/public/materialsystem/MaterialSystemUtil.h b/mp/src/public/materialsystem/MaterialSystemUtil.h index 6e5ab11d..3f22e918 100644 --- a/mp/src/public/materialsystem/MaterialSystemUtil.h +++ b/mp/src/public/materialsystem/MaterialSystemUtil.h @@ -1,99 +1,99 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $Workfile: $
-// $Date: $
-// $NoKeywords: $
-//===========================================================================//
-#ifndef MATERIALSYSTEMUTIL_H
-#define MATERIALSYSTEMUTIL_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "bitmap/imageformat.h" //ImageFormat enum definition
-#include "materialsystem/imaterialsystem.h" // RenderTargetSizeMode_t and MaterialRenderTargetDepth_t definition
-
-//-----------------------------------------------------------------------------
-// Forward declarations
-//-----------------------------------------------------------------------------
-class IMaterial;
-class ITexture;
-class KeyValues;
-
-class KeyValues;
-
-
-//-----------------------------------------------------------------------------
-// Little utility class to deal with material references
-//-----------------------------------------------------------------------------
-class CMaterialReference
-{
-public:
- // constructor, destructor
- CMaterialReference( char const* pMaterialName = 0, const char *pTextureGroupName = 0, bool bComplain = true );
- ~CMaterialReference();
-
- // Attach to a material
- void Init( const char* pMaterialName, const char *pTextureGroupName, bool bComplain = true );
- void Init( const char *pMaterialName, KeyValues *pVMTKeyValues );
- void Init( IMaterial* pMaterial );
- void Init( CMaterialReference& ref );
- void Init( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues );
-
- // Detach from a material
- void Shutdown();
- bool IsValid() { return m_pMaterial != 0; }
-
- // Automatic casts to IMaterial
- operator IMaterial*() { return m_pMaterial; }
- operator IMaterial*() const { return m_pMaterial; }
- operator IMaterial const*() const { return m_pMaterial; }
- IMaterial* operator->() { return m_pMaterial; }
-
-private:
- IMaterial* m_pMaterial;
-};
-
-//-----------------------------------------------------------------------------
-// Little utility class to deal with texture references
-//-----------------------------------------------------------------------------
-class CTextureReference
-{
-public:
- // constructor, destructor
- CTextureReference( );
- CTextureReference( const CTextureReference &ref );
- ~CTextureReference();
-
- // Attach to a texture
- void Init( char const* pTexture, const char *pTextureGroupName, bool bComplain = true );
- void InitProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags );
- void InitRenderTarget( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName = NULL );
-#if defined( _X360 )
- // used when RT coupling is disparate (texture is DDR based, surface is EDRAM based)
- void InitRenderTargetTexture( int width, int height, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName = NULL );
- void InitRenderTargetSurface( int width, int height, ImageFormat fmt, bool bSameAsTexture );
-#endif
- void Init( ITexture* pTexture );
-
- // Detach from a texture
- void Shutdown( bool bDeleteIfUnReferenced = false );
- bool IsValid() { return m_pTexture != 0; }
-
- // Automatic casts to ITexture
- operator ITexture*() { return m_pTexture; }
- operator ITexture const*() const { return m_pTexture; }
- ITexture* operator->() { return m_pTexture; }
-
- // Assignment operator
- void operator=( CTextureReference &ref );
-
-private:
- ITexture* m_pTexture;
-};
-
-
-#endif // !MATERIALSYSTEMUTIL_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//===========================================================================// +#ifndef MATERIALSYSTEMUTIL_H +#define MATERIALSYSTEMUTIL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "bitmap/imageformat.h" //ImageFormat enum definition +#include "materialsystem/imaterialsystem.h" // RenderTargetSizeMode_t and MaterialRenderTargetDepth_t definition + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class IMaterial; +class ITexture; +class KeyValues; + +class KeyValues; + + +//----------------------------------------------------------------------------- +// Little utility class to deal with material references +//----------------------------------------------------------------------------- +class CMaterialReference +{ +public: + // constructor, destructor + CMaterialReference( char const* pMaterialName = 0, const char *pTextureGroupName = 0, bool bComplain = true ); + ~CMaterialReference(); + + // Attach to a material + void Init( const char* pMaterialName, const char *pTextureGroupName, bool bComplain = true ); + void Init( const char *pMaterialName, KeyValues *pVMTKeyValues ); + void Init( IMaterial* pMaterial ); + void Init( CMaterialReference& ref ); + void Init( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ); + + // Detach from a material + void Shutdown(); + bool IsValid() { return m_pMaterial != 0; } + + // Automatic casts to IMaterial + operator IMaterial*() { return m_pMaterial; } + operator IMaterial*() const { return m_pMaterial; } + operator IMaterial const*() const { return m_pMaterial; } + IMaterial* operator->() { return m_pMaterial; } + +private: + IMaterial* m_pMaterial; +}; + +//----------------------------------------------------------------------------- +// Little utility class to deal with texture references +//----------------------------------------------------------------------------- +class CTextureReference +{ +public: + // constructor, destructor + CTextureReference( ); + CTextureReference( const CTextureReference &ref ); + ~CTextureReference(); + + // Attach to a texture + void Init( char const* pTexture, const char *pTextureGroupName, bool bComplain = true ); + void InitProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags ); + void InitRenderTarget( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName = NULL ); +#if defined( _X360 ) + // used when RT coupling is disparate (texture is DDR based, surface is EDRAM based) + void InitRenderTargetTexture( int width, int height, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName = NULL ); + void InitRenderTargetSurface( int width, int height, ImageFormat fmt, bool bSameAsTexture ); +#endif + void Init( ITexture* pTexture ); + + // Detach from a texture + void Shutdown( bool bDeleteIfUnReferenced = false ); + bool IsValid() { return m_pTexture != 0; } + + // Automatic casts to ITexture + operator ITexture*() { return m_pTexture; } + operator ITexture const*() const { return m_pTexture; } + ITexture* operator->() { return m_pTexture; } + + // Assignment operator + void operator=( CTextureReference &ref ); + +private: + ITexture* m_pTexture; +}; + + +#endif // !MATERIALSYSTEMUTIL_H diff --git a/mp/src/public/materialsystem/deformations.h b/mp/src/public/materialsystem/deformations.h index 429ff297..083ceeb5 100644 --- a/mp/src/public/materialsystem/deformations.h +++ b/mp/src/public/materialsystem/deformations.h @@ -1,58 +1,58 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//===========================================================================//
-
-#ifndef DEFORMATIONS_H
-#define DEFORMATIONS_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-
-// nonlinear transformations which may be applied to model vertices when rendering. must be powers of two
-enum DeformationType_t
-{
- DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE = 1, // minxyz.minsoftness / maxxyz.maxsoftness
-};
-
-
-struct DeformationBase_t // base class. don't use this
-{
- DeformationType_t m_eType;
-};
-
-
-struct BoxDeformation_t : DeformationBase_t
-{
- // don't change the layout without changing code in shaderapidx8!!!!
- Vector m_SourceMins; // cube to clamp within
- float m_flPad0;
- Vector m_SourceMaxes;
- float m_flPad1;
-
- Vector m_ClampMins;
- float m_flPad2;
- Vector m_ClampMaxes;
- float m_flPad3;
-
- FORCEINLINE BoxDeformation_t( void )
- {
- m_eType = DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE;
- // invalid cube
- m_SourceMins.Init( 0,0,0 );
- m_SourceMaxes.Init( -1, -1, -1 );
-
- // no clamp
- m_ClampMins.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX );
- m_ClampMaxes.Init( FLT_MAX, FLT_MAX, FLT_MAX );
- }
-
-};
-
-
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef DEFORMATIONS_H +#define DEFORMATIONS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" + +// nonlinear transformations which may be applied to model vertices when rendering. must be powers of two +enum DeformationType_t +{ + DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE = 1, // minxyz.minsoftness / maxxyz.maxsoftness +}; + + +struct DeformationBase_t // base class. don't use this +{ + DeformationType_t m_eType; +}; + + +struct BoxDeformation_t : DeformationBase_t +{ + // don't change the layout without changing code in shaderapidx8!!!! + Vector m_SourceMins; // cube to clamp within + float m_flPad0; + Vector m_SourceMaxes; + float m_flPad1; + + Vector m_ClampMins; + float m_flPad2; + Vector m_ClampMaxes; + float m_flPad3; + + FORCEINLINE BoxDeformation_t( void ) + { + m_eType = DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE; + // invalid cube + m_SourceMins.Init( 0,0,0 ); + m_SourceMaxes.Init( -1, -1, -1 ); + + // no clamp + m_ClampMins.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); + m_ClampMaxes.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + } + +}; + + + +#endif diff --git a/mp/src/public/materialsystem/hardwareverts.h b/mp/src/public/materialsystem/hardwareverts.h index 6f335581..c7a08fe9 100644 --- a/mp/src/public/materialsystem/hardwareverts.h +++ b/mp/src/public/materialsystem/hardwareverts.h @@ -1,86 +1,86 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Hardware Verts
-//
-// Contains data purposely formatted for a dma copy into a D3D Vertex Buffer.
-// The file is divided into two partitions, the foremost contains the static
-// portion (header), the latter contains the streamable compliant portion.
-// The streamable component starts and ends on a sector (512) aligned boundary.
-// The header identifies the vertex format of the data and the atomic sizes of each component.
-// The hierarchial mesh is flattened for dma but the vertex counts are available
-// per mesh to transfer each mesh individually.
-//=============================================================================//
-
-#ifndef HARDWAREVERTS_H
-#define HARDWAREVERTS_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "datamap.h"
-
-// valve hardware vertexes
-#define VHV_VERSION 2
-
-namespace HardwareVerts
-{
-
-#pragma pack(1)
-
-struct MeshHeader_t
-{
- DECLARE_BYTESWAP_DATADESC();
-
- // this mesh is part of this lod
- unsigned int m_nLod;
-
- // this mesh has this many vertexes
- unsigned int m_nVertexes;
-
- // starting at this offset
- unsigned int m_nOffset;
-
- unsigned int m_nUnused[4];
-};
-
-struct FileHeader_t
-{
- DECLARE_BYTESWAP_DATADESC();
-
- // file version as defined by VHV_VERSION
- int m_nVersion;
-
- // must match checkSum in the .mdl header
- unsigned int m_nChecksum;
-
- // a vertex consists of these components
- uint32 m_nVertexFlags;
-
- // the byte size of a single vertex
- // this won't be adequate, need some concept of byte format i.e. rgbexp32 vs rgba8888
- unsigned int m_nVertexSize;
-
- // total number of vertexes
- unsigned int m_nVertexes;
-
- int m_nMeshes;
- inline MeshHeader_t *pMesh( int nMesh ) const
- {
- return (MeshHeader_t *)(((byte *)this) + sizeof(FileHeader_t)) + nMesh;
- };
-
- inline void *pVertexBase( int nMesh ) const
- {
- return (void *)((byte *)this + pMesh( nMesh )->m_nOffset);
- };
-
- unsigned int m_nUnused[4];
-};
-
-#pragma pack()
-
-}; // end namespace
-
-#endif // HARDWAREVERTS_H
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Hardware Verts +// +// Contains data purposely formatted for a dma copy into a D3D Vertex Buffer. +// The file is divided into two partitions, the foremost contains the static +// portion (header), the latter contains the streamable compliant portion. +// The streamable component starts and ends on a sector (512) aligned boundary. +// The header identifies the vertex format of the data and the atomic sizes of each component. +// The hierarchial mesh is flattened for dma but the vertex counts are available +// per mesh to transfer each mesh individually. +//=============================================================================// + +#ifndef HARDWAREVERTS_H +#define HARDWAREVERTS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "datamap.h" + +// valve hardware vertexes +#define VHV_VERSION 2 + +namespace HardwareVerts +{ + +#pragma pack(1) + +struct MeshHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + + // this mesh is part of this lod + unsigned int m_nLod; + + // this mesh has this many vertexes + unsigned int m_nVertexes; + + // starting at this offset + unsigned int m_nOffset; + + unsigned int m_nUnused[4]; +}; + +struct FileHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + + // file version as defined by VHV_VERSION + int m_nVersion; + + // must match checkSum in the .mdl header + unsigned int m_nChecksum; + + // a vertex consists of these components + uint32 m_nVertexFlags; + + // the byte size of a single vertex + // this won't be adequate, need some concept of byte format i.e. rgbexp32 vs rgba8888 + unsigned int m_nVertexSize; + + // total number of vertexes + unsigned int m_nVertexes; + + int m_nMeshes; + inline MeshHeader_t *pMesh( int nMesh ) const + { + return (MeshHeader_t *)(((byte *)this) + sizeof(FileHeader_t)) + nMesh; + }; + + inline void *pVertexBase( int nMesh ) const + { + return (void *)((byte *)this + pMesh( nMesh )->m_nOffset); + }; + + unsigned int m_nUnused[4]; +}; + +#pragma pack() + +}; // end namespace + +#endif // HARDWAREVERTS_H + diff --git a/mp/src/public/materialsystem/idebugtextureinfo.h b/mp/src/public/materialsystem/idebugtextureinfo.h index dee72a8b..426486da 100644 --- a/mp/src/public/materialsystem/idebugtextureinfo.h +++ b/mp/src/public/materialsystem/idebugtextureinfo.h @@ -1,69 +1,69 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef IDEBUGTEXTUREINFO_H
-#define IDEBUGTEXTUREINFO_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-class KeyValues;
-
-
-// This interface is actually exported by the shader API DLL.
-#define DEBUG_TEXTURE_INFO_VERSION "DebugTextureInfo001"
-
-
-abstract_class IDebugTextureInfo
-{
-public:
-
- // Use this to turn on the mode where it builds the debug texture list.
- // At the end of the next frame, GetDebugTextureList() will return a valid list of the textures.
- virtual void EnableDebugTextureList( bool bEnable ) = 0;
-
- // If this is on, then it will return all textures that exist, not just the ones that were bound in the last frame.
- // It is required to enable debug texture list to get this.
- virtual void EnableGetAllTextures( bool bEnable ) = 0;
-
- // Use this to get the results of the texture list.
- // Do NOT release the KeyValues after using them.
- // There will be a bunch of subkeys, each with these values:
- // Name - the texture's filename
- // Binds - how many times the texture was bound
- // Format - ImageFormat of the texture
- // Width - Width of the texture
- // Height - Height of the texture
- // It is required to enable debug texture list to get this.
- virtual KeyValues* GetDebugTextureList() = 0;
-
- // Texture memory usage
- enum TextureMemoryType
- {
- MEMORY_RESERVED_MIN = 0,
- MEMORY_BOUND_LAST_FRAME, // sums up textures bound last frame
- MEMORY_TOTAL_LOADED, // total texture memory used
- MEMORY_ESTIMATE_PICMIP_1, // estimate of running with "picmip 1"
- MEMORY_ESTIMATE_PICMIP_2, // estimate of running with "picmip 2"
- MEMORY_RESERVED_MAX
- };
-
- // This returns how much memory was used.
- virtual int GetTextureMemoryUsed( TextureMemoryType eTextureMemory ) = 0;
-
- // Use this to determine if texture debug info was computed within last numFramesAllowed frames.
- virtual bool IsDebugTextureListFresh( int numFramesAllowed = 1 ) = 0;
-
- // Enable debug texture rendering when texture binds should not count towards textures
- // used during a frame. Returns the old state of debug texture rendering flag to use
- // it for restoring the mode.
- virtual bool SetDebugTextureRendering( bool bEnable ) = 0;
-
-};
-
-
-#endif // IDEBUGTEXTUREINFO_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef IDEBUGTEXTUREINFO_H +#define IDEBUGTEXTUREINFO_H +#ifdef _WIN32 +#pragma once +#endif + + +class KeyValues; + + +// This interface is actually exported by the shader API DLL. +#define DEBUG_TEXTURE_INFO_VERSION "DebugTextureInfo001" + + +abstract_class IDebugTextureInfo +{ +public: + + // Use this to turn on the mode where it builds the debug texture list. + // At the end of the next frame, GetDebugTextureList() will return a valid list of the textures. + virtual void EnableDebugTextureList( bool bEnable ) = 0; + + // If this is on, then it will return all textures that exist, not just the ones that were bound in the last frame. + // It is required to enable debug texture list to get this. + virtual void EnableGetAllTextures( bool bEnable ) = 0; + + // Use this to get the results of the texture list. + // Do NOT release the KeyValues after using them. + // There will be a bunch of subkeys, each with these values: + // Name - the texture's filename + // Binds - how many times the texture was bound + // Format - ImageFormat of the texture + // Width - Width of the texture + // Height - Height of the texture + // It is required to enable debug texture list to get this. + virtual KeyValues* GetDebugTextureList() = 0; + + // Texture memory usage + enum TextureMemoryType + { + MEMORY_RESERVED_MIN = 0, + MEMORY_BOUND_LAST_FRAME, // sums up textures bound last frame + MEMORY_TOTAL_LOADED, // total texture memory used + MEMORY_ESTIMATE_PICMIP_1, // estimate of running with "picmip 1" + MEMORY_ESTIMATE_PICMIP_2, // estimate of running with "picmip 2" + MEMORY_RESERVED_MAX + }; + + // This returns how much memory was used. + virtual int GetTextureMemoryUsed( TextureMemoryType eTextureMemory ) = 0; + + // Use this to determine if texture debug info was computed within last numFramesAllowed frames. + virtual bool IsDebugTextureListFresh( int numFramesAllowed = 1 ) = 0; + + // Enable debug texture rendering when texture binds should not count towards textures + // used during a frame. Returns the old state of debug texture rendering flag to use + // it for restoring the mode. + virtual bool SetDebugTextureRendering( bool bEnable ) = 0; + +}; + + +#endif // IDEBUGTEXTUREINFO_H diff --git a/mp/src/public/materialsystem/imaterial.h b/mp/src/public/materialsystem/imaterial.h index 8499dfb0..7af7aa15 100644 --- a/mp/src/public/materialsystem/imaterial.h +++ b/mp/src/public/materialsystem/imaterial.h @@ -1,612 +1,612 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-
-#ifndef IMATERIAL_H
-#define IMATERIAL_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "bitmap/imageformat.h"
-#include "materialsystem/imaterialsystem.h"
-
-//-----------------------------------------------------------------------------
-// forward declaraions
-//-----------------------------------------------------------------------------
-
-class IMaterialVar;
-class ITexture;
-class IMaterialProxy;
-class Vector;
-
-//-----------------------------------------------------------------------------
-// Flags for GetVertexFormat
-//-----------------------------------------------------------------------------
-#define VERTEX_POSITION 0x0001
-#define VERTEX_NORMAL 0x0002
-#define VERTEX_COLOR 0x0004
-#define VERTEX_SPECULAR 0x0008
-
-#define VERTEX_TANGENT_S 0x0010
-#define VERTEX_TANGENT_T 0x0020
-#define VERTEX_TANGENT_SPACE ( VERTEX_TANGENT_S | VERTEX_TANGENT_T )
-
-// Indicates we're using wrinkle
-#define VERTEX_WRINKLE 0x0040
-
-// Indicates we're using bone indices
-#define VERTEX_BONE_INDEX 0x0080
-
-// Indicates this is a vertex shader
-#define VERTEX_FORMAT_VERTEX_SHADER 0x0100
-
-// Indicates this format shouldn't be bloated to cache align it
-// (only used for VertexUsage)
-#define VERTEX_FORMAT_USE_EXACT_FORMAT 0x0200
-
-// Indicates that compressed vertex elements are to be used (see also VertexCompressionType_t)
-#define VERTEX_FORMAT_COMPRESSED 0x400
-
-// Update this if you add or remove bits...
-#define VERTEX_LAST_BIT 10
-
-#define VERTEX_BONE_WEIGHT_BIT (VERTEX_LAST_BIT + 1)
-#define USER_DATA_SIZE_BIT (VERTEX_LAST_BIT + 4)
-#define TEX_COORD_SIZE_BIT (VERTEX_LAST_BIT + 7)
-
-#define VERTEX_BONE_WEIGHT_MASK ( 0x7 << VERTEX_BONE_WEIGHT_BIT )
-#define USER_DATA_SIZE_MASK ( 0x7 << USER_DATA_SIZE_BIT )
-
-#define VERTEX_FORMAT_FIELD_MASK 0x0FF
-
-// If everything is off, it's an unknown vertex format
-#define VERTEX_FORMAT_UNKNOWN 0
-
-
-
-//-----------------------------------------------------------------------------
-// Macros for construction..
-//-----------------------------------------------------------------------------
-#define VERTEX_BONEWEIGHT( _n ) ((_n) << VERTEX_BONE_WEIGHT_BIT)
-#define VERTEX_USERDATA_SIZE( _n ) ((_n) << USER_DATA_SIZE_BIT)
-#define VERTEX_TEXCOORD_MASK( _coord ) (( 0x7ULL ) << ( TEX_COORD_SIZE_BIT + 3 * (_coord) ))
-
-inline VertexFormat_t VERTEX_TEXCOORD_SIZE( int nIndex, int nNumCoords )
-{
- uint64 n64=nNumCoords;
- uint64 nShift=TEX_COORD_SIZE_BIT + (3*nIndex);
- return n64 << nShift;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Gets at various vertex format info...
-//-----------------------------------------------------------------------------
-inline int VertexFlags( VertexFormat_t vertexFormat )
-{
- return static_cast<int> ( vertexFormat & ( (1 << (VERTEX_LAST_BIT+1)) - 1 ) );
-}
-
-inline int NumBoneWeights( VertexFormat_t vertexFormat )
-{
- return static_cast<int> ( (vertexFormat >> VERTEX_BONE_WEIGHT_BIT) & 0x7 );
-}
-
-inline int UserDataSize( VertexFormat_t vertexFormat )
-{
- return static_cast<int> ( (vertexFormat >> USER_DATA_SIZE_BIT) & 0x7 );
-}
-
-inline int TexCoordSize( int nTexCoordIndex, VertexFormat_t vertexFormat )
-{
- return static_cast<int> ( (vertexFormat >> (TEX_COORD_SIZE_BIT + 3*nTexCoordIndex) ) & 0x7 );
-}
-
-inline bool UsesVertexShader( VertexFormat_t vertexFormat )
-{
- return (vertexFormat & VERTEX_FORMAT_VERTEX_SHADER) != 0;
-}
-
-inline VertexCompressionType_t CompressionType( VertexFormat_t vertexFormat )
-{
- // This is trivial now, but we may add multiple flavours of compressed vertex later on
- if ( vertexFormat & VERTEX_FORMAT_COMPRESSED )
- return VERTEX_COMPRESSION_ON;
- else
- return VERTEX_COMPRESSION_NONE;
-}
-
-
-//-----------------------------------------------------------------------------
-// VertexElement_t (enumerates all usable vertex elements)
-//-----------------------------------------------------------------------------
-// FIXME: unify this with VertexFormat_t (i.e. construct the lower bits of VertexFormat_t with "1 << (VertexElement_t)element")
-enum VertexElement_t
-{
- VERTEX_ELEMENT_NONE = -1,
-
- // Deliberately explicitly numbered so it's a pain in the ass to change, so you read this:
- // #!#!#NOTE#!#!# update GetVertexElementSize, VertexElementToDeclType and
- // CVBAllocTracker (elementTable) when you update this!
- VERTEX_ELEMENT_POSITION = 0,
- VERTEX_ELEMENT_NORMAL = 1,
- VERTEX_ELEMENT_COLOR = 2,
- VERTEX_ELEMENT_SPECULAR = 3,
- VERTEX_ELEMENT_TANGENT_S = 4,
- VERTEX_ELEMENT_TANGENT_T = 5,
- VERTEX_ELEMENT_WRINKLE = 6,
- VERTEX_ELEMENT_BONEINDEX = 7,
- VERTEX_ELEMENT_BONEWEIGHTS1 = 8,
- VERTEX_ELEMENT_BONEWEIGHTS2 = 9,
- VERTEX_ELEMENT_BONEWEIGHTS3 = 10,
- VERTEX_ELEMENT_BONEWEIGHTS4 = 11,
- VERTEX_ELEMENT_USERDATA1 = 12,
- VERTEX_ELEMENT_USERDATA2 = 13,
- VERTEX_ELEMENT_USERDATA3 = 14,
- VERTEX_ELEMENT_USERDATA4 = 15,
- VERTEX_ELEMENT_TEXCOORD1D_0 = 16,
- VERTEX_ELEMENT_TEXCOORD1D_1 = 17,
- VERTEX_ELEMENT_TEXCOORD1D_2 = 18,
- VERTEX_ELEMENT_TEXCOORD1D_3 = 19,
- VERTEX_ELEMENT_TEXCOORD1D_4 = 20,
- VERTEX_ELEMENT_TEXCOORD1D_5 = 21,
- VERTEX_ELEMENT_TEXCOORD1D_6 = 22,
- VERTEX_ELEMENT_TEXCOORD1D_7 = 23,
- VERTEX_ELEMENT_TEXCOORD2D_0 = 24,
- VERTEX_ELEMENT_TEXCOORD2D_1 = 25,
- VERTEX_ELEMENT_TEXCOORD2D_2 = 26,
- VERTEX_ELEMENT_TEXCOORD2D_3 = 27,
- VERTEX_ELEMENT_TEXCOORD2D_4 = 28,
- VERTEX_ELEMENT_TEXCOORD2D_5 = 29,
- VERTEX_ELEMENT_TEXCOORD2D_6 = 30,
- VERTEX_ELEMENT_TEXCOORD2D_7 = 31,
- VERTEX_ELEMENT_TEXCOORD3D_0 = 32,
- VERTEX_ELEMENT_TEXCOORD3D_1 = 33,
- VERTEX_ELEMENT_TEXCOORD3D_2 = 34,
- VERTEX_ELEMENT_TEXCOORD3D_3 = 35,
- VERTEX_ELEMENT_TEXCOORD3D_4 = 36,
- VERTEX_ELEMENT_TEXCOORD3D_5 = 37,
- VERTEX_ELEMENT_TEXCOORD3D_6 = 38,
- VERTEX_ELEMENT_TEXCOORD3D_7 = 39,
- VERTEX_ELEMENT_TEXCOORD4D_0 = 40,
- VERTEX_ELEMENT_TEXCOORD4D_1 = 41,
- VERTEX_ELEMENT_TEXCOORD4D_2 = 42,
- VERTEX_ELEMENT_TEXCOORD4D_3 = 43,
- VERTEX_ELEMENT_TEXCOORD4D_4 = 44,
- VERTEX_ELEMENT_TEXCOORD4D_5 = 45,
- VERTEX_ELEMENT_TEXCOORD4D_6 = 46,
- VERTEX_ELEMENT_TEXCOORD4D_7 = 47,
-
- VERTEX_ELEMENT_NUMELEMENTS = 48
-};
-
-inline void Detect_VertexElement_t_Changes( VertexElement_t element ) // GREPs for VertexElement_t will hit this
-{
- // Make it harder for someone to change VertexElement_t without noticing that dependent code
- // (GetVertexElementSize, VertexElementToDeclType, CVBAllocTracker) needs updating
- Assert( VERTEX_ELEMENT_NUMELEMENTS == 48 );
- switch ( element )
- {
- case VERTEX_ELEMENT_POSITION: Assert( VERTEX_ELEMENT_POSITION == 0 ); break;
- case VERTEX_ELEMENT_NORMAL: Assert( VERTEX_ELEMENT_NORMAL == 1 ); break;
- case VERTEX_ELEMENT_COLOR: Assert( VERTEX_ELEMENT_COLOR == 2 ); break;
- case VERTEX_ELEMENT_SPECULAR: Assert( VERTEX_ELEMENT_SPECULAR == 3 ); break;
- case VERTEX_ELEMENT_TANGENT_S: Assert( VERTEX_ELEMENT_TANGENT_S == 4 ); break;
- case VERTEX_ELEMENT_TANGENT_T: Assert( VERTEX_ELEMENT_TANGENT_T == 5 ); break;
- case VERTEX_ELEMENT_WRINKLE: Assert( VERTEX_ELEMENT_WRINKLE == 6 ); break;
- case VERTEX_ELEMENT_BONEINDEX: Assert( VERTEX_ELEMENT_BONEINDEX == 7 ); break;
- case VERTEX_ELEMENT_BONEWEIGHTS1: Assert( VERTEX_ELEMENT_BONEWEIGHTS1 == 8 ); break;
- case VERTEX_ELEMENT_BONEWEIGHTS2: Assert( VERTEX_ELEMENT_BONEWEIGHTS2 == 9 ); break;
- case VERTEX_ELEMENT_BONEWEIGHTS3: Assert( VERTEX_ELEMENT_BONEWEIGHTS3 == 10 ); break;
- case VERTEX_ELEMENT_BONEWEIGHTS4: Assert( VERTEX_ELEMENT_BONEWEIGHTS4 == 11 ); break;
- case VERTEX_ELEMENT_USERDATA1: Assert( VERTEX_ELEMENT_USERDATA1 == 12 ); break;
- case VERTEX_ELEMENT_USERDATA2: Assert( VERTEX_ELEMENT_USERDATA2 == 13 ); break;
- case VERTEX_ELEMENT_USERDATA3: Assert( VERTEX_ELEMENT_USERDATA3 == 14 ); break;
- case VERTEX_ELEMENT_USERDATA4: Assert( VERTEX_ELEMENT_USERDATA4 == 15 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_0: Assert( VERTEX_ELEMENT_TEXCOORD1D_0 == 16 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_1: Assert( VERTEX_ELEMENT_TEXCOORD1D_1 == 17 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_2: Assert( VERTEX_ELEMENT_TEXCOORD1D_2 == 18 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_3: Assert( VERTEX_ELEMENT_TEXCOORD1D_3 == 19 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_4: Assert( VERTEX_ELEMENT_TEXCOORD1D_4 == 20 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_5: Assert( VERTEX_ELEMENT_TEXCOORD1D_5 == 21 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_6: Assert( VERTEX_ELEMENT_TEXCOORD1D_6 == 22 ); break;
- case VERTEX_ELEMENT_TEXCOORD1D_7: Assert( VERTEX_ELEMENT_TEXCOORD1D_7 == 23 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_0: Assert( VERTEX_ELEMENT_TEXCOORD2D_0 == 24 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_1: Assert( VERTEX_ELEMENT_TEXCOORD2D_1 == 25 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_2: Assert( VERTEX_ELEMENT_TEXCOORD2D_2 == 26 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_3: Assert( VERTEX_ELEMENT_TEXCOORD2D_3 == 27 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_4: Assert( VERTEX_ELEMENT_TEXCOORD2D_4 == 28 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_5: Assert( VERTEX_ELEMENT_TEXCOORD2D_5 == 29 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_6: Assert( VERTEX_ELEMENT_TEXCOORD2D_6 == 30 ); break;
- case VERTEX_ELEMENT_TEXCOORD2D_7: Assert( VERTEX_ELEMENT_TEXCOORD2D_7 == 31 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_0: Assert( VERTEX_ELEMENT_TEXCOORD3D_0 == 32 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_1: Assert( VERTEX_ELEMENT_TEXCOORD3D_1 == 33 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_2: Assert( VERTEX_ELEMENT_TEXCOORD3D_2 == 34 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_3: Assert( VERTEX_ELEMENT_TEXCOORD3D_3 == 35 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_4: Assert( VERTEX_ELEMENT_TEXCOORD3D_4 == 36 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_5: Assert( VERTEX_ELEMENT_TEXCOORD3D_5 == 37 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_6: Assert( VERTEX_ELEMENT_TEXCOORD3D_6 == 38 ); break;
- case VERTEX_ELEMENT_TEXCOORD3D_7: Assert( VERTEX_ELEMENT_TEXCOORD3D_7 == 39 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_0: Assert( VERTEX_ELEMENT_TEXCOORD4D_0 == 40 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_1: Assert( VERTEX_ELEMENT_TEXCOORD4D_1 == 41 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_2: Assert( VERTEX_ELEMENT_TEXCOORD4D_2 == 42 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_3: Assert( VERTEX_ELEMENT_TEXCOORD4D_3 == 43 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_4: Assert( VERTEX_ELEMENT_TEXCOORD4D_4 == 44 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_5: Assert( VERTEX_ELEMENT_TEXCOORD4D_5 == 45 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_6: Assert( VERTEX_ELEMENT_TEXCOORD4D_6 == 46 ); break;
- case VERTEX_ELEMENT_TEXCOORD4D_7: Assert( VERTEX_ELEMENT_TEXCOORD4D_7 == 47 ); break;
- default:
- Assert( 0 ); // Invalid input or VertexElement_t has definitely changed
- break;
- }
-}
-
-// We're testing 2 normal compression methods
-// One compressed normals+tangents into a SHORT2 each (8 bytes total)
-// The other compresses them together, into a single UBYTE4 (4 bytes total)
-// FIXME: pick one or the other, compare lighting quality in important cases
-#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0
-#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1
-//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2
-#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4
-
-inline int GetVertexElementSize( VertexElement_t element, VertexCompressionType_t compressionType )
-{
- Detect_VertexElement_t_Changes( element );
-
- if ( compressionType == VERTEX_COMPRESSION_ON )
- {
- // Compressed-vertex element sizes
- switch ( element )
- {
-#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 )
- case VERTEX_ELEMENT_NORMAL:
- return ( 2 * sizeof( short ) );
- case VERTEX_ELEMENT_USERDATA4:
- return ( 2 * sizeof( short ) );
-#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 )
- // Normals and tangents (userdata4) are combined into a single UBYTE4 vertex element
- case VERTEX_ELEMENT_NORMAL:
- return ( 4 * sizeof( unsigned char ) );
- case VERTEX_ELEMENT_USERDATA4:
- return ( 0 );
-#endif
- // Compressed bone weights use a SHORT2 vertex element:
- case VERTEX_ELEMENT_BONEWEIGHTS1:
- case VERTEX_ELEMENT_BONEWEIGHTS2:
- return ( 2 * sizeof( short ) );
- default:
- break;
- }
- }
-
- // Uncompressed-vertex element sizes
- switch ( element )
- {
- case VERTEX_ELEMENT_POSITION: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_NORMAL: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_COLOR: return ( 4 * sizeof( unsigned char ) );
- case VERTEX_ELEMENT_SPECULAR: return ( 4 * sizeof( unsigned char ) );
- case VERTEX_ELEMENT_TANGENT_S: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TANGENT_T: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_WRINKLE: return ( 1 * sizeof( float ) ); // Packed into Position.W
- case VERTEX_ELEMENT_BONEINDEX: return ( 4 * sizeof( unsigned char ) );
- case VERTEX_ELEMENT_BONEWEIGHTS1: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_BONEWEIGHTS2: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_BONEWEIGHTS3: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_BONEWEIGHTS4: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_USERDATA1: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_USERDATA2: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_USERDATA3: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_USERDATA4: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_0: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_1: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_2: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_3: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_4: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_5: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_6: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD1D_7: return ( 1 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_0: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_1: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_2: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_3: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_4: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_5: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_6: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD2D_7: return ( 2 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_0: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_1: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_2: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_3: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_4: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_5: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_6: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD3D_7: return ( 3 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_0: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_1: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_2: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_3: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_4: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_5: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_6: return ( 4 * sizeof( float ) );
- case VERTEX_ELEMENT_TEXCOORD4D_7: return ( 4 * sizeof( float ) );
- default:
- Assert(0);
- return 0;
- };
-}
-
-
-//-----------------------------------------------------------------------------
-// Shader state flags can be read from the FLAGS materialvar
-// Also can be read or written to with the Set/GetMaterialVarFlags() call
-// Also make sure you add/remove a string associated with each flag below to CShaderSystem::ShaderStateString in ShaderSystem.cpp
-//-----------------------------------------------------------------------------
-enum MaterialVarFlags_t
-{
- MATERIAL_VAR_DEBUG = (1 << 0),
- MATERIAL_VAR_NO_DEBUG_OVERRIDE = (1 << 1),
- MATERIAL_VAR_NO_DRAW = (1 << 2),
- MATERIAL_VAR_USE_IN_FILLRATE_MODE = (1 << 3),
-
- MATERIAL_VAR_VERTEXCOLOR = (1 << 4),
- MATERIAL_VAR_VERTEXALPHA = (1 << 5),
- MATERIAL_VAR_SELFILLUM = (1 << 6),
- MATERIAL_VAR_ADDITIVE = (1 << 7),
- MATERIAL_VAR_ALPHATEST = (1 << 8),
- MATERIAL_VAR_MULTIPASS = (1 << 9),
- MATERIAL_VAR_ZNEARER = (1 << 10),
- MATERIAL_VAR_MODEL = (1 << 11),
- MATERIAL_VAR_FLAT = (1 << 12),
- MATERIAL_VAR_NOCULL = (1 << 13),
- MATERIAL_VAR_NOFOG = (1 << 14),
- MATERIAL_VAR_IGNOREZ = (1 << 15),
- MATERIAL_VAR_DECAL = (1 << 16),
- MATERIAL_VAR_ENVMAPSPHERE = (1 << 17),
- MATERIAL_VAR_NOALPHAMOD = (1 << 18),
- MATERIAL_VAR_ENVMAPCAMERASPACE = (1 << 19),
- MATERIAL_VAR_BASEALPHAENVMAPMASK = (1 << 20),
- MATERIAL_VAR_TRANSLUCENT = (1 << 21),
- MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK = (1 << 22),
- MATERIAL_VAR_NEEDS_SOFTWARE_SKINNING = (1 << 23),
- MATERIAL_VAR_OPAQUETEXTURE = (1 << 24),
- MATERIAL_VAR_ENVMAPMODE = (1 << 25),
- MATERIAL_VAR_SUPPRESS_DECALS = (1 << 26),
- MATERIAL_VAR_HALFLAMBERT = (1 << 27),
- MATERIAL_VAR_WIREFRAME = (1 << 28),
- MATERIAL_VAR_ALLOWALPHATOCOVERAGE = (1 << 29),
- MATERIAL_VAR_IGNORE_ALPHA_MODULATION = (1 << 30),
-
- // NOTE: Only add flags here that either should be read from
- // .vmts or can be set directly from client code. Other, internal
- // flags should to into the flag enum in imaterialinternal.h
-};
-
-
-//-----------------------------------------------------------------------------
-// Internal flags not accessible from outside the material system. Stored in Flags2
-//-----------------------------------------------------------------------------
-enum MaterialVarFlags2_t
-{
- // NOTE: These are for $flags2!!!!!
-// UNUSED = (1 << 0),
-
- MATERIAL_VAR2_LIGHTING_UNLIT = 0,
- MATERIAL_VAR2_LIGHTING_VERTEX_LIT = (1 << 1),
- MATERIAL_VAR2_LIGHTING_LIGHTMAP = (1 << 2),
- MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP = (1 << 3),
- MATERIAL_VAR2_LIGHTING_MASK =
- ( MATERIAL_VAR2_LIGHTING_VERTEX_LIT |
- MATERIAL_VAR2_LIGHTING_LIGHTMAP |
- MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ),
-
- // FIXME: Should this be a part of the above lighting enums?
- MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL = (1 << 4),
- MATERIAL_VAR2_USES_ENV_CUBEMAP = (1 << 5),
- MATERIAL_VAR2_NEEDS_TANGENT_SPACES = (1 << 6),
- MATERIAL_VAR2_NEEDS_SOFTWARE_LIGHTING = (1 << 7),
- // GR - HDR path puts lightmap alpha in separate texture...
- MATERIAL_VAR2_BLEND_WITH_LIGHTMAP_ALPHA = (1 << 8),
- MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS = (1 << 9),
- MATERIAL_VAR2_USE_FLASHLIGHT = (1 << 10),
- MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING = (1 << 11),
- MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT = (1 << 12),
- MATERIAL_VAR2_USE_EDITOR = (1 << 13),
- MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE = (1 << 14),
- MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE = (1 << 15),
- MATERIAL_VAR2_IS_SPRITECARD = (1 << 16),
- MATERIAL_VAR2_USES_VERTEXID = (1 << 17),
- MATERIAL_VAR2_SUPPORTS_HW_SKINNING = (1 << 18),
- MATERIAL_VAR2_SUPPORTS_FLASHLIGHT = (1 << 19),
-};
-
-
-//-----------------------------------------------------------------------------
-// Preview image return values
-//-----------------------------------------------------------------------------
-enum PreviewImageRetVal_t
-{
- MATERIAL_PREVIEW_IMAGE_BAD = 0,
- MATERIAL_PREVIEW_IMAGE_OK,
- MATERIAL_NO_PREVIEW_IMAGE,
-};
-
-
-//-----------------------------------------------------------------------------
-// material interface
-//-----------------------------------------------------------------------------
-abstract_class IMaterial
-{
-public:
- // Get the name of the material. This is a full path to
- // the vmt file starting from "hl2/materials" (or equivalent) without
- // a file extension.
- virtual const char * GetName() const = 0;
- virtual const char * GetTextureGroupName() const = 0;
-
- // Get the preferred size/bitDepth of a preview image of a material.
- // This is the sort of image that you would use for a thumbnail view
- // of a material, or in WorldCraft until it uses materials to render.
- // separate this for the tools maybe
- virtual PreviewImageRetVal_t GetPreviewImageProperties( int *width, int *height,
- ImageFormat *imageFormat, bool* isTranslucent ) const = 0;
-
- // Get a preview image at the specified width/height and bitDepth.
- // Will do resampling if necessary.(not yet!!! :) )
- // Will do color format conversion. (works now.)
- virtual PreviewImageRetVal_t GetPreviewImage( unsigned char *data,
- int width, int height,
- ImageFormat imageFormat ) const = 0;
- //
- virtual int GetMappingWidth( ) = 0;
- virtual int GetMappingHeight( ) = 0;
-
- virtual int GetNumAnimationFrames( ) = 0;
-
- // For material subrects (material pages). Offset(u,v) and scale(u,v) are normalized to texture.
- virtual bool InMaterialPage( void ) = 0;
- virtual void GetMaterialOffset( float *pOffset ) = 0;
- virtual void GetMaterialScale( float *pScale ) = 0;
- virtual IMaterial *GetMaterialPage( void ) = 0;
-
- // find a vmt variable.
- // This is how game code affects how a material is rendered.
- // The game code must know about the params that are used by
- // the shader for the material that it is trying to affect.
- virtual IMaterialVar * FindVar( const char *varName, bool *found, bool complain = true ) = 0;
-
- // The user never allocates or deallocates materials. Reference counting is
- // used instead. Garbage collection is done upon a call to
- // IMaterialSystem::UncacheUnusedMaterials.
- virtual void IncrementReferenceCount( void ) = 0;
- virtual void DecrementReferenceCount( void ) = 0;
-
- inline void AddRef() { IncrementReferenceCount(); }
- inline void Release() { DecrementReferenceCount(); }
-
- // Each material is assigned a number that groups it with like materials
- // for sorting in the application.
- virtual int GetEnumerationID( void ) const = 0;
-
- virtual void GetLowResColorSample( float s, float t, float *color ) const = 0;
-
- // This computes the state snapshots for this material
- virtual void RecomputeStateSnapshots() = 0;
-
- // Are we translucent?
- virtual bool IsTranslucent() = 0;
-
- // Are we alphatested?
- virtual bool IsAlphaTested() = 0;
-
- // Are we vertex lit?
- virtual bool IsVertexLit() = 0;
-
- // Gets the vertex format
- virtual VertexFormat_t GetVertexFormat() const = 0;
-
- // returns true if this material uses a material proxy
- virtual bool HasProxy( void ) const = 0;
-
- virtual bool UsesEnvCubemap( void ) = 0;
-
- virtual bool NeedsTangentSpace( void ) = 0;
-
- virtual bool NeedsPowerOfTwoFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0;
- virtual bool NeedsFullFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0;
-
- // returns true if the shader doesn't do skinning itself and requires
- // the data that is sent to it to be preskinned.
- virtual bool NeedsSoftwareSkinning( void ) = 0;
-
- // Apply constant color or alpha modulation
- virtual void AlphaModulate( float alpha ) = 0;
- virtual void ColorModulate( float r, float g, float b ) = 0;
-
- // Material Var flags...
- virtual void SetMaterialVarFlag( MaterialVarFlags_t flag, bool on ) = 0;
- virtual bool GetMaterialVarFlag( MaterialVarFlags_t flag ) const = 0;
-
- // Gets material reflectivity
- virtual void GetReflectivity( Vector& reflect ) = 0;
-
- // Gets material property flags
- virtual bool GetPropertyFlag( MaterialPropertyTypes_t type ) = 0;
-
- // Is the material visible from both sides?
- virtual bool IsTwoSided() = 0;
-
- // Sets the shader associated with the material
- virtual void SetShader( const char *pShaderName ) = 0;
-
- // Can't be const because the material might have to precache itself.
- virtual int GetNumPasses( void ) = 0;
-
- // Can't be const because the material might have to precache itself.
- virtual int GetTextureMemoryBytes( void ) = 0;
-
- // 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() = 0;
-
- // GR - returns true is material uses lightmap alpha for blending
- virtual bool NeedsLightmapBlendAlpha( void ) = 0;
-
- // 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 ) = 0;
-
- // Gets at the shader parameters
- virtual int ShaderParamCount() const = 0;
- virtual IMaterialVar **GetShaderParams( void ) = 0;
-
- // Returns true if this is the error material you get back from IMaterialSystem::FindMaterial if
- // the material can't be found.
- virtual bool IsErrorMaterial() const = 0;
-
- virtual void SetUseFixedFunctionBakedLighting( bool bEnable ) = 0;
-
- // Gets the current alpha modulation
- virtual float GetAlphaModulation() = 0;
- virtual void GetColorModulation( float *r, float *g, float *b ) = 0;
-
- // Gets the morph format
- virtual MorphFormat_t GetMorphFormat() const = 0;
-
- // fast find that stores the index of the found var in the string table in local cache
- virtual IMaterialVar * FindVarFast( char const *pVarName, unsigned int *pToken ) = 0;
-
- // Sets new VMT shader parameters for the material
- virtual void SetShaderAndParams( KeyValues *pKeyValues ) = 0;
- virtual const char * GetShaderName() const = 0;
-
- virtual void DeleteIfUnreferenced() = 0;
-
- virtual bool IsSpriteCard() = 0;
-
- virtual void CallBindProxy( void *proxyData ) = 0;
-
- virtual IMaterial *CheckProxyReplacement( void *proxyData ) = 0;
-
- virtual void RefreshPreservingMaterialVars() = 0;
-
- virtual bool WasReloadedFromWhitelist() = 0;
-
- virtual bool IsPrecached() const = 0;
-};
-
-
-inline bool IsErrorMaterial( IMaterial *pMat )
-{
- return !pMat || pMat->IsErrorMaterial();
-}
-
-#endif // IMATERIAL_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef IMATERIAL_H +#define IMATERIAL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "bitmap/imageformat.h" +#include "materialsystem/imaterialsystem.h" + +//----------------------------------------------------------------------------- +// forward declaraions +//----------------------------------------------------------------------------- + +class IMaterialVar; +class ITexture; +class IMaterialProxy; +class Vector; + +//----------------------------------------------------------------------------- +// Flags for GetVertexFormat +//----------------------------------------------------------------------------- +#define VERTEX_POSITION 0x0001 +#define VERTEX_NORMAL 0x0002 +#define VERTEX_COLOR 0x0004 +#define VERTEX_SPECULAR 0x0008 + +#define VERTEX_TANGENT_S 0x0010 +#define VERTEX_TANGENT_T 0x0020 +#define VERTEX_TANGENT_SPACE ( VERTEX_TANGENT_S | VERTEX_TANGENT_T ) + +// Indicates we're using wrinkle +#define VERTEX_WRINKLE 0x0040 + +// Indicates we're using bone indices +#define VERTEX_BONE_INDEX 0x0080 + +// Indicates this is a vertex shader +#define VERTEX_FORMAT_VERTEX_SHADER 0x0100 + +// Indicates this format shouldn't be bloated to cache align it +// (only used for VertexUsage) +#define VERTEX_FORMAT_USE_EXACT_FORMAT 0x0200 + +// Indicates that compressed vertex elements are to be used (see also VertexCompressionType_t) +#define VERTEX_FORMAT_COMPRESSED 0x400 + +// Update this if you add or remove bits... +#define VERTEX_LAST_BIT 10 + +#define VERTEX_BONE_WEIGHT_BIT (VERTEX_LAST_BIT + 1) +#define USER_DATA_SIZE_BIT (VERTEX_LAST_BIT + 4) +#define TEX_COORD_SIZE_BIT (VERTEX_LAST_BIT + 7) + +#define VERTEX_BONE_WEIGHT_MASK ( 0x7 << VERTEX_BONE_WEIGHT_BIT ) +#define USER_DATA_SIZE_MASK ( 0x7 << USER_DATA_SIZE_BIT ) + +#define VERTEX_FORMAT_FIELD_MASK 0x0FF + +// If everything is off, it's an unknown vertex format +#define VERTEX_FORMAT_UNKNOWN 0 + + + +//----------------------------------------------------------------------------- +// Macros for construction.. +//----------------------------------------------------------------------------- +#define VERTEX_BONEWEIGHT( _n ) ((_n) << VERTEX_BONE_WEIGHT_BIT) +#define VERTEX_USERDATA_SIZE( _n ) ((_n) << USER_DATA_SIZE_BIT) +#define VERTEX_TEXCOORD_MASK( _coord ) (( 0x7ULL ) << ( TEX_COORD_SIZE_BIT + 3 * (_coord) )) + +inline VertexFormat_t VERTEX_TEXCOORD_SIZE( int nIndex, int nNumCoords ) +{ + uint64 n64=nNumCoords; + uint64 nShift=TEX_COORD_SIZE_BIT + (3*nIndex); + return n64 << nShift; +} + + + +//----------------------------------------------------------------------------- +// Gets at various vertex format info... +//----------------------------------------------------------------------------- +inline int VertexFlags( VertexFormat_t vertexFormat ) +{ + return static_cast<int> ( vertexFormat & ( (1 << (VERTEX_LAST_BIT+1)) - 1 ) ); +} + +inline int NumBoneWeights( VertexFormat_t vertexFormat ) +{ + return static_cast<int> ( (vertexFormat >> VERTEX_BONE_WEIGHT_BIT) & 0x7 ); +} + +inline int UserDataSize( VertexFormat_t vertexFormat ) +{ + return static_cast<int> ( (vertexFormat >> USER_DATA_SIZE_BIT) & 0x7 ); +} + +inline int TexCoordSize( int nTexCoordIndex, VertexFormat_t vertexFormat ) +{ + return static_cast<int> ( (vertexFormat >> (TEX_COORD_SIZE_BIT + 3*nTexCoordIndex) ) & 0x7 ); +} + +inline bool UsesVertexShader( VertexFormat_t vertexFormat ) +{ + return (vertexFormat & VERTEX_FORMAT_VERTEX_SHADER) != 0; +} + +inline VertexCompressionType_t CompressionType( VertexFormat_t vertexFormat ) +{ + // This is trivial now, but we may add multiple flavours of compressed vertex later on + if ( vertexFormat & VERTEX_FORMAT_COMPRESSED ) + return VERTEX_COMPRESSION_ON; + else + return VERTEX_COMPRESSION_NONE; +} + + +//----------------------------------------------------------------------------- +// VertexElement_t (enumerates all usable vertex elements) +//----------------------------------------------------------------------------- +// FIXME: unify this with VertexFormat_t (i.e. construct the lower bits of VertexFormat_t with "1 << (VertexElement_t)element") +enum VertexElement_t +{ + VERTEX_ELEMENT_NONE = -1, + + // Deliberately explicitly numbered so it's a pain in the ass to change, so you read this: + // #!#!#NOTE#!#!# update GetVertexElementSize, VertexElementToDeclType and + // CVBAllocTracker (elementTable) when you update this! + VERTEX_ELEMENT_POSITION = 0, + VERTEX_ELEMENT_NORMAL = 1, + VERTEX_ELEMENT_COLOR = 2, + VERTEX_ELEMENT_SPECULAR = 3, + VERTEX_ELEMENT_TANGENT_S = 4, + VERTEX_ELEMENT_TANGENT_T = 5, + VERTEX_ELEMENT_WRINKLE = 6, + VERTEX_ELEMENT_BONEINDEX = 7, + VERTEX_ELEMENT_BONEWEIGHTS1 = 8, + VERTEX_ELEMENT_BONEWEIGHTS2 = 9, + VERTEX_ELEMENT_BONEWEIGHTS3 = 10, + VERTEX_ELEMENT_BONEWEIGHTS4 = 11, + VERTEX_ELEMENT_USERDATA1 = 12, + VERTEX_ELEMENT_USERDATA2 = 13, + VERTEX_ELEMENT_USERDATA3 = 14, + VERTEX_ELEMENT_USERDATA4 = 15, + VERTEX_ELEMENT_TEXCOORD1D_0 = 16, + VERTEX_ELEMENT_TEXCOORD1D_1 = 17, + VERTEX_ELEMENT_TEXCOORD1D_2 = 18, + VERTEX_ELEMENT_TEXCOORD1D_3 = 19, + VERTEX_ELEMENT_TEXCOORD1D_4 = 20, + VERTEX_ELEMENT_TEXCOORD1D_5 = 21, + VERTEX_ELEMENT_TEXCOORD1D_6 = 22, + VERTEX_ELEMENT_TEXCOORD1D_7 = 23, + VERTEX_ELEMENT_TEXCOORD2D_0 = 24, + VERTEX_ELEMENT_TEXCOORD2D_1 = 25, + VERTEX_ELEMENT_TEXCOORD2D_2 = 26, + VERTEX_ELEMENT_TEXCOORD2D_3 = 27, + VERTEX_ELEMENT_TEXCOORD2D_4 = 28, + VERTEX_ELEMENT_TEXCOORD2D_5 = 29, + VERTEX_ELEMENT_TEXCOORD2D_6 = 30, + VERTEX_ELEMENT_TEXCOORD2D_7 = 31, + VERTEX_ELEMENT_TEXCOORD3D_0 = 32, + VERTEX_ELEMENT_TEXCOORD3D_1 = 33, + VERTEX_ELEMENT_TEXCOORD3D_2 = 34, + VERTEX_ELEMENT_TEXCOORD3D_3 = 35, + VERTEX_ELEMENT_TEXCOORD3D_4 = 36, + VERTEX_ELEMENT_TEXCOORD3D_5 = 37, + VERTEX_ELEMENT_TEXCOORD3D_6 = 38, + VERTEX_ELEMENT_TEXCOORD3D_7 = 39, + VERTEX_ELEMENT_TEXCOORD4D_0 = 40, + VERTEX_ELEMENT_TEXCOORD4D_1 = 41, + VERTEX_ELEMENT_TEXCOORD4D_2 = 42, + VERTEX_ELEMENT_TEXCOORD4D_3 = 43, + VERTEX_ELEMENT_TEXCOORD4D_4 = 44, + VERTEX_ELEMENT_TEXCOORD4D_5 = 45, + VERTEX_ELEMENT_TEXCOORD4D_6 = 46, + VERTEX_ELEMENT_TEXCOORD4D_7 = 47, + + VERTEX_ELEMENT_NUMELEMENTS = 48 +}; + +inline void Detect_VertexElement_t_Changes( VertexElement_t element ) // GREPs for VertexElement_t will hit this +{ + // Make it harder for someone to change VertexElement_t without noticing that dependent code + // (GetVertexElementSize, VertexElementToDeclType, CVBAllocTracker) needs updating + Assert( VERTEX_ELEMENT_NUMELEMENTS == 48 ); + switch ( element ) + { + case VERTEX_ELEMENT_POSITION: Assert( VERTEX_ELEMENT_POSITION == 0 ); break; + case VERTEX_ELEMENT_NORMAL: Assert( VERTEX_ELEMENT_NORMAL == 1 ); break; + case VERTEX_ELEMENT_COLOR: Assert( VERTEX_ELEMENT_COLOR == 2 ); break; + case VERTEX_ELEMENT_SPECULAR: Assert( VERTEX_ELEMENT_SPECULAR == 3 ); break; + case VERTEX_ELEMENT_TANGENT_S: Assert( VERTEX_ELEMENT_TANGENT_S == 4 ); break; + case VERTEX_ELEMENT_TANGENT_T: Assert( VERTEX_ELEMENT_TANGENT_T == 5 ); break; + case VERTEX_ELEMENT_WRINKLE: Assert( VERTEX_ELEMENT_WRINKLE == 6 ); break; + case VERTEX_ELEMENT_BONEINDEX: Assert( VERTEX_ELEMENT_BONEINDEX == 7 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS1: Assert( VERTEX_ELEMENT_BONEWEIGHTS1 == 8 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS2: Assert( VERTEX_ELEMENT_BONEWEIGHTS2 == 9 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS3: Assert( VERTEX_ELEMENT_BONEWEIGHTS3 == 10 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS4: Assert( VERTEX_ELEMENT_BONEWEIGHTS4 == 11 ); break; + case VERTEX_ELEMENT_USERDATA1: Assert( VERTEX_ELEMENT_USERDATA1 == 12 ); break; + case VERTEX_ELEMENT_USERDATA2: Assert( VERTEX_ELEMENT_USERDATA2 == 13 ); break; + case VERTEX_ELEMENT_USERDATA3: Assert( VERTEX_ELEMENT_USERDATA3 == 14 ); break; + case VERTEX_ELEMENT_USERDATA4: Assert( VERTEX_ELEMENT_USERDATA4 == 15 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_0: Assert( VERTEX_ELEMENT_TEXCOORD1D_0 == 16 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_1: Assert( VERTEX_ELEMENT_TEXCOORD1D_1 == 17 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_2: Assert( VERTEX_ELEMENT_TEXCOORD1D_2 == 18 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_3: Assert( VERTEX_ELEMENT_TEXCOORD1D_3 == 19 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_4: Assert( VERTEX_ELEMENT_TEXCOORD1D_4 == 20 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_5: Assert( VERTEX_ELEMENT_TEXCOORD1D_5 == 21 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_6: Assert( VERTEX_ELEMENT_TEXCOORD1D_6 == 22 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_7: Assert( VERTEX_ELEMENT_TEXCOORD1D_7 == 23 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_0: Assert( VERTEX_ELEMENT_TEXCOORD2D_0 == 24 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_1: Assert( VERTEX_ELEMENT_TEXCOORD2D_1 == 25 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_2: Assert( VERTEX_ELEMENT_TEXCOORD2D_2 == 26 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_3: Assert( VERTEX_ELEMENT_TEXCOORD2D_3 == 27 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_4: Assert( VERTEX_ELEMENT_TEXCOORD2D_4 == 28 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_5: Assert( VERTEX_ELEMENT_TEXCOORD2D_5 == 29 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_6: Assert( VERTEX_ELEMENT_TEXCOORD2D_6 == 30 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_7: Assert( VERTEX_ELEMENT_TEXCOORD2D_7 == 31 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_0: Assert( VERTEX_ELEMENT_TEXCOORD3D_0 == 32 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_1: Assert( VERTEX_ELEMENT_TEXCOORD3D_1 == 33 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_2: Assert( VERTEX_ELEMENT_TEXCOORD3D_2 == 34 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_3: Assert( VERTEX_ELEMENT_TEXCOORD3D_3 == 35 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_4: Assert( VERTEX_ELEMENT_TEXCOORD3D_4 == 36 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_5: Assert( VERTEX_ELEMENT_TEXCOORD3D_5 == 37 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_6: Assert( VERTEX_ELEMENT_TEXCOORD3D_6 == 38 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_7: Assert( VERTEX_ELEMENT_TEXCOORD3D_7 == 39 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_0: Assert( VERTEX_ELEMENT_TEXCOORD4D_0 == 40 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_1: Assert( VERTEX_ELEMENT_TEXCOORD4D_1 == 41 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_2: Assert( VERTEX_ELEMENT_TEXCOORD4D_2 == 42 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_3: Assert( VERTEX_ELEMENT_TEXCOORD4D_3 == 43 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_4: Assert( VERTEX_ELEMENT_TEXCOORD4D_4 == 44 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_5: Assert( VERTEX_ELEMENT_TEXCOORD4D_5 == 45 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_6: Assert( VERTEX_ELEMENT_TEXCOORD4D_6 == 46 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_7: Assert( VERTEX_ELEMENT_TEXCOORD4D_7 == 47 ); break; + default: + Assert( 0 ); // Invalid input or VertexElement_t has definitely changed + break; + } +} + +// We're testing 2 normal compression methods +// One compressed normals+tangents into a SHORT2 each (8 bytes total) +// The other compresses them together, into a single UBYTE4 (4 bytes total) +// FIXME: pick one or the other, compare lighting quality in important cases +#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0 +#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1 +//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 +#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 + +inline int GetVertexElementSize( VertexElement_t element, VertexCompressionType_t compressionType ) +{ + Detect_VertexElement_t_Changes( element ); + + if ( compressionType == VERTEX_COMPRESSION_ON ) + { + // Compressed-vertex element sizes + switch ( element ) + { +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + case VERTEX_ELEMENT_NORMAL: + return ( 2 * sizeof( short ) ); + case VERTEX_ELEMENT_USERDATA4: + return ( 2 * sizeof( short ) ); +#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // Normals and tangents (userdata4) are combined into a single UBYTE4 vertex element + case VERTEX_ELEMENT_NORMAL: + return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_USERDATA4: + return ( 0 ); +#endif + // Compressed bone weights use a SHORT2 vertex element: + case VERTEX_ELEMENT_BONEWEIGHTS1: + case VERTEX_ELEMENT_BONEWEIGHTS2: + return ( 2 * sizeof( short ) ); + default: + break; + } + } + + // Uncompressed-vertex element sizes + switch ( element ) + { + case VERTEX_ELEMENT_POSITION: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_NORMAL: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_COLOR: return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_SPECULAR: return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_TANGENT_S: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TANGENT_T: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_WRINKLE: return ( 1 * sizeof( float ) ); // Packed into Position.W + case VERTEX_ELEMENT_BONEINDEX: return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_BONEWEIGHTS1: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_BONEWEIGHTS2: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_BONEWEIGHTS3: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_BONEWEIGHTS4: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA1: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA2: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA3: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA4: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_0: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_1: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_2: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_3: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_4: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_5: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_6: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_7: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_0: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_1: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_2: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_3: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_4: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_5: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_6: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_7: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_0: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_1: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_2: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_3: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_4: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_5: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_6: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_7: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_0: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_1: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_2: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_3: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_4: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_5: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_6: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_7: return ( 4 * sizeof( float ) ); + default: + Assert(0); + return 0; + }; +} + + +//----------------------------------------------------------------------------- +// Shader state flags can be read from the FLAGS materialvar +// Also can be read or written to with the Set/GetMaterialVarFlags() call +// Also make sure you add/remove a string associated with each flag below to CShaderSystem::ShaderStateString in ShaderSystem.cpp +//----------------------------------------------------------------------------- +enum MaterialVarFlags_t +{ + MATERIAL_VAR_DEBUG = (1 << 0), + MATERIAL_VAR_NO_DEBUG_OVERRIDE = (1 << 1), + MATERIAL_VAR_NO_DRAW = (1 << 2), + MATERIAL_VAR_USE_IN_FILLRATE_MODE = (1 << 3), + + MATERIAL_VAR_VERTEXCOLOR = (1 << 4), + MATERIAL_VAR_VERTEXALPHA = (1 << 5), + MATERIAL_VAR_SELFILLUM = (1 << 6), + MATERIAL_VAR_ADDITIVE = (1 << 7), + MATERIAL_VAR_ALPHATEST = (1 << 8), + MATERIAL_VAR_MULTIPASS = (1 << 9), + MATERIAL_VAR_ZNEARER = (1 << 10), + MATERIAL_VAR_MODEL = (1 << 11), + MATERIAL_VAR_FLAT = (1 << 12), + MATERIAL_VAR_NOCULL = (1 << 13), + MATERIAL_VAR_NOFOG = (1 << 14), + MATERIAL_VAR_IGNOREZ = (1 << 15), + MATERIAL_VAR_DECAL = (1 << 16), + MATERIAL_VAR_ENVMAPSPHERE = (1 << 17), + MATERIAL_VAR_NOALPHAMOD = (1 << 18), + MATERIAL_VAR_ENVMAPCAMERASPACE = (1 << 19), + MATERIAL_VAR_BASEALPHAENVMAPMASK = (1 << 20), + MATERIAL_VAR_TRANSLUCENT = (1 << 21), + MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK = (1 << 22), + MATERIAL_VAR_NEEDS_SOFTWARE_SKINNING = (1 << 23), + MATERIAL_VAR_OPAQUETEXTURE = (1 << 24), + MATERIAL_VAR_ENVMAPMODE = (1 << 25), + MATERIAL_VAR_SUPPRESS_DECALS = (1 << 26), + MATERIAL_VAR_HALFLAMBERT = (1 << 27), + MATERIAL_VAR_WIREFRAME = (1 << 28), + MATERIAL_VAR_ALLOWALPHATOCOVERAGE = (1 << 29), + MATERIAL_VAR_IGNORE_ALPHA_MODULATION = (1 << 30), + + // NOTE: Only add flags here that either should be read from + // .vmts or can be set directly from client code. Other, internal + // flags should to into the flag enum in imaterialinternal.h +}; + + +//----------------------------------------------------------------------------- +// Internal flags not accessible from outside the material system. Stored in Flags2 +//----------------------------------------------------------------------------- +enum MaterialVarFlags2_t +{ + // NOTE: These are for $flags2!!!!! +// UNUSED = (1 << 0), + + MATERIAL_VAR2_LIGHTING_UNLIT = 0, + MATERIAL_VAR2_LIGHTING_VERTEX_LIT = (1 << 1), + MATERIAL_VAR2_LIGHTING_LIGHTMAP = (1 << 2), + MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP = (1 << 3), + MATERIAL_VAR2_LIGHTING_MASK = + ( MATERIAL_VAR2_LIGHTING_VERTEX_LIT | + MATERIAL_VAR2_LIGHTING_LIGHTMAP | + MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ), + + // FIXME: Should this be a part of the above lighting enums? + MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL = (1 << 4), + MATERIAL_VAR2_USES_ENV_CUBEMAP = (1 << 5), + MATERIAL_VAR2_NEEDS_TANGENT_SPACES = (1 << 6), + MATERIAL_VAR2_NEEDS_SOFTWARE_LIGHTING = (1 << 7), + // GR - HDR path puts lightmap alpha in separate texture... + MATERIAL_VAR2_BLEND_WITH_LIGHTMAP_ALPHA = (1 << 8), + MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS = (1 << 9), + MATERIAL_VAR2_USE_FLASHLIGHT = (1 << 10), + MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING = (1 << 11), + MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT = (1 << 12), + MATERIAL_VAR2_USE_EDITOR = (1 << 13), + MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE = (1 << 14), + MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE = (1 << 15), + MATERIAL_VAR2_IS_SPRITECARD = (1 << 16), + MATERIAL_VAR2_USES_VERTEXID = (1 << 17), + MATERIAL_VAR2_SUPPORTS_HW_SKINNING = (1 << 18), + MATERIAL_VAR2_SUPPORTS_FLASHLIGHT = (1 << 19), +}; + + +//----------------------------------------------------------------------------- +// Preview image return values +//----------------------------------------------------------------------------- +enum PreviewImageRetVal_t +{ + MATERIAL_PREVIEW_IMAGE_BAD = 0, + MATERIAL_PREVIEW_IMAGE_OK, + MATERIAL_NO_PREVIEW_IMAGE, +}; + + +//----------------------------------------------------------------------------- +// material interface +//----------------------------------------------------------------------------- +abstract_class IMaterial +{ +public: + // Get the name of the material. This is a full path to + // the vmt file starting from "hl2/materials" (or equivalent) without + // a file extension. + virtual const char * GetName() const = 0; + virtual const char * GetTextureGroupName() const = 0; + + // Get the preferred size/bitDepth of a preview image of a material. + // This is the sort of image that you would use for a thumbnail view + // of a material, or in WorldCraft until it uses materials to render. + // separate this for the tools maybe + virtual PreviewImageRetVal_t GetPreviewImageProperties( int *width, int *height, + ImageFormat *imageFormat, bool* isTranslucent ) const = 0; + + // Get a preview image at the specified width/height and bitDepth. + // Will do resampling if necessary.(not yet!!! :) ) + // Will do color format conversion. (works now.) + virtual PreviewImageRetVal_t GetPreviewImage( unsigned char *data, + int width, int height, + ImageFormat imageFormat ) const = 0; + // + virtual int GetMappingWidth( ) = 0; + virtual int GetMappingHeight( ) = 0; + + virtual int GetNumAnimationFrames( ) = 0; + + // For material subrects (material pages). Offset(u,v) and scale(u,v) are normalized to texture. + virtual bool InMaterialPage( void ) = 0; + virtual void GetMaterialOffset( float *pOffset ) = 0; + virtual void GetMaterialScale( float *pScale ) = 0; + virtual IMaterial *GetMaterialPage( void ) = 0; + + // find a vmt variable. + // This is how game code affects how a material is rendered. + // The game code must know about the params that are used by + // the shader for the material that it is trying to affect. + virtual IMaterialVar * FindVar( const char *varName, bool *found, bool complain = true ) = 0; + + // The user never allocates or deallocates materials. Reference counting is + // used instead. Garbage collection is done upon a call to + // IMaterialSystem::UncacheUnusedMaterials. + virtual void IncrementReferenceCount( void ) = 0; + virtual void DecrementReferenceCount( void ) = 0; + + inline void AddRef() { IncrementReferenceCount(); } + inline void Release() { DecrementReferenceCount(); } + + // Each material is assigned a number that groups it with like materials + // for sorting in the application. + virtual int GetEnumerationID( void ) const = 0; + + virtual void GetLowResColorSample( float s, float t, float *color ) const = 0; + + // This computes the state snapshots for this material + virtual void RecomputeStateSnapshots() = 0; + + // Are we translucent? + virtual bool IsTranslucent() = 0; + + // Are we alphatested? + virtual bool IsAlphaTested() = 0; + + // Are we vertex lit? + virtual bool IsVertexLit() = 0; + + // Gets the vertex format + virtual VertexFormat_t GetVertexFormat() const = 0; + + // returns true if this material uses a material proxy + virtual bool HasProxy( void ) const = 0; + + virtual bool UsesEnvCubemap( void ) = 0; + + virtual bool NeedsTangentSpace( void ) = 0; + + virtual bool NeedsPowerOfTwoFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0; + virtual bool NeedsFullFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0; + + // returns true if the shader doesn't do skinning itself and requires + // the data that is sent to it to be preskinned. + virtual bool NeedsSoftwareSkinning( void ) = 0; + + // Apply constant color or alpha modulation + virtual void AlphaModulate( float alpha ) = 0; + virtual void ColorModulate( float r, float g, float b ) = 0; + + // Material Var flags... + virtual void SetMaterialVarFlag( MaterialVarFlags_t flag, bool on ) = 0; + virtual bool GetMaterialVarFlag( MaterialVarFlags_t flag ) const = 0; + + // Gets material reflectivity + virtual void GetReflectivity( Vector& reflect ) = 0; + + // Gets material property flags + virtual bool GetPropertyFlag( MaterialPropertyTypes_t type ) = 0; + + // Is the material visible from both sides? + virtual bool IsTwoSided() = 0; + + // Sets the shader associated with the material + virtual void SetShader( const char *pShaderName ) = 0; + + // Can't be const because the material might have to precache itself. + virtual int GetNumPasses( void ) = 0; + + // Can't be const because the material might have to precache itself. + virtual int GetTextureMemoryBytes( void ) = 0; + + // 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() = 0; + + // GR - returns true is material uses lightmap alpha for blending + virtual bool NeedsLightmapBlendAlpha( void ) = 0; + + // 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 ) = 0; + + // Gets at the shader parameters + virtual int ShaderParamCount() const = 0; + virtual IMaterialVar **GetShaderParams( void ) = 0; + + // Returns true if this is the error material you get back from IMaterialSystem::FindMaterial if + // the material can't be found. + virtual bool IsErrorMaterial() const = 0; + + virtual void SetUseFixedFunctionBakedLighting( bool bEnable ) = 0; + + // Gets the current alpha modulation + virtual float GetAlphaModulation() = 0; + virtual void GetColorModulation( float *r, float *g, float *b ) = 0; + + // Gets the morph format + virtual MorphFormat_t GetMorphFormat() const = 0; + + // fast find that stores the index of the found var in the string table in local cache + virtual IMaterialVar * FindVarFast( char const *pVarName, unsigned int *pToken ) = 0; + + // Sets new VMT shader parameters for the material + virtual void SetShaderAndParams( KeyValues *pKeyValues ) = 0; + virtual const char * GetShaderName() const = 0; + + virtual void DeleteIfUnreferenced() = 0; + + virtual bool IsSpriteCard() = 0; + + virtual void CallBindProxy( void *proxyData ) = 0; + + virtual IMaterial *CheckProxyReplacement( void *proxyData ) = 0; + + virtual void RefreshPreservingMaterialVars() = 0; + + virtual bool WasReloadedFromWhitelist() = 0; + + virtual bool IsPrecached() const = 0; +}; + + +inline bool IsErrorMaterial( IMaterial *pMat ) +{ + return !pMat || pMat->IsErrorMaterial(); +} + +#endif // IMATERIAL_H diff --git a/mp/src/public/materialsystem/imaterialproxy.h b/mp/src/public/materialsystem/imaterialproxy.h index 603ef03b..52c49bef 100644 --- a/mp/src/public/materialsystem/imaterialproxy.h +++ b/mp/src/public/materialsystem/imaterialproxy.h @@ -1,32 +1,32 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef IMATERIALPROXY_H
-#define IMATERIALPROXY_H
-#pragma once
-
-#include "interface.h"
-
-#define IMATERIAL_PROXY_INTERFACE_VERSION "_IMaterialProxy003"
-
-class IMaterial;
-class KeyValues;
-
-abstract_class IMaterialProxy
-{
-public:
- virtual bool Init( IMaterial* pMaterial, KeyValues *pKeyValues ) = 0;
- virtual void OnBind( void * ) = 0;
- virtual void Release() = 0;
- virtual IMaterial * GetMaterial() = 0;
-
-protected:
- // no one should call this directly
- virtual ~IMaterialProxy() {}
-};
-
-#endif // IMATERIALPROXY_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IMATERIALPROXY_H +#define IMATERIALPROXY_H +#pragma once + +#include "interface.h" + +#define IMATERIAL_PROXY_INTERFACE_VERSION "_IMaterialProxy003" + +class IMaterial; +class KeyValues; + +abstract_class IMaterialProxy +{ +public: + virtual bool Init( IMaterial* pMaterial, KeyValues *pKeyValues ) = 0; + virtual void OnBind( void * ) = 0; + virtual void Release() = 0; + virtual IMaterial * GetMaterial() = 0; + +protected: + // no one should call this directly + virtual ~IMaterialProxy() {} +}; + +#endif // IMATERIALPROXY_H diff --git a/mp/src/public/materialsystem/imaterialproxyfactory.h b/mp/src/public/materialsystem/imaterialproxyfactory.h index e9d47ee6..4045cb00 100644 --- a/mp/src/public/materialsystem/imaterialproxyfactory.h +++ b/mp/src/public/materialsystem/imaterialproxyfactory.h @@ -1,25 +1,25 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef IMATERIALPROXYFACTORY_H
-#define IMATERIALPROXYFACTORY_H
-#pragma once
-
-#include "interface.h"
-
-#define IMATERIAL_PROXY_FACTOR_INTERFACE_VERSION "IMaterialProxyFactory001"
-
-class IMaterialProxy;
-
-abstract_class IMaterialProxyFactory
-{
-public:
- virtual IMaterialProxy *CreateProxy( const char *proxyName ) = 0;
- virtual void DeleteProxy( IMaterialProxy *pProxy ) = 0;
-};
-
-#endif // IMATERIALPROXYFACTORY_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IMATERIALPROXYFACTORY_H +#define IMATERIALPROXYFACTORY_H +#pragma once + +#include "interface.h" + +#define IMATERIAL_PROXY_FACTOR_INTERFACE_VERSION "IMaterialProxyFactory001" + +class IMaterialProxy; + +abstract_class IMaterialProxyFactory +{ +public: + virtual IMaterialProxy *CreateProxy( const char *proxyName ) = 0; + virtual void DeleteProxy( IMaterialProxy *pProxy ) = 0; +}; + +#endif // IMATERIALPROXYFACTORY_H diff --git a/mp/src/public/materialsystem/imaterialsystem.h b/mp/src/public/materialsystem/imaterialsystem.h index cc125156..9a16b9db 100644 --- a/mp/src/public/materialsystem/imaterialsystem.h +++ b/mp/src/public/materialsystem/imaterialsystem.h @@ -1,1758 +1,1758 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-
-#ifndef IMATERIALSYSTEM_H
-#define IMATERIALSYSTEM_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#define OVERBRIGHT 2.0f
-#define OO_OVERBRIGHT ( 1.0f / 2.0f )
-#define GAMMA 2.2f
-#define TEXGAMMA 2.2f
-
-#include "tier1/interface.h"
-#include "tier1/refcount.h"
-#include "mathlib/vector.h"
-#include "mathlib/vector4d.h"
-#include "mathlib/vmatrix.h"
-#include "appframework/IAppSystem.h"
-#include "bitmap/imageformat.h"
-#include "texture_group_names.h"
-#include "vtf/vtf.h"
-#include "materialsystem/deformations.h"
-#include "materialsystem/imaterialsystemhardwareconfig.h"
-#include "materialsystem/IColorCorrection.h"
-
-
-//-----------------------------------------------------------------------------
-// forward declarations
-//-----------------------------------------------------------------------------
-class IMaterial;
-class IMesh;
-class IVertexBuffer;
-class IIndexBuffer;
-struct MaterialSystem_Config_t;
-class VMatrix;
-struct matrix3x4_t;
-class ITexture;
-struct MaterialSystemHardwareIdentifier_t;
-class KeyValues;
-class IShader;
-class IVertexTexture;
-class IMorph;
-class IMatRenderContext;
-class ICallQueue;
-struct MorphWeight_t;
-class IFileList;
-
-
-//-----------------------------------------------------------------------------
-// The vertex format type
-//-----------------------------------------------------------------------------
-typedef uint64 VertexFormat_t;
-
-//-----------------------------------------------------------------------------
-// important enumeration
-//-----------------------------------------------------------------------------
-
-// NOTE NOTE NOTE!!!! If you up this, grep for "NEW_INTERFACE" to see if there is anything
-// waiting to be enabled during an interface revision.
-#define MATERIAL_SYSTEM_INTERFACE_VERSION "VMaterialSystem080"
-
-#ifdef POSIX
-#define ABSOLUTE_MINIMUM_DXLEVEL 90
-#else
-#define ABSOLUTE_MINIMUM_DXLEVEL 80
-#endif
-
-enum ShaderParamType_t
-{
- SHADER_PARAM_TYPE_TEXTURE,
- SHADER_PARAM_TYPE_INTEGER,
- SHADER_PARAM_TYPE_COLOR,
- SHADER_PARAM_TYPE_VEC2,
- SHADER_PARAM_TYPE_VEC3,
- SHADER_PARAM_TYPE_VEC4,
- SHADER_PARAM_TYPE_ENVMAP, // obsolete
- SHADER_PARAM_TYPE_FLOAT,
- SHADER_PARAM_TYPE_BOOL,
- SHADER_PARAM_TYPE_FOURCC,
- SHADER_PARAM_TYPE_MATRIX,
- SHADER_PARAM_TYPE_MATERIAL,
- SHADER_PARAM_TYPE_STRING,
-};
-
-enum MaterialMatrixMode_t
-{
- MATERIAL_VIEW = 0,
- MATERIAL_PROJECTION,
-
- // Texture matrices
- MATERIAL_TEXTURE0,
- MATERIAL_TEXTURE1,
- MATERIAL_TEXTURE2,
- MATERIAL_TEXTURE3,
- MATERIAL_TEXTURE4,
- MATERIAL_TEXTURE5,
- MATERIAL_TEXTURE6,
- MATERIAL_TEXTURE7,
-
- MATERIAL_MODEL,
-
- // Total number of matrices
- NUM_MATRIX_MODES = MATERIAL_MODEL+1,
-
- // Number of texture transforms
- NUM_TEXTURE_TRANSFORMS = MATERIAL_TEXTURE7 - MATERIAL_TEXTURE0 + 1
-};
-
-// FIXME: How do I specify the actual number of matrix modes?
-const int NUM_MODEL_TRANSFORMS = 53;
-const int MATERIAL_MODEL_MAX = MATERIAL_MODEL + NUM_MODEL_TRANSFORMS;
-
-enum MaterialPrimitiveType_t
-{
- MATERIAL_POINTS = 0x0,
- MATERIAL_LINES,
- MATERIAL_TRIANGLES,
- MATERIAL_TRIANGLE_STRIP,
- MATERIAL_LINE_STRIP,
- MATERIAL_LINE_LOOP, // a single line loop
- MATERIAL_POLYGON, // this is a *single* polygon
- MATERIAL_QUADS,
- MATERIAL_INSTANCED_QUADS, // (X360) like MATERIAL_QUADS, but uses vertex instancing
-
- // This is used for static meshes that contain multiple types of
- // primitive types. When calling draw, you'll need to specify
- // a primitive type.
- MATERIAL_HETEROGENOUS
-};
-
-enum MaterialPropertyTypes_t
-{
- MATERIAL_PROPERTY_NEEDS_LIGHTMAP = 0, // bool
- MATERIAL_PROPERTY_OPACITY, // int (enum MaterialPropertyOpacityTypes_t)
- MATERIAL_PROPERTY_REFLECTIVITY, // vec3_t
- MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS // bool
-};
-
-// acceptable property values for MATERIAL_PROPERTY_OPACITY
-enum MaterialPropertyOpacityTypes_t
-{
- MATERIAL_ALPHATEST = 0,
- MATERIAL_OPAQUE,
- MATERIAL_TRANSLUCENT
-};
-
-enum MaterialBufferTypes_t
-{
- MATERIAL_FRONT = 0,
- MATERIAL_BACK
-};
-
-enum MaterialCullMode_t
-{
- MATERIAL_CULLMODE_CCW, // this culls polygons with counterclockwise winding
- MATERIAL_CULLMODE_CW // this culls polygons with clockwise winding
-};
-
-enum MaterialIndexFormat_t
-{
- MATERIAL_INDEX_FORMAT_UNKNOWN = -1,
- MATERIAL_INDEX_FORMAT_16BIT = 0,
- MATERIAL_INDEX_FORMAT_32BIT,
-};
-
-enum MaterialFogMode_t
-{
- MATERIAL_FOG_NONE,
- MATERIAL_FOG_LINEAR,
- MATERIAL_FOG_LINEAR_BELOW_FOG_Z,
-};
-
-enum MaterialHeightClipMode_t
-{
- MATERIAL_HEIGHTCLIPMODE_DISABLE,
- MATERIAL_HEIGHTCLIPMODE_RENDER_ABOVE_HEIGHT,
- MATERIAL_HEIGHTCLIPMODE_RENDER_BELOW_HEIGHT
-};
-
-enum MaterialNonInteractiveMode_t
-{
- MATERIAL_NON_INTERACTIVE_MODE_NONE = -1,
- MATERIAL_NON_INTERACTIVE_MODE_STARTUP = 0,
- MATERIAL_NON_INTERACTIVE_MODE_LEVEL_LOAD,
-
- MATERIAL_NON_INTERACTIVE_MODE_COUNT,
-};
-
-
-//-----------------------------------------------------------------------------
-// Special morph used in decalling pass
-//-----------------------------------------------------------------------------
-#define MATERIAL_MORPH_DECAL ( (IMorph*)1 )
-
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-enum MaterialThreadMode_t
-{
- MATERIAL_SINGLE_THREADED,
- MATERIAL_QUEUED_SINGLE_THREADED,
- MATERIAL_QUEUED_THREADED
-};
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-enum MaterialContextType_t
-{
- MATERIAL_HARDWARE_CONTEXT,
- MATERIAL_QUEUED_CONTEXT,
- MATERIAL_NULL_CONTEXT
-};
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-enum MaterialFindContext_t
-{
- MATERIAL_FINDCONTEXT_NONE,
- MATERIAL_FINDCONTEXT_ISONAMODEL,
-};
-
-//-----------------------------------------------------------------------------
-// Light structure
-//-----------------------------------------------------------------------------
-#include "mathlib/lightdesc.h"
-
-#if 0
-enum LightType_t
-{
- MATERIAL_LIGHT_DISABLE = 0,
- MATERIAL_LIGHT_POINT,
- MATERIAL_LIGHT_DIRECTIONAL,
- MATERIAL_LIGHT_SPOT,
-};
-
-enum LightType_OptimizationFlags_t
-{
- LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 = 1,
- LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 = 2,
- LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 = 4,
-};
-
-
-struct LightDesc_t
-{
- LightType_t m_Type;
- Vector m_Color;
- Vector m_Position;
- Vector m_Direction;
- float m_Range;
- float m_Falloff;
- float m_Attenuation0;
- float m_Attenuation1;
- float m_Attenuation2;
- float m_Theta;
- float m_Phi;
- // These aren't used by DX8. . used for software lighting.
- float m_ThetaDot;
- float m_PhiDot;
- unsigned int m_Flags;
-
-
- LightDesc_t() {}
-
-private:
- // No copy constructors allowed
- LightDesc_t(const LightDesc_t& vOther);
-};
-#endif
-
-#define CREATERENDERTARGETFLAGS_HDR 0x00000001
-#define CREATERENDERTARGETFLAGS_AUTOMIPMAP 0x00000002
-#define CREATERENDERTARGETFLAGS_UNFILTERABLE_OK 0x00000004
-// XBOX ONLY:
-#define CREATERENDERTARGETFLAGS_NOEDRAM 0x00000008 // inhibit allocation in 360 EDRAM
-#define CREATERENDERTARGETFLAGS_TEMP 0x00000010 // only allocates memory upon first resolve, destroyed at level end
-
-
-//-----------------------------------------------------------------------------
-// allowed stencil operations. These match the d3d operations
-//-----------------------------------------------------------------------------
-enum StencilOperation_t
-{
-#if !defined( _X360 )
- STENCILOPERATION_KEEP = 1,
- STENCILOPERATION_ZERO = 2,
- STENCILOPERATION_REPLACE = 3,
- STENCILOPERATION_INCRSAT = 4,
- STENCILOPERATION_DECRSAT = 5,
- STENCILOPERATION_INVERT = 6,
- STENCILOPERATION_INCR = 7,
- STENCILOPERATION_DECR = 8,
-#else
- STENCILOPERATION_KEEP = D3DSTENCILOP_KEEP,
- STENCILOPERATION_ZERO = D3DSTENCILOP_ZERO,
- STENCILOPERATION_REPLACE = D3DSTENCILOP_REPLACE,
- STENCILOPERATION_INCRSAT = D3DSTENCILOP_INCRSAT,
- STENCILOPERATION_DECRSAT = D3DSTENCILOP_DECRSAT,
- STENCILOPERATION_INVERT = D3DSTENCILOP_INVERT,
- STENCILOPERATION_INCR = D3DSTENCILOP_INCR,
- STENCILOPERATION_DECR = D3DSTENCILOP_DECR,
-#endif
- STENCILOPERATION_FORCE_DWORD = 0x7fffffff
-};
-
-enum StencilComparisonFunction_t
-{
-#if !defined( _X360 )
- STENCILCOMPARISONFUNCTION_NEVER = 1,
- STENCILCOMPARISONFUNCTION_LESS = 2,
- STENCILCOMPARISONFUNCTION_EQUAL = 3,
- STENCILCOMPARISONFUNCTION_LESSEQUAL = 4,
- STENCILCOMPARISONFUNCTION_GREATER = 5,
- STENCILCOMPARISONFUNCTION_NOTEQUAL = 6,
- STENCILCOMPARISONFUNCTION_GREATEREQUAL = 7,
- STENCILCOMPARISONFUNCTION_ALWAYS = 8,
-#else
- STENCILCOMPARISONFUNCTION_NEVER = D3DCMP_NEVER,
- STENCILCOMPARISONFUNCTION_LESS = D3DCMP_LESS,
- STENCILCOMPARISONFUNCTION_EQUAL = D3DCMP_EQUAL,
- STENCILCOMPARISONFUNCTION_LESSEQUAL = D3DCMP_LESSEQUAL,
- STENCILCOMPARISONFUNCTION_GREATER = D3DCMP_GREATER,
- STENCILCOMPARISONFUNCTION_NOTEQUAL = D3DCMP_NOTEQUAL,
- STENCILCOMPARISONFUNCTION_GREATEREQUAL = D3DCMP_GREATEREQUAL,
- STENCILCOMPARISONFUNCTION_ALWAYS = D3DCMP_ALWAYS,
-#endif
-
- STENCILCOMPARISONFUNCTION_FORCE_DWORD = 0x7fffffff
-};
-
-
-//-----------------------------------------------------------------------------
-// Enumeration for the various fields capable of being morphed
-//-----------------------------------------------------------------------------
-enum MorphFormatFlags_t
-{
- MORPH_POSITION = 0x0001, // 3D
- MORPH_NORMAL = 0x0002, // 3D
- MORPH_WRINKLE = 0x0004, // 1D
- MORPH_SPEED = 0x0008, // 1D
- MORPH_SIDE = 0x0010, // 1D
-};
-
-
-//-----------------------------------------------------------------------------
-// The morph format type
-//-----------------------------------------------------------------------------
-typedef unsigned int MorphFormat_t;
-
-
-//-----------------------------------------------------------------------------
-// Standard lightmaps
-//-----------------------------------------------------------------------------
-enum StandardLightmap_t
-{
- MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE = -1,
- MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE_BUMP = -2,
- MATERIAL_SYSTEM_LIGHTMAP_PAGE_USER_DEFINED = -3
-};
-
-
-struct MaterialSystem_SortInfo_t
-{
- IMaterial *material;
- int lightmapPageID;
-};
-
-
-#define MAX_FB_TEXTURES 4
-
-//-----------------------------------------------------------------------------
-// Information about each adapter
-//-----------------------------------------------------------------------------
-enum
-{
- MATERIAL_ADAPTER_NAME_LENGTH = 512
-};
-
-struct MaterialAdapterInfo_t
-{
- char m_pDriverName[MATERIAL_ADAPTER_NAME_LENGTH];
- unsigned int m_VendorID;
- unsigned int m_DeviceID;
- unsigned int m_SubSysID;
- unsigned int m_Revision;
- int m_nDXSupportLevel; // This is the *preferred* dx support level
- int m_nMaxDXSupportLevel;
- unsigned int m_nDriverVersionHigh;
- unsigned int m_nDriverVersionLow;
-};
-
-
-//-----------------------------------------------------------------------------
-// Video mode info..
-//-----------------------------------------------------------------------------
-struct MaterialVideoMode_t
-{
- int m_Width; // if width and height are 0 and you select
- int m_Height; // windowed mode, it'll use the window size
- ImageFormat m_Format; // use ImageFormats (ignored for windowed mode)
- int m_RefreshRate; // 0 == default (ignored for windowed mode)
-};
-
-// fixme: should move this into something else.
-struct FlashlightState_t
-{
- FlashlightState_t()
- {
- m_bEnableShadows = false; // Provide reasonable defaults for shadow depth mapping parameters
- m_bDrawShadowFrustum = false;
- m_flShadowMapResolution = 1024.0f;
- m_flShadowFilterSize = 3.0f;
- m_flShadowSlopeScaleDepthBias = 16.0f;
- m_flShadowDepthBias = 0.0005f;
- m_flShadowJitterSeed = 0.0f;
- m_flShadowAtten = 0.0f;
- m_bScissor = false;
- m_nLeft = -1;
- m_nTop = -1;
- m_nRight = -1;
- m_nBottom = -1;
- m_nShadowQuality = 0;
- }
-
- Vector m_vecLightOrigin;
- Quaternion m_quatOrientation;
- float m_NearZ;
- float m_FarZ;
- float m_fHorizontalFOVDegrees;
- float m_fVerticalFOVDegrees;
- float m_fQuadraticAtten;
- float m_fLinearAtten;
- float m_fConstantAtten;
- float m_Color[4];
- ITexture *m_pSpotlightTexture;
- int m_nSpotlightTextureFrame;
-
- // Shadow depth mapping parameters
- bool m_bEnableShadows;
- bool m_bDrawShadowFrustum;
- float m_flShadowMapResolution;
- float m_flShadowFilterSize;
- float m_flShadowSlopeScaleDepthBias;
- float m_flShadowDepthBias;
- float m_flShadowJitterSeed;
- float m_flShadowAtten;
- int m_nShadowQuality;
-
- // Getters for scissor members
- bool DoScissor() { return m_bScissor; }
- int GetLeft() { return m_nLeft; }
- int GetTop() { return m_nTop; }
- int GetRight() { return m_nRight; }
- int GetBottom() { return m_nBottom; }
-
-private:
-
- friend class CShadowMgr;
-
- bool m_bScissor;
- int m_nLeft;
- int m_nTop;
- int m_nRight;
- int m_nBottom;
-};
-
-//-----------------------------------------------------------------------------
-// Flags to be used with the Init call
-//-----------------------------------------------------------------------------
-enum MaterialInitFlags_t
-{
- MATERIAL_INIT_ALLOCATE_FULLSCREEN_TEXTURE = 0x2,
- MATERIAL_INIT_REFERENCE_RASTERIZER = 0x4,
-};
-
-//-----------------------------------------------------------------------------
-// Flags to specify type of depth buffer used with RT
-//-----------------------------------------------------------------------------
-
-// GR - this is to add RT with no depth buffer bound
-
-enum MaterialRenderTargetDepth_t
-{
- MATERIAL_RT_DEPTH_SHARED = 0x0,
- MATERIAL_RT_DEPTH_SEPARATE = 0x1,
- MATERIAL_RT_DEPTH_NONE = 0x2,
- MATERIAL_RT_DEPTH_ONLY = 0x3,
-};
-
-//-----------------------------------------------------------------------------
-// A function to be called when we need to release all vertex buffers
-// NOTE: The restore function will tell the caller if all the vertex formats
-// changed so that it can flush caches, etc. if it needs to (for dxlevel support)
-//-----------------------------------------------------------------------------
-enum RestoreChangeFlags_t
-{
- MATERIAL_RESTORE_VERTEX_FORMAT_CHANGED = 0x1,
-};
-
-
-// NOTE: All size modes will force the render target to be smaller than or equal to
-// the size of the framebuffer.
-enum RenderTargetSizeMode_t
-{
- RT_SIZE_NO_CHANGE=0, // Only allowed for render targets that don't want a depth buffer
- // (because if they have a depth buffer, the render target must be less than or equal to the size of the framebuffer).
- RT_SIZE_DEFAULT=1, // Don't play with the specified width and height other than making sure it fits in the framebuffer.
- RT_SIZE_PICMIP=2, // Apply picmip to the render target's width and height.
- RT_SIZE_HDR=3, // frame_buffer_width / 4
- RT_SIZE_FULL_FRAME_BUFFER=4, // Same size as frame buffer, or next lower power of 2 if we can't do that.
- RT_SIZE_OFFSCREEN=5, // Target of specified size, don't mess with dimensions
- RT_SIZE_FULL_FRAME_BUFFER_ROUNDED_UP=6, // Same size as the frame buffer, rounded up if necessary for systems that can't do non-power of two textures.
- RT_SIZE_REPLAY_SCREENSHOT = 7 // Rounded down to power of 2, essentially...
-};
-
-typedef void (*MaterialBufferReleaseFunc_t)( );
-typedef void (*MaterialBufferRestoreFunc_t)( int nChangeFlags ); // see RestoreChangeFlags_t
-typedef void (*ModeChangeCallbackFunc_t)( void );
-
-typedef int VertexBufferHandle_t;
-typedef unsigned short MaterialHandle_t;
-
-DECLARE_POINTER_HANDLE( OcclusionQueryObjectHandle_t );
-#define INVALID_OCCLUSION_QUERY_OBJECT_HANDLE ( (OcclusionQueryObjectHandle_t)0 )
-
-class IMaterialProxyFactory;
-class ITexture;
-class IMaterialSystemHardwareConfig;
-class CShadowMgr;
-
-DECLARE_POINTER_HANDLE( MaterialLock_t );
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-abstract_class IMaterialSystem : public IAppSystem
-{
-public:
-
- // Placeholder for API revision
- virtual bool Connect( CreateInterfaceFn factory ) = 0;
- virtual void Disconnect() = 0;
- virtual void *QueryInterface( const char *pInterfaceName ) = 0;
- virtual InitReturnVal_t Init() = 0;
- virtual void Shutdown() = 0;
-
- //---------------------------------------------------------
- // Initialization and shutdown
- //---------------------------------------------------------
-
- // Call this to initialize the material system
- // returns a method to create interfaces in the shader dll
- virtual CreateInterfaceFn Init( char const* pShaderAPIDLL,
- IMaterialProxyFactory *pMaterialProxyFactory,
- CreateInterfaceFn fileSystemFactory,
- CreateInterfaceFn cvarFactory=NULL ) = 0;
-
- // Call this to set an explicit shader version to use
- // Must be called before Init().
- virtual void SetShaderAPI( char const *pShaderAPIDLL ) = 0;
-
- // Must be called before Init(), if you're going to call it at all...
- virtual void SetAdapter( int nAdapter, int nFlags ) = 0;
-
- // Call this when the mod has been set up, which may occur after init
- // At this point, the game + gamebin paths have been set up
- virtual void ModInit() = 0;
- virtual void ModShutdown() = 0;
-
- //---------------------------------------------------------
- //
- //---------------------------------------------------------
- virtual void SetThreadMode( MaterialThreadMode_t mode, int nServiceThread = -1 ) = 0;
- virtual MaterialThreadMode_t GetThreadMode( ) = 0;
- virtual bool IsRenderThreadSafe( ) = 0;
- virtual void ExecuteQueued() = 0;
-
- //---------------------------------------------------------
- // Config management
- //---------------------------------------------------------
-
- virtual IMaterialSystemHardwareConfig *GetHardwareConfig( const char *pVersion, int *returnCode ) = 0;
-
-
- // 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 bForceUpdate ) = 0;
-
- // Force this to be the config; update all material system convars to match the state
- // return true if lightmaps need to be redownloaded
- virtual bool OverrideConfig( const MaterialSystem_Config_t &config, bool bForceUpdate ) = 0;
-
- // Get the current config for this video card (as last set by UpdateConfig)
- virtual const MaterialSystem_Config_t &GetCurrentConfigForVideoCard() const = 0;
-
- // Gets *recommended* configuration information associated with the display card,
- // given a particular dx level to run under.
- // Use dxlevel 0 to use the recommended dx level.
- // The function returns false if an invalid dxlevel was specified
-
- // UNDONE: To find out all convars affected by configuration, we'll need to change
- // the dxsupport.pl program to output all column headers into a single keyvalue block
- // and then we would read that in, and send it back to the client
- virtual bool GetRecommendedConfigurationInfo( int nDXLevel, KeyValues * pKeyValues ) = 0;
-
-
- // -----------------------------------------------------------
- // Device methods
- // -----------------------------------------------------------
-
- // Gets the number of adapters...
- virtual int GetDisplayAdapterCount() const = 0;
-
- // Returns the current adapter in use
- virtual int GetCurrentAdapter() const = 0;
-
- // Returns info about each adapter
- virtual void GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const = 0;
-
- // Returns the number of modes
- virtual int GetModeCount( int adapter ) const = 0;
-
- // Returns mode information..
- virtual void GetModeInfo( int adapter, int mode, MaterialVideoMode_t& info ) const = 0;
-
- virtual void AddModeChangeCallBack( ModeChangeCallbackFunc_t func ) = 0;
-
- // Returns the mode info for the current display device
- virtual void GetDisplayMode( MaterialVideoMode_t& mode ) const = 0;
-
- // Sets the mode...
- virtual bool SetMode( void* hwnd, const MaterialSystem_Config_t &config ) = 0;
-
- virtual bool SupportsMSAAMode( int nMSAAMode ) = 0;
-
- // FIXME: REMOVE! Get video card identitier
- virtual const MaterialSystemHardwareIdentifier_t &GetVideoCardIdentifier( void ) const = 0;
-
- // Use this to spew information about the 3D layer
- virtual void SpewDriverInfo() const = 0;
-
- virtual void GetDXLevelDefaults(uint &max_dxlevel,uint &recommended_dxlevel) = 0;
-
- // Get the image format of the back buffer. . useful when creating render targets, etc.
- virtual void GetBackBufferDimensions( int &width, int &height) const = 0;
- virtual ImageFormat GetBackBufferFormat() const = 0;
-
- virtual bool SupportsHDRMode( HDRType_t nHDRModede ) = 0;
-
-
- // -----------------------------------------------------------
- // Window methods
- // -----------------------------------------------------------
-
- // Creates/ destroys a child window
- virtual bool AddView( void* hwnd ) = 0;
- virtual void RemoveView( void* hwnd ) = 0;
-
- // Sets the view
- virtual void SetView( void* hwnd ) = 0;
-
-
- // -----------------------------------------------------------
- // Control flow
- // -----------------------------------------------------------
-
- virtual void BeginFrame( float frameTime ) = 0;
- virtual void EndFrame( ) = 0;
- virtual void Flush( bool flushHardware = false ) = 0;
-
- /// FIXME: This stuff needs to be cleaned up and abstracted.
- // Stuff that gets exported to the launcher through the engine
- virtual void SwapBuffers( ) = 0;
-
- // Flushes managed textures from the texture cacher
- virtual void EvictManagedResources() = 0;
-
- virtual void ReleaseResources(void) = 0;
- virtual void ReacquireResources(void ) = 0;
-
-
- // -----------------------------------------------------------
- // Device loss/restore
- // -----------------------------------------------------------
-
- // Installs a function to be called when we need to release vertex buffers + textures
- virtual void AddReleaseFunc( MaterialBufferReleaseFunc_t func ) = 0;
- virtual void RemoveReleaseFunc( MaterialBufferReleaseFunc_t func ) = 0;
-
- // Installs a function to be called when we need to restore vertex buffers
- virtual void AddRestoreFunc( MaterialBufferRestoreFunc_t func ) = 0;
- virtual void RemoveRestoreFunc( MaterialBufferRestoreFunc_t func ) = 0;
-
- // Release temporary HW memory...
- virtual void ResetTempHWMemory( bool bExitingLevel = false ) = 0;
-
- // For dealing with device lost in cases where SwapBuffers isn't called all the time (Hammer)
- virtual void HandleDeviceLost() = 0;
-
-
- // -----------------------------------------------------------
- // Shaders
- // -----------------------------------------------------------
-
- // Used to iterate over all shaders for editing purposes
- // GetShaders returns the number of shaders it actually found
- virtual int ShaderCount() const = 0;
- virtual int GetShaders( int nFirstShader, int nMaxCount, IShader **ppShaderList ) const = 0;
-
- // FIXME: Is there a better way of doing this?
- // Returns shader flag names for editors to be able to edit them
- virtual int ShaderFlagCount() const = 0;
- virtual const char * ShaderFlagName( int nIndex ) const = 0;
-
- // Gets the actual shader fallback for a particular shader
- virtual void GetShaderFallback( const char *pShaderName, char *pFallbackShader, int nFallbackLength ) = 0;
-
-
- // -----------------------------------------------------------
- // Material proxies
- // -----------------------------------------------------------
-
- virtual IMaterialProxyFactory *GetMaterialProxyFactory() = 0;
-
- // Sets the material proxy factory. Calling this causes all materials to be uncached.
- virtual void SetMaterialProxyFactory( IMaterialProxyFactory* pFactory ) = 0;
-
-
- // -----------------------------------------------------------
- // Editor mode
- // -----------------------------------------------------------
-
- // Used to enable editor materials. Must be called before Init.
- virtual void EnableEditorMaterials() = 0;
-
-
- // -----------------------------------------------------------
- // Stub mode mode
- // -----------------------------------------------------------
-
- // Force it to ignore Draw calls.
- virtual void SetInStubMode( bool bInStubMode ) = 0;
-
-
- //---------------------------------------------------------
- // Debug support
- //---------------------------------------------------------
-
- virtual void DebugPrintUsedMaterials( const char *pSearchSubString, bool bVerbose ) = 0;
- virtual void DebugPrintUsedTextures( void ) = 0;
-
- virtual void ToggleSuppressMaterial( char const* pMaterialName ) = 0;
- virtual void ToggleDebugMaterial( char const* pMaterialName ) = 0;
-
-
- //---------------------------------------------------------
- // Misc features
- //---------------------------------------------------------
- //returns whether fast clipping is being used or not - needed to be exposed for better per-object clip behavior
- virtual bool UsingFastClipping( void ) = 0;
-
- virtual int StencilBufferBits( void ) = 0; //number of bits per pixel in the stencil buffer
-
-
- //---------------------------------------------------------
- // Material and texture management
- //---------------------------------------------------------
-
- // uncache all materials. . good for forcing reload of materials.
- virtual void UncacheAllMaterials( ) = 0;
-
- // Remove any materials from memory that aren't in use as determined
- // by the IMaterial's reference count.
- virtual void UncacheUnusedMaterials( bool bRecomputeStateSnapshots = false ) = 0;
-
- // Load any materials into memory that are to be used as determined
- // by the IMaterial's reference count.
- virtual void CacheUsedMaterials( ) = 0;
-
- // Force all textures to be reloaded from disk.
- virtual void ReloadTextures( ) = 0;
-
- // Reloads materials
- virtual void ReloadMaterials( const char *pSubString = NULL ) = 0;
-
- // Create a procedural material. The keyvalues looks like a VMT file
- virtual IMaterial * CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues ) = 0;
-
- // 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"
- //
- // Most of the texture groups for pTextureGroupName are listed in texture_group_names.h.
- //
- // Note: if the material can't be found, this returns a checkerboard material. You can
- // find out if you have that material by calling IMaterial::IsErrorMaterial().
- // (Or use the global IsErrorMaterial function, which checks if it's null too).
- virtual IMaterial * FindMaterial( char const* pMaterialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL ) = 0;
-
- // Query whether a material is loaded (eg, whether FindMaterial will be nonblocking)
- virtual bool IsMaterialLoaded( char const* pMaterialName ) = 0;
-
- //---------------------------------
- // 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 = 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 = 0;
-
- // This is the invalid material
- virtual MaterialHandle_t InvalidMaterial() const = 0;
-
- // Returns a particular material
- virtual IMaterial* GetMaterial( MaterialHandle_t h ) const = 0;
-
- // Get the total number of materials in the system. These aren't just the used
- // materials, but the complete collection.
- virtual int GetNumMaterials( ) const = 0;
-
- //---------------------------------
-
- virtual void SetAsyncTextureLoadCache( void* hFileCache ) = 0;
-
- virtual ITexture * FindTexture( char const* pTextureName, const char *pTextureGroupName, bool complain = true, int nAdditionalCreationFlags = 0 ) = 0;
-
- // Checks to see if a particular texture is loaded
- virtual bool IsTextureLoaded( char const* pTextureName ) const = 0;
-
- // Creates a procedural texture
- virtual ITexture * CreateProceduralTexture( const char *pTextureName,
- const char *pTextureGroupName,
- int w,
- int h,
- ImageFormat fmt,
- int nFlags ) = 0;
-
- //
- // Render targets
- //
- virtual void BeginRenderTargetAllocation() = 0;
- virtual void EndRenderTargetAllocation() = 0; // Simulate an Alt-Tab in here, which causes a release/restore of all resources
-
- // Creates a render target
- // If depth == true, a depth buffer is also allocated. If not, then
- // the screen's depth buffer is used.
- // Creates a texture for use as a render target
- 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 = MATERIAL_RT_DEPTH_SHARED ) = 0;
-
- 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 ) = 0;
-
- 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 = MATERIAL_RT_DEPTH_SHARED,
- bool bClampTexCoords = true,
- bool bAutoMipMap = false ) = 0;
-
- // Must be called between the above Begin-End calls!
- virtual 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 ) = 0;
-
- // -----------------------------------------------------------
- // Lightmaps
- // -----------------------------------------------------------
-
- // 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( ) = 0;
- virtual void EndLightmapAllocation( ) = 0;
-
- // returns the sorting id for this surface
- virtual int AllocateLightmap( int width, int height,
- int offsetIntoLightmapPage[2],
- IMaterial *pMaterial ) = 0;
- // returns the sorting id for this surface
- virtual int AllocateWhiteLightmap( IMaterial *pMaterial ) = 0;
-
- // 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 ) = 0;
-
- // fixme: could just be an array of ints for lightmapPageIDs since the material
- // for a surface is already known.
- virtual int GetNumSortIDs( ) = 0;
- virtual void GetSortInfo( MaterialSystem_SortInfo_t *sortInfoArray ) = 0;
-
- // Read the page size of an existing lightmap by sort id (returned from AllocateLightmap())
- virtual void GetLightmapPageSize( int lightmap, int *width, int *height ) const = 0;
-
- virtual void ResetMaterialLightmapPageInfo() = 0;
-
-
-
- virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil = false ) = 0;
-
- // -----------------------------------------------------------
- // X360 specifics
- // -----------------------------------------------------------
-
-#if defined( _X360 )
- virtual void ListUsedMaterials( void ) = 0;
- virtual HXUIFONT OpenTrueTypeFont( const char *pFontname, int tall, int style ) = 0;
- virtual void CloseTrueTypeFont( HXUIFONT hFont ) = 0;
- virtual bool GetTrueTypeFontMetrics( HXUIFONT hFont, XUIFontMetrics *pFontMetrics, XUICharMetrics charMetrics[256] ) = 0;
- // Render a sequence of characters and extract the data into a buffer
- // For each character, provide the width+height of the font texture subrect,
- // an offset to apply when rendering the glyph, and an offset into a buffer to receive the RGBA data
- virtual bool GetTrueTypeGlyphs( HXUIFONT hFont, int numChars, wchar_t *pWch, int *pOffsetX, int *pOffsetY, int *pWidth, int *pHeight, unsigned char *pRGBA, int *pRGBAOffset ) = 0;
- virtual void PersistDisplay() = 0;
- virtual void *GetD3DDevice() = 0;
- virtual bool OwnGPUResources( bool bEnable ) = 0;
-#endif
-
- // -----------------------------------------------------------
- // Access the render contexts
- // -----------------------------------------------------------
- virtual IMatRenderContext * GetRenderContext() = 0;
-
- virtual bool SupportsShadowDepthTextures( void ) = 0;
- virtual void BeginUpdateLightmaps( void ) = 0;
- virtual void EndUpdateLightmaps( void ) = 0;
-
- // -----------------------------------------------------------
- // Methods to force the material system into non-threaded, non-queued mode
- // -----------------------------------------------------------
- virtual MaterialLock_t Lock() = 0;
- virtual void Unlock( MaterialLock_t ) = 0;
-
- // Vendor-dependent shadow depth texture format
- virtual ImageFormat GetShadowDepthTextureFormat() = 0;
-
- virtual bool SupportsFetch4( void ) = 0;
-
- // Create a custom render context. Cannot be used to create MATERIAL_HARDWARE_CONTEXT
- virtual IMatRenderContext *CreateRenderContext( MaterialContextType_t type ) = 0;
-
- // Set a specified render context to be the global context for the thread. Returns the prior context.
- virtual IMatRenderContext *SetRenderContext( IMatRenderContext * ) = 0;
-
- virtual bool SupportsCSAAMode( int nNumSamples, int nQualityLevel ) = 0;
-
- virtual void RemoveModeChangeCallBack( ModeChangeCallbackFunc_t func ) = 0;
-
- // Finds or create a procedural material.
- virtual IMaterial * FindProceduralMaterial( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ) = 0;
-
- virtual ImageFormat GetNullTextureFormat() = 0;
-
- virtual void AddTextureAlias( const char *pAlias, const char *pRealName ) = 0;
- virtual void RemoveTextureAlias( const char *pAlias ) = 0;
-
- // returns a lightmap page ID for this allocation, -1 if none available
- // frameID is a number that should be changed every frame to prevent locking any textures that are
- // being used to draw in the previous frame
- virtual int AllocateDynamicLightmap( int lightmapSize[2], int *pOutOffsetIntoPage, int frameID ) = 0;
-
- virtual void SetExcludedTextures( const char *pScriptName ) = 0;
- virtual void UpdateExcludedTextures( void ) = 0;
-
- virtual bool IsInFrame( ) const = 0;
-
- virtual void CompactMemory() = 0;
-
- // 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 ) = 0;
- virtual bool AllowThreading( bool bAllow, int nServiceThread ) = 0;
-
- // Extended version of FindMaterial().
- // Contains context in so it can make decisions (i.e. if it's a model, ignore certain cheat parameters)
- virtual IMaterial * FindMaterialEx( char const* pMaterialName, const char *pTextureGroupName, int nContext, bool complain = true, const char *pComplainPrefix = NULL ) = 0;
-
-#ifdef DX_TO_GL_ABSTRACTION
- virtual void DoStartupShaderPreloading( void ) = 0;
-#endif
-};
-
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-abstract_class IMatRenderContext : public IRefCounted
-{
-public:
- virtual void BeginRender() = 0;
- virtual void EndRender() = 0;
-
- virtual void Flush( bool flushHardware = false ) = 0;
-
- virtual void BindLocalCubemap( ITexture *pTexture ) = 0;
-
- // pass in an ITexture (that is build with "rendertarget" "1") or
- // pass in NULL for the regular backbuffer.
- virtual void SetRenderTarget( ITexture *pTexture ) = 0;
- virtual ITexture * GetRenderTarget( void ) = 0;
-
- virtual void GetRenderTargetDimensions( int &width, int &height) const = 0;
-
- // Bind a material is current for rendering.
- virtual void Bind( IMaterial *material, void *proxyData = 0 ) = 0;
- // Bind a lightmap page current for rendering. You only have to
- // do this for materials that require lightmaps.
- virtual void BindLightmapPage( int lightmapPageID ) = 0;
-
- // inputs are between 0 and 1
- virtual void DepthRange( float zNear, float zFar ) = 0;
-
- virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil = false ) = 0;
-
- // read to a unsigned char rgb image.
- virtual void ReadPixels( int x, int y, int width, int height, unsigned char *data, ImageFormat dstFormat ) = 0;
-
- // Sets lighting
- virtual void SetAmbientLight( float r, float g, float b ) = 0;
- virtual void SetLight( int lightNum, const LightDesc_t& desc ) = 0;
-
- // The faces of the cube are specified in the same order as cubemap textures
- virtual void SetAmbientLightCube( Vector4D cube[6] ) = 0;
-
- // Blit the backbuffer to the framebuffer texture
- virtual void CopyRenderTargetToTexture( ITexture *pTexture ) = 0;
-
- // Set the current texture that is a copy of the framebuffer.
- virtual void SetFrameBufferCopyTexture( ITexture *pTexture, int textureIndex = 0 ) = 0;
- virtual ITexture *GetFrameBufferCopyTexture( int textureIndex ) = 0;
-
- //
- // end vertex array api
- //
-
- // matrix api
- virtual void MatrixMode( MaterialMatrixMode_t matrixMode ) = 0;
- virtual void PushMatrix( void ) = 0;
- virtual void PopMatrix( void ) = 0;
- virtual void LoadMatrix( VMatrix const& matrix ) = 0;
- virtual void LoadMatrix( matrix3x4_t const& matrix ) = 0;
- virtual void MultMatrix( VMatrix const& matrix ) = 0;
- virtual void MultMatrix( matrix3x4_t const& matrix ) = 0;
- virtual void MultMatrixLocal( VMatrix const& matrix ) = 0;
- virtual void MultMatrixLocal( matrix3x4_t const& matrix ) = 0;
- virtual void GetMatrix( MaterialMatrixMode_t matrixMode, VMatrix *matrix ) = 0;
- virtual void GetMatrix( MaterialMatrixMode_t matrixMode, matrix3x4_t *matrix ) = 0;
- virtual void LoadIdentity( void ) = 0;
- virtual void Ortho( double left, double top, double right, double bottom, double zNear, double zFar ) = 0;
- virtual void PerspectiveX( double fovx, double aspect, double zNear, double zFar ) = 0;
- virtual void PickMatrix( int x, int y, int width, int height ) = 0;
- virtual void Rotate( float angle, float x, float y, float z ) = 0;
- virtual void Translate( float x, float y, float z ) = 0;
- virtual void Scale( float x, float y, float z ) = 0;
- // end matrix api
-
- // Sets/gets the viewport
- virtual void Viewport( int x, int y, int width, int height ) = 0;
- virtual void GetViewport( int& x, int& y, int& width, int& height ) const = 0;
-
- // The cull mode
- virtual void CullMode( MaterialCullMode_t cullMode ) = 0;
-
- // end matrix api
-
- // This could easily be extended to a general user clip plane
- virtual void SetHeightClipMode( MaterialHeightClipMode_t nHeightClipMode ) = 0;
- // garymcthack : fog z is always used for heightclipz for now.
- virtual void SetHeightClipZ( float z ) = 0;
-
- // Fog methods...
- virtual void FogMode( MaterialFogMode_t fogMode ) = 0;
- virtual void FogStart( float fStart ) = 0;
- virtual void FogEnd( float fEnd ) = 0;
- virtual void SetFogZ( float fogZ ) = 0;
- virtual MaterialFogMode_t GetFogMode( void ) = 0;
-
- virtual void FogColor3f( float r, float g, float b ) = 0;
- virtual void FogColor3fv( float const* rgb ) = 0;
- virtual void FogColor3ub( unsigned char r, unsigned char g, unsigned char b ) = 0;
- virtual void FogColor3ubv( unsigned char const* rgb ) = 0;
-
- virtual void GetFogColor( unsigned char *rgb ) = 0;
-
- // Sets the number of bones for skinning
- virtual void SetNumBoneWeights( int numBones ) = 0;
-
- // Creates/destroys Mesh
- virtual IMesh* CreateStaticMesh( VertexFormat_t fmt, const char *pTextureBudgetGroup, IMaterial * pMaterial = NULL ) = 0;
- virtual void DestroyStaticMesh( IMesh* mesh ) = 0;
-
- // 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 buffered = true,
- IMesh* pVertexOverride = 0,
- IMesh* pIndexOverride = 0,
- IMaterial *pAutoBind = 0 ) = 0;
-
- // ------------ New Vertex/Index Buffer interface ----------------------------
- // Do we need support for bForceTempMesh and bSoftwareVertexShader?
- // I don't think we use bSoftwareVertexShader anymore. .need to look into bForceTempMesh.
- virtual IVertexBuffer *CreateStaticVertexBuffer( VertexFormat_t fmt, int nVertexCount, const char *pTextureBudgetGroup ) = 0;
- virtual IIndexBuffer *CreateStaticIndexBuffer( MaterialIndexFormat_t fmt, int nIndexCount, const char *pTextureBudgetGroup ) = 0;
- virtual void DestroyVertexBuffer( IVertexBuffer * ) = 0;
- virtual void DestroyIndexBuffer( IIndexBuffer * ) = 0;
- // 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 ) = 0;
- virtual IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true ) = 0;
- virtual void BindVertexBuffer( int streamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, int nFirstVertex, int nVertexCount, VertexFormat_t fmt, int nRepetitions = 1 ) = 0;
- virtual void BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes ) = 0;
- virtual void Draw( MaterialPrimitiveType_t primitiveType, int firstIndex, int numIndices ) = 0;
- // ------------ End ----------------------------
-
- // Selection mode methods
- virtual int SelectionMode( bool selectionMode ) = 0;
- virtual void SelectionBuffer( unsigned int* pBuffer, int size ) = 0;
- virtual void ClearSelectionNames( ) = 0;
- virtual void LoadSelectionName( int name ) = 0;
- virtual void PushSelectionName( int name ) = 0;
- virtual void PopSelectionName() = 0;
-
- // Sets the Clear Color for ClearBuffer....
- virtual void ClearColor3ub( unsigned char r, unsigned char g, unsigned char b ) = 0;
- virtual void ClearColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) = 0;
-
- // Allows us to override the depth buffer setting of a material
- virtual void OverrideDepthEnable( bool bEnable, bool bDepthEnable ) = 0;
-
- // FIXME: This is a hack required for NVidia/XBox, can they fix in drivers?
- virtual void DrawScreenSpaceQuad( IMaterial* pMaterial ) = 0;
-
- // For debugging and building recording files. This will stuff a token into the recording file,
- // then someone doing a playback can watch for the token.
- virtual void SyncToken( const char *pToken ) = 0;
-
- // FIXME: REMOVE THIS FUNCTION!
- // The only reason why it's not gone is because we're a week from ship when I found the bug in it
- // and everything's tuned to use it.
- // It's returning values which are 2x too big (it's returning sphere diameter x2)
- // Use ComputePixelDiameterOfSphere below in all new code instead.
- virtual float ComputePixelWidthOfSphere( const Vector& origin, float flRadius ) = 0;
-
- //
- // Occlusion query support
- //
-
- // Allocate and delete query objects.
- virtual OcclusionQueryObjectHandle_t CreateOcclusionQueryObject( void ) = 0;
- virtual void DestroyOcclusionQueryObject( OcclusionQueryObjectHandle_t ) = 0;
-
- // Bracket drawing with begin and end so that we can get counts next frame.
- virtual void BeginOcclusionQueryDrawing( OcclusionQueryObjectHandle_t ) = 0;
- virtual void EndOcclusionQueryDrawing( OcclusionQueryObjectHandle_t ) = 0;
-
- // Get the number of pixels rendered between begin and end on an earlier frame.
- // Calling this in the same frame is a huge perf hit!
- virtual int OcclusionQuery_GetNumPixelsRendered( OcclusionQueryObjectHandle_t ) = 0;
-
- virtual void SetFlashlightMode( bool bEnable ) = 0;
-
- virtual void SetFlashlightState( const FlashlightState_t &state, const VMatrix &worldToTexture ) = 0;
-
- // Gets the current height clip mode
- virtual MaterialHeightClipMode_t GetHeightClipMode( ) = 0;
-
- // This returns the diameter of the sphere in pixels based on
- // the current model, view, + projection matrices and viewport.
- virtual float ComputePixelDiameterOfSphere( const Vector& vecAbsOrigin, float flRadius ) = 0;
-
- // By default, the material system applies the VIEW and PROJECTION matrices to the user clip
- // planes (which are specified in world space) to generate projection-space user clip planes
- // Occasionally (for the particle system in hl2, for example), we want to override that
- // behavior and explictly specify a ViewProj transform for user clip planes
- virtual void EnableUserClipTransformOverride( bool bEnable ) = 0;
- virtual void UserClipTransform( const VMatrix &worldToView ) = 0;
-
- virtual bool GetFlashlightMode() const = 0;
-
- // Used to make the handle think it's never had a successful query before
- virtual void ResetOcclusionQueryObject( OcclusionQueryObjectHandle_t ) = 0;
-
- // FIXME: Remove
- virtual void Unused3() {}
-
- // Creates/destroys morph data associated w/ a particular material
- virtual IMorph *CreateMorph( MorphFormat_t format, const char *pDebugName ) = 0;
- virtual void DestroyMorph( IMorph *pMorph ) = 0;
-
- // Binds the morph data for use in rendering
- virtual void BindMorph( IMorph *pMorph ) = 0;
-
- // Sets flexweights for rendering
- virtual void SetFlexWeights( int nFirstWeight, int nCount, const MorphWeight_t* pWeights ) = 0;
-
- // FIXME: Remove
- virtual void Unused4() {};
- virtual void Unused5() {};
- virtual void Unused6() {};
- virtual void Unused7() {};
- virtual void Unused8() {};
-
- // Read w/ stretch to a host-memory buffer
- virtual void ReadPixelsAndStretch( Rect_t *pSrcRect, Rect_t *pDstRect, unsigned char *pBuffer, ImageFormat dstFormat, int nDstStride ) = 0;
-
- // Gets the window size
- virtual void GetWindowSize( int &width, int &height ) const = 0;
-
- // This function performs a texture map from one texture map to the render destination, doing
- // all the necessary pixel/texel coordinate fix ups. fractional values can be used for the
- // src_texture coordinates to get linear sampling - integer values should produce 1:1 mappings
- // for non-scaled operations.
- virtual void DrawScreenSpaceRectangle(
- IMaterial *pMaterial,
- int destx, int desty,
- int width, int height,
- float src_texture_x0, float src_texture_y0, // which texel you want to appear at
- // destx/y
- float src_texture_x1, float src_texture_y1, // which texel you want to appear at
- // destx+width-1, desty+height-1
- int src_texture_width, int src_texture_height, // needed for fixup
- void *pClientRenderable = NULL,
- int nXDice = 1,
- int nYDice = 1 )=0;
-
- virtual void LoadBoneMatrix( int boneIndex, const matrix3x4_t& matrix ) = 0;
-
- // This version will push the current rendertarget + current viewport onto the stack
- virtual void PushRenderTargetAndViewport( ) = 0;
-
- // This version will push a new rendertarget + a maximal viewport for that rendertarget onto the stack
- virtual void PushRenderTargetAndViewport( ITexture *pTexture ) = 0;
-
- // This version will push a new rendertarget + a specified viewport onto the stack
- virtual void PushRenderTargetAndViewport( ITexture *pTexture, int nViewX, int nViewY, int nViewW, int nViewH ) = 0;
-
- // This version will push a new rendertarget + a specified viewport onto the stack
- virtual void PushRenderTargetAndViewport( ITexture *pTexture, ITexture *pDepthTexture, int nViewX, int nViewY, int nViewW, int nViewH ) = 0;
-
- // This will pop a rendertarget + viewport
- virtual void PopRenderTargetAndViewport( void ) = 0;
-
- // Binds a particular texture as the current lightmap
- virtual void BindLightmapTexture( ITexture *pLightmapTexture ) = 0;
-
- // 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 ) = 0;
- virtual void CopyTextureToRenderTargetEx( int nRenderTargetID, ITexture *pTexture, Rect_t *pSrcRect, Rect_t *pDstRect = NULL ) = 0;
-
- // Special off-center perspective matrix for DoF, MSAA jitter and poster rendering
- virtual void PerspectiveOffCenterX( double fovx, double aspect, double zNear, double zFar, double bottom, double top, double left, double right ) = 0;
-
- // Rendering parameters control special drawing modes withing the material system, shader
- // system, shaders, and engine. renderparm.h has their definitions.
- virtual void SetFloatRenderingParameter(int parm_number, float value) = 0;
- virtual void SetIntRenderingParameter(int parm_number, int value) = 0;
- virtual void SetVectorRenderingParameter(int parm_number, Vector const &value) = 0;
-
- // stencil buffer operations.
- virtual void SetStencilEnable(bool onoff) = 0;
- virtual void SetStencilFailOperation(StencilOperation_t op) = 0;
- virtual void SetStencilZFailOperation(StencilOperation_t op) = 0;
- virtual void SetStencilPassOperation(StencilOperation_t op) = 0;
- virtual void SetStencilCompareFunction(StencilComparisonFunction_t cmpfn) = 0;
- virtual void SetStencilReferenceValue(int ref) = 0;
- virtual void SetStencilTestMask(uint32 msk) = 0;
- virtual void SetStencilWriteMask(uint32 msk) = 0;
- virtual void ClearStencilBufferRectangle(int xmin, int ymin, int xmax, int ymax,int value) =0;
-
- virtual void SetRenderTargetEx( int nRenderTargetID, ITexture *pTexture ) = 0;
-
- // rendering clip planes, beware that only the most recently pushed plane will actually be used in a sizeable chunk of hardware configurations
- // and that changes to the clip planes mid-frame while UsingFastClipping() is true will result unresolvable depth inconsistencies
- virtual void PushCustomClipPlane( const float *pPlane ) = 0;
- virtual void PopCustomClipPlane( void ) = 0;
-
- // Returns the number of vertices + indices we can render using the dynamic mesh
- // Passing true in the second parameter will return the max # of vertices + indices
- // we can use before a flush is provoked and may return different values
- // if called multiple times in succession.
- // Passing false into the second parameter will return
- // the maximum possible vertices + indices that can be rendered in a single batch
- virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ) = 0;
-
- // Returns the max possible vertices + indices to render in a single draw call
- virtual int GetMaxVerticesToRender( IMaterial *pMaterial ) = 0;
- virtual int GetMaxIndicesToRender( ) = 0;
- virtual void DisableAllLocalLights() = 0;
- virtual int CompareMaterialCombos( IMaterial *pMaterial1, IMaterial *pMaterial2, int lightMapID1, int lightMapID2 ) = 0;
-
- virtual IMesh *GetFlexMesh() = 0;
-
- virtual void SetFlashlightStateEx( const FlashlightState_t &state, const VMatrix &worldToTexture, ITexture *pFlashlightDepthTexture ) = 0;
-
- // Returns the currently bound local cubemap
- virtual ITexture *GetLocalCubemap( ) = 0;
-
- // This is a version of clear buffers which will only clear the buffer at pixels which pass the stencil test
- virtual void ClearBuffersObeyStencil( bool bClearColor, bool bClearDepth ) = 0;
-
- //enables/disables all entered clipping planes, returns the input from the last time it was called.
- virtual bool EnableClipping( bool bEnable ) = 0;
-
- //get fog distances entered with FogStart(), FogEnd(), and SetFogZ()
- virtual void GetFogDistances( float *fStart, float *fEnd, float *fFogZ ) = 0;
-
- // Hooks for firing PIX events from outside the Material System...
- virtual void BeginPIXEvent( unsigned long color, const char *szName ) = 0;
- virtual void EndPIXEvent() = 0;
- virtual void SetPIXMarker( unsigned long color, const char *szName ) = 0;
-
- // Batch API
- // from changelist 166623:
- // - replaced obtuse material system batch usage with an explicit and easier to thread API
- virtual void BeginBatch( IMesh* pIndices ) = 0;
- virtual void BindBatch( IMesh* pVertices, IMaterial *pAutoBind = NULL ) = 0;
- virtual void DrawBatch(int firstIndex, int numIndices ) = 0;
- virtual void EndBatch() = 0;
-
- // Raw access to the call queue, which can be NULL if not in a queued mode
- virtual ICallQueue *GetCallQueue() = 0;
-
- // Returns the world-space camera position
- virtual void GetWorldSpaceCameraPosition( Vector *pCameraPos ) = 0;
- virtual void GetWorldSpaceCameraVectors( Vector *pVecForward, Vector *pVecRight, Vector *pVecUp ) = 0;
-
- // Tone mapping
- virtual void ResetToneMappingScale( float monoscale) = 0; // set scale to monoscale instantly with no chasing
- virtual void SetGoalToneMappingScale( float monoscale) = 0; // set scale to monoscale instantly with no chasing
-
- // call TurnOnToneMapping before drawing the 3d scene to get the proper interpolated brightness
- // value set.
- virtual void TurnOnToneMapping() = 0;
-
- // Set a linear vector color scale for all 3D rendering.
- // A value of [1.0f, 1.0f, 1.0f] should match non-tone-mapped rendering.
- virtual void SetToneMappingScaleLinear( const Vector &scale ) = 0;
-
- virtual Vector GetToneMappingScaleLinear( void ) = 0;
- virtual void SetShadowDepthBiasFactors( float fSlopeScaleDepthBias, float fDepthBias ) = 0;
-
- // Apply stencil operations to every pixel on the screen without disturbing depth or color buffers
- virtual void PerformFullScreenStencilOperation( void ) = 0;
-
- // Sets lighting origin for the current model (needed to convert directional lights to points)
- virtual void SetLightingOrigin( Vector vLightingOrigin ) = 0;
-
- // Set scissor rect for rendering
- virtual void SetScissorRect( const int nLeft, const int nTop, const int nRight, const int nBottom, const bool bEnableScissor ) = 0;
-
- // Methods used to build the morph accumulator that is read from when HW morph<ing is enabled.
- virtual void BeginMorphAccumulation() = 0;
- virtual void EndMorphAccumulation() = 0;
- virtual void AccumulateMorph( IMorph* pMorph, int nMorphCount, const MorphWeight_t* pWeights ) = 0;
-
- virtual void PushDeformation( DeformationBase_t const *Deformation ) = 0;
- virtual void PopDeformation( ) = 0;
- virtual int GetNumActiveDeformations() const = 0;
-
- virtual bool GetMorphAccumulatorTexCoord( Vector2D *pTexCoord, IMorph *pMorph, int nVertex ) = 0;
-
- // Version of get dynamic mesh that specifies a specific vertex format
- virtual IMesh* GetDynamicMeshEx( VertexFormat_t vertexFormat, bool bBuffered = true,
- IMesh* pVertexOverride = 0, IMesh* pIndexOverride = 0, IMaterial *pAutoBind = 0 ) = 0;
-
- virtual void FogMaxDensity( float flMaxDensity ) = 0;
-
-#if defined( _X360 )
- //Seems best to expose GPR allocation to scene rendering code. 128 total to split between vertex/pixel shaders (pixel will be set to 128 - vertex). Minimum value of 16. More GPR's = more threads.
- virtual void PushVertexShaderGPRAllocation( int iVertexShaderCount = 64 ) = 0;
- virtual void PopVertexShaderGPRAllocation( void ) = 0;
-#endif
-
- virtual IMaterial *GetCurrentMaterial() = 0;
- virtual int GetCurrentNumBones() const = 0;
- virtual void *GetCurrentProxy() = 0;
-
- // Color correction related methods..
- // Client cannot call IColorCorrectionSystem directly because it is not thread-safe
- // FIXME: Make IColorCorrectionSystem threadsafe?
- virtual void EnableColorCorrection( bool bEnable ) = 0;
- virtual ColorCorrectionHandle_t AddLookup( const char *pName ) = 0;
- virtual bool RemoveLookup( ColorCorrectionHandle_t handle ) = 0;
- virtual void LockLookup( ColorCorrectionHandle_t handle ) = 0;
- virtual void LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ) = 0;
- virtual void UnlockLookup( ColorCorrectionHandle_t handle ) = 0;
- virtual void SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ) = 0;
- virtual void ResetLookupWeights( ) = 0;
- virtual void SetResetable( ColorCorrectionHandle_t handle, bool bResetable ) = 0;
-
- //There are some cases where it's simply not reasonable to update the full screen depth texture (mostly on PC).
- //Use this to mark it as invalid and use a dummy texture for depth reads.
- virtual void SetFullScreenDepthTextureValidityFlag( bool bIsValid ) = 0;
-
- // 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 ) = 0;
- virtual void SetNonInteractiveTempFullscreenBuffer( ITexture *pTexture, MaterialNonInteractiveMode_t mode ) = 0;
- virtual void EnableNonInteractiveMode( MaterialNonInteractiveMode_t mode ) = 0;
- virtual void RefreshFrontBufferNonInteractive() = 0;
- // Allocates temp render data. Renderdata goes out of scope at frame end in multicore
- // Renderdata goes out of scope after refcount goes to zero in singlecore.
- // Locking/unlocking increases + decreases refcount
- virtual void * LockRenderData( int nSizeInBytes ) = 0;
- virtual void UnlockRenderData( void *pData ) = 0;
-
- // Typed version. If specified, pSrcData is copied into the locked memory.
- template< class E > E* LockRenderDataTyped( int nCount, const E* pSrcData = NULL );
-
- // Temp render data gets immediately freed after it's all unlocked in single core.
- // This prevents it from being freed
- virtual void AddRefRenderData() = 0;
- virtual void ReleaseRenderData() = 0;
-
- // Returns whether a pointer is render data. NOTE: passing NULL returns true
- virtual bool IsRenderData( const void *pData ) const = 0;
- virtual void PrintfVA( char *fmt, va_list vargs ) = 0;
- virtual void Printf( PRINTF_FORMAT_STRING char *fmt, ... ) = 0;
- virtual float Knob( char *knobname, float *setvalue = NULL ) = 0;
- // Allows us to override the alpha write setting of a material
- virtual void OverrideAlphaWriteEnable( bool bEnable, bool bAlphaWriteEnable ) = 0;
- virtual void OverrideColorWriteEnable( bool bOverrideEnable, bool bColorWriteEnable ) = 0;
-
- virtual void ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth ) = 0;
-};
-
-template< class E > inline E* IMatRenderContext::LockRenderDataTyped( int nCount, const E* pSrcData )
-{
- int nSizeInBytes = nCount * sizeof(E);
- E *pDstData = (E*)LockRenderData( nSizeInBytes );
- if ( pSrcData && pDstData )
- {
- memcpy( pDstData, pSrcData, nSizeInBytes );
- }
- return pDstData;
-}
-
-
-//-----------------------------------------------------------------------------
-// Utility class for addreffing/releasing render data (prevents freeing on single core)
-//-----------------------------------------------------------------------------
-class CMatRenderDataReference
-{
-public:
- CMatRenderDataReference();
- CMatRenderDataReference( IMatRenderContext* pRenderContext );
- ~CMatRenderDataReference();
- void Lock( IMatRenderContext *pRenderContext );
- void Release();
-
-private:
- IMatRenderContext *m_pRenderContext;
-};
-
-
-inline CMatRenderDataReference::CMatRenderDataReference()
-{
- m_pRenderContext = NULL;
-}
-
-inline CMatRenderDataReference::CMatRenderDataReference( IMatRenderContext* pRenderContext )
-{
- m_pRenderContext = NULL;
- Lock( pRenderContext );
-}
-
-inline CMatRenderDataReference::~CMatRenderDataReference()
-{
- Release();
-}
-
-inline void CMatRenderDataReference::Lock( IMatRenderContext* pRenderContext )
-{
- if ( !m_pRenderContext )
- {
- m_pRenderContext = pRenderContext;
- m_pRenderContext->AddRefRenderData( );
- }
-}
-
-inline void CMatRenderDataReference::Release()
-{
- if ( m_pRenderContext )
- {
- m_pRenderContext->ReleaseRenderData( );
- m_pRenderContext = NULL;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Utility class for locking/unlocking render data
-//-----------------------------------------------------------------------------
-template< typename E >
-class CMatRenderData
-{
-public:
- CMatRenderData( IMatRenderContext* pRenderContext );
- CMatRenderData( IMatRenderContext* pRenderContext, int nCount, const E *pSrcData = NULL );
- ~CMatRenderData();
- E* Lock( int nCount, const E* pSrcData = NULL );
- void Release();
- bool IsValid() const;
- const E* Base() const;
- E* Base();
- const E& operator[]( int i ) const;
- E& operator[]( int i );
-
-private:
- IMatRenderContext* m_pRenderContext;
- E *m_pRenderData;
- int m_nCount;
- bool m_bNeedsUnlock;
-};
-
-template< typename E >
-inline CMatRenderData<E>::CMatRenderData( IMatRenderContext* pRenderContext )
-{
- m_pRenderContext = pRenderContext;
- m_nCount = 0;
- m_pRenderData = 0;
- m_bNeedsUnlock = false;
-}
-
-template< typename E >
-inline CMatRenderData<E>::CMatRenderData( IMatRenderContext* pRenderContext, int nCount, const E* pSrcData )
-{
- m_pRenderContext = pRenderContext;
- m_nCount = 0;
- m_pRenderData = 0;
- m_bNeedsUnlock = false;
- Lock( nCount, pSrcData );
-}
-
-template< typename E >
-inline CMatRenderData<E>::~CMatRenderData()
-{
- Release();
-}
-
-template< typename E >
-inline bool CMatRenderData<E>::IsValid() const
-{
- return m_pRenderData != NULL;
-}
-
-template< typename E >
-inline E* CMatRenderData<E>::Lock( int nCount, const E* pSrcData )
-{
- m_nCount = nCount;
- if ( pSrcData && m_pRenderContext->IsRenderData( pSrcData ) )
- {
- // Yes, we're const-casting away, but that should be ok since
- // the src data is render data
- m_pRenderData = const_cast<E*>( pSrcData );
- m_pRenderContext->AddRefRenderData();
- m_bNeedsUnlock = false;
- return m_pRenderData;
- }
- m_pRenderData = m_pRenderContext->LockRenderDataTyped<E>( nCount, pSrcData );
- m_bNeedsUnlock = true;
- return m_pRenderData;
-}
-
-template< typename E >
-inline void CMatRenderData<E>::Release()
-{
- if ( m_pRenderContext && m_pRenderData )
- {
- if ( m_bNeedsUnlock )
- {
- m_pRenderContext->UnlockRenderData( m_pRenderData );
- }
- else
- {
- m_pRenderContext->ReleaseRenderData();
- }
- }
- m_pRenderData = NULL;
- m_nCount = 0;
- m_bNeedsUnlock = false;
-}
-
-template< typename E >
-inline E* CMatRenderData<E>::Base()
-{
- return m_pRenderData;
-}
-
-template< typename E >
-inline const E* CMatRenderData<E>::Base() const
-{
- return m_pRenderData;
-}
-
-template< typename E >
-inline E& CMatRenderData<E>::operator[]( int i )
-{
- Assert( ( i >= 0 ) && ( i < m_nCount ) );
- return m_pRenderData[i];
-}
-
-template< typename E >
-inline const E& CMatRenderData<E>::operator[]( int i ) const
-{
- Assert( ( i >= 0 ) && ( i < m_nCount ) );
- return m_pRenderData[i];
-}
-
-
-//-----------------------------------------------------------------------------
-
-class CMatRenderContextPtr : public CRefPtr<IMatRenderContext>
-{
- typedef CRefPtr<IMatRenderContext> BaseClass;
-public:
- CMatRenderContextPtr() {}
- CMatRenderContextPtr( IMatRenderContext *pInit ) : BaseClass( pInit ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->BeginRender(); }
- CMatRenderContextPtr( IMaterialSystem *pFrom ) : BaseClass( pFrom->GetRenderContext() ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->BeginRender(); }
- ~CMatRenderContextPtr() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); }
-
- IMatRenderContext *operator=( IMatRenderContext *p ) { if ( p ) p->BeginRender(); return BaseClass::operator=( p ); }
-
- void SafeRelease() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); BaseClass::SafeRelease(); }
- void AssignAddRef( IMatRenderContext *pFrom ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); BaseClass::AssignAddRef( pFrom ); BaseClass::m_pObject->BeginRender(); }
-
- void GetFrom( IMaterialSystem *pFrom ) { AssignAddRef( pFrom->GetRenderContext() ); }
-
-
-private:
- CMatRenderContextPtr( const CMatRenderContextPtr &from );
- void operator=( const CMatRenderContextPtr &from );
-
-};
-
-//-----------------------------------------------------------------------------
-// Helper class for begin/end of pix event via constructor/destructor
-//-----------------------------------------------------------------------------
-#define PIX_VALVE_ORANGE 0xFFF5940F
-
-class PIXEvent
-{
-public:
- PIXEvent( IMatRenderContext *pRenderContext, const char *szName, unsigned long color = PIX_VALVE_ORANGE )
- {
- m_pRenderContext = pRenderContext;
- Assert( m_pRenderContext );
- Assert( szName );
- m_pRenderContext->BeginPIXEvent( color, szName );
- }
- ~PIXEvent()
- {
- m_pRenderContext->EndPIXEvent();
- }
-private:
- IMatRenderContext *m_pRenderContext;
-};
-
-
-// Also be sure to enable PIX_INSTRUMENTATION in shaderdevicedx8.h
-//#define PIX_ENABLE 1 // set this to 1 and build engine/studiorender to enable pix events in the engine
-
-#if PIX_ENABLE
-# define PIXEVENT PIXEvent _pixEvent
-#else
-# define PIXEVENT
-#endif
-
-//-----------------------------------------------------------------------------
-
-#ifdef MATERIAL_SYSTEM_DEBUG_CALL_QUEUE
-#include "tier1/callqueue.h"
-#include "tier1/fmtstr.h"
-static void DoMatSysQueueMark( IMaterialSystem *pMaterialSystem, const char *psz )
-{
- CMatRenderContextPtr pRenderContext( pMaterialSystem );
- if ( pRenderContext->GetCallQueue() )
- pRenderContext->GetCallQueue()->QueueCall( Plat_DebugString, CUtlEnvelope<const char *>( psz ) );
-}
-
-#define MatSysQueueMark( pMaterialSystem, ...) DoMatSysQueueMark( pMaterialSystem, CFmtStr( __VA_ARGS__ ) )
-#else
-#define MatSysQueueMark( msg, ...) ((void)0)
-#endif
-
-//-----------------------------------------------------------------------------
-
-extern IMaterialSystem *materials;
-extern IMaterialSystem *g_pMaterialSystem;
-
-#endif // IMATERIALSYSTEM_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef IMATERIALSYSTEM_H +#define IMATERIALSYSTEM_H + +#ifdef _WIN32 +#pragma once +#endif + +#define OVERBRIGHT 2.0f +#define OO_OVERBRIGHT ( 1.0f / 2.0f ) +#define GAMMA 2.2f +#define TEXGAMMA 2.2f + +#include "tier1/interface.h" +#include "tier1/refcount.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "mathlib/vmatrix.h" +#include "appframework/IAppSystem.h" +#include "bitmap/imageformat.h" +#include "texture_group_names.h" +#include "vtf/vtf.h" +#include "materialsystem/deformations.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "materialsystem/IColorCorrection.h" + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterial; +class IMesh; +class IVertexBuffer; +class IIndexBuffer; +struct MaterialSystem_Config_t; +class VMatrix; +struct matrix3x4_t; +class ITexture; +struct MaterialSystemHardwareIdentifier_t; +class KeyValues; +class IShader; +class IVertexTexture; +class IMorph; +class IMatRenderContext; +class ICallQueue; +struct MorphWeight_t; +class IFileList; + + +//----------------------------------------------------------------------------- +// The vertex format type +//----------------------------------------------------------------------------- +typedef uint64 VertexFormat_t; + +//----------------------------------------------------------------------------- +// important enumeration +//----------------------------------------------------------------------------- + +// NOTE NOTE NOTE!!!! If you up this, grep for "NEW_INTERFACE" to see if there is anything +// waiting to be enabled during an interface revision. +#define MATERIAL_SYSTEM_INTERFACE_VERSION "VMaterialSystem080" + +#ifdef POSIX +#define ABSOLUTE_MINIMUM_DXLEVEL 90 +#else +#define ABSOLUTE_MINIMUM_DXLEVEL 80 +#endif + +enum ShaderParamType_t +{ + SHADER_PARAM_TYPE_TEXTURE, + SHADER_PARAM_TYPE_INTEGER, + SHADER_PARAM_TYPE_COLOR, + SHADER_PARAM_TYPE_VEC2, + SHADER_PARAM_TYPE_VEC3, + SHADER_PARAM_TYPE_VEC4, + SHADER_PARAM_TYPE_ENVMAP, // obsolete + SHADER_PARAM_TYPE_FLOAT, + SHADER_PARAM_TYPE_BOOL, + SHADER_PARAM_TYPE_FOURCC, + SHADER_PARAM_TYPE_MATRIX, + SHADER_PARAM_TYPE_MATERIAL, + SHADER_PARAM_TYPE_STRING, +}; + +enum MaterialMatrixMode_t +{ + MATERIAL_VIEW = 0, + MATERIAL_PROJECTION, + + // Texture matrices + MATERIAL_TEXTURE0, + MATERIAL_TEXTURE1, + MATERIAL_TEXTURE2, + MATERIAL_TEXTURE3, + MATERIAL_TEXTURE4, + MATERIAL_TEXTURE5, + MATERIAL_TEXTURE6, + MATERIAL_TEXTURE7, + + MATERIAL_MODEL, + + // Total number of matrices + NUM_MATRIX_MODES = MATERIAL_MODEL+1, + + // Number of texture transforms + NUM_TEXTURE_TRANSFORMS = MATERIAL_TEXTURE7 - MATERIAL_TEXTURE0 + 1 +}; + +// FIXME: How do I specify the actual number of matrix modes? +const int NUM_MODEL_TRANSFORMS = 53; +const int MATERIAL_MODEL_MAX = MATERIAL_MODEL + NUM_MODEL_TRANSFORMS; + +enum MaterialPrimitiveType_t +{ + MATERIAL_POINTS = 0x0, + MATERIAL_LINES, + MATERIAL_TRIANGLES, + MATERIAL_TRIANGLE_STRIP, + MATERIAL_LINE_STRIP, + MATERIAL_LINE_LOOP, // a single line loop + MATERIAL_POLYGON, // this is a *single* polygon + MATERIAL_QUADS, + MATERIAL_INSTANCED_QUADS, // (X360) like MATERIAL_QUADS, but uses vertex instancing + + // This is used for static meshes that contain multiple types of + // primitive types. When calling draw, you'll need to specify + // a primitive type. + MATERIAL_HETEROGENOUS +}; + +enum MaterialPropertyTypes_t +{ + MATERIAL_PROPERTY_NEEDS_LIGHTMAP = 0, // bool + MATERIAL_PROPERTY_OPACITY, // int (enum MaterialPropertyOpacityTypes_t) + MATERIAL_PROPERTY_REFLECTIVITY, // vec3_t + MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS // bool +}; + +// acceptable property values for MATERIAL_PROPERTY_OPACITY +enum MaterialPropertyOpacityTypes_t +{ + MATERIAL_ALPHATEST = 0, + MATERIAL_OPAQUE, + MATERIAL_TRANSLUCENT +}; + +enum MaterialBufferTypes_t +{ + MATERIAL_FRONT = 0, + MATERIAL_BACK +}; + +enum MaterialCullMode_t +{ + MATERIAL_CULLMODE_CCW, // this culls polygons with counterclockwise winding + MATERIAL_CULLMODE_CW // this culls polygons with clockwise winding +}; + +enum MaterialIndexFormat_t +{ + MATERIAL_INDEX_FORMAT_UNKNOWN = -1, + MATERIAL_INDEX_FORMAT_16BIT = 0, + MATERIAL_INDEX_FORMAT_32BIT, +}; + +enum MaterialFogMode_t +{ + MATERIAL_FOG_NONE, + MATERIAL_FOG_LINEAR, + MATERIAL_FOG_LINEAR_BELOW_FOG_Z, +}; + +enum MaterialHeightClipMode_t +{ + MATERIAL_HEIGHTCLIPMODE_DISABLE, + MATERIAL_HEIGHTCLIPMODE_RENDER_ABOVE_HEIGHT, + MATERIAL_HEIGHTCLIPMODE_RENDER_BELOW_HEIGHT +}; + +enum MaterialNonInteractiveMode_t +{ + MATERIAL_NON_INTERACTIVE_MODE_NONE = -1, + MATERIAL_NON_INTERACTIVE_MODE_STARTUP = 0, + MATERIAL_NON_INTERACTIVE_MODE_LEVEL_LOAD, + + MATERIAL_NON_INTERACTIVE_MODE_COUNT, +}; + + +//----------------------------------------------------------------------------- +// Special morph used in decalling pass +//----------------------------------------------------------------------------- +#define MATERIAL_MORPH_DECAL ( (IMorph*)1 ) + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum MaterialThreadMode_t +{ + MATERIAL_SINGLE_THREADED, + MATERIAL_QUEUED_SINGLE_THREADED, + MATERIAL_QUEUED_THREADED +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum MaterialContextType_t +{ + MATERIAL_HARDWARE_CONTEXT, + MATERIAL_QUEUED_CONTEXT, + MATERIAL_NULL_CONTEXT +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum MaterialFindContext_t +{ + MATERIAL_FINDCONTEXT_NONE, + MATERIAL_FINDCONTEXT_ISONAMODEL, +}; + +//----------------------------------------------------------------------------- +// Light structure +//----------------------------------------------------------------------------- +#include "mathlib/lightdesc.h" + +#if 0 +enum LightType_t +{ + MATERIAL_LIGHT_DISABLE = 0, + MATERIAL_LIGHT_POINT, + MATERIAL_LIGHT_DIRECTIONAL, + MATERIAL_LIGHT_SPOT, +}; + +enum LightType_OptimizationFlags_t +{ + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 = 1, + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 = 2, + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 = 4, +}; + + +struct LightDesc_t +{ + LightType_t m_Type; + Vector m_Color; + Vector m_Position; + Vector m_Direction; + float m_Range; + float m_Falloff; + float m_Attenuation0; + float m_Attenuation1; + float m_Attenuation2; + float m_Theta; + float m_Phi; + // These aren't used by DX8. . used for software lighting. + float m_ThetaDot; + float m_PhiDot; + unsigned int m_Flags; + + + LightDesc_t() {} + +private: + // No copy constructors allowed + LightDesc_t(const LightDesc_t& vOther); +}; +#endif + +#define CREATERENDERTARGETFLAGS_HDR 0x00000001 +#define CREATERENDERTARGETFLAGS_AUTOMIPMAP 0x00000002 +#define CREATERENDERTARGETFLAGS_UNFILTERABLE_OK 0x00000004 +// XBOX ONLY: +#define CREATERENDERTARGETFLAGS_NOEDRAM 0x00000008 // inhibit allocation in 360 EDRAM +#define CREATERENDERTARGETFLAGS_TEMP 0x00000010 // only allocates memory upon first resolve, destroyed at level end + + +//----------------------------------------------------------------------------- +// allowed stencil operations. These match the d3d operations +//----------------------------------------------------------------------------- +enum StencilOperation_t +{ +#if !defined( _X360 ) + STENCILOPERATION_KEEP = 1, + STENCILOPERATION_ZERO = 2, + STENCILOPERATION_REPLACE = 3, + STENCILOPERATION_INCRSAT = 4, + STENCILOPERATION_DECRSAT = 5, + STENCILOPERATION_INVERT = 6, + STENCILOPERATION_INCR = 7, + STENCILOPERATION_DECR = 8, +#else + STENCILOPERATION_KEEP = D3DSTENCILOP_KEEP, + STENCILOPERATION_ZERO = D3DSTENCILOP_ZERO, + STENCILOPERATION_REPLACE = D3DSTENCILOP_REPLACE, + STENCILOPERATION_INCRSAT = D3DSTENCILOP_INCRSAT, + STENCILOPERATION_DECRSAT = D3DSTENCILOP_DECRSAT, + STENCILOPERATION_INVERT = D3DSTENCILOP_INVERT, + STENCILOPERATION_INCR = D3DSTENCILOP_INCR, + STENCILOPERATION_DECR = D3DSTENCILOP_DECR, +#endif + STENCILOPERATION_FORCE_DWORD = 0x7fffffff +}; + +enum StencilComparisonFunction_t +{ +#if !defined( _X360 ) + STENCILCOMPARISONFUNCTION_NEVER = 1, + STENCILCOMPARISONFUNCTION_LESS = 2, + STENCILCOMPARISONFUNCTION_EQUAL = 3, + STENCILCOMPARISONFUNCTION_LESSEQUAL = 4, + STENCILCOMPARISONFUNCTION_GREATER = 5, + STENCILCOMPARISONFUNCTION_NOTEQUAL = 6, + STENCILCOMPARISONFUNCTION_GREATEREQUAL = 7, + STENCILCOMPARISONFUNCTION_ALWAYS = 8, +#else + STENCILCOMPARISONFUNCTION_NEVER = D3DCMP_NEVER, + STENCILCOMPARISONFUNCTION_LESS = D3DCMP_LESS, + STENCILCOMPARISONFUNCTION_EQUAL = D3DCMP_EQUAL, + STENCILCOMPARISONFUNCTION_LESSEQUAL = D3DCMP_LESSEQUAL, + STENCILCOMPARISONFUNCTION_GREATER = D3DCMP_GREATER, + STENCILCOMPARISONFUNCTION_NOTEQUAL = D3DCMP_NOTEQUAL, + STENCILCOMPARISONFUNCTION_GREATEREQUAL = D3DCMP_GREATEREQUAL, + STENCILCOMPARISONFUNCTION_ALWAYS = D3DCMP_ALWAYS, +#endif + + STENCILCOMPARISONFUNCTION_FORCE_DWORD = 0x7fffffff +}; + + +//----------------------------------------------------------------------------- +// Enumeration for the various fields capable of being morphed +//----------------------------------------------------------------------------- +enum MorphFormatFlags_t +{ + MORPH_POSITION = 0x0001, // 3D + MORPH_NORMAL = 0x0002, // 3D + MORPH_WRINKLE = 0x0004, // 1D + MORPH_SPEED = 0x0008, // 1D + MORPH_SIDE = 0x0010, // 1D +}; + + +//----------------------------------------------------------------------------- +// The morph format type +//----------------------------------------------------------------------------- +typedef unsigned int MorphFormat_t; + + +//----------------------------------------------------------------------------- +// Standard lightmaps +//----------------------------------------------------------------------------- +enum StandardLightmap_t +{ + MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE = -1, + MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE_BUMP = -2, + MATERIAL_SYSTEM_LIGHTMAP_PAGE_USER_DEFINED = -3 +}; + + +struct MaterialSystem_SortInfo_t +{ + IMaterial *material; + int lightmapPageID; +}; + + +#define MAX_FB_TEXTURES 4 + +//----------------------------------------------------------------------------- +// Information about each adapter +//----------------------------------------------------------------------------- +enum +{ + MATERIAL_ADAPTER_NAME_LENGTH = 512 +}; + +struct MaterialAdapterInfo_t +{ + char m_pDriverName[MATERIAL_ADAPTER_NAME_LENGTH]; + unsigned int m_VendorID; + unsigned int m_DeviceID; + unsigned int m_SubSysID; + unsigned int m_Revision; + int m_nDXSupportLevel; // This is the *preferred* dx support level + int m_nMaxDXSupportLevel; + unsigned int m_nDriverVersionHigh; + unsigned int m_nDriverVersionLow; +}; + + +//----------------------------------------------------------------------------- +// Video mode info.. +//----------------------------------------------------------------------------- +struct MaterialVideoMode_t +{ + int m_Width; // if width and height are 0 and you select + int m_Height; // windowed mode, it'll use the window size + ImageFormat m_Format; // use ImageFormats (ignored for windowed mode) + int m_RefreshRate; // 0 == default (ignored for windowed mode) +}; + +// fixme: should move this into something else. +struct FlashlightState_t +{ + FlashlightState_t() + { + m_bEnableShadows = false; // Provide reasonable defaults for shadow depth mapping parameters + m_bDrawShadowFrustum = false; + m_flShadowMapResolution = 1024.0f; + m_flShadowFilterSize = 3.0f; + m_flShadowSlopeScaleDepthBias = 16.0f; + m_flShadowDepthBias = 0.0005f; + m_flShadowJitterSeed = 0.0f; + m_flShadowAtten = 0.0f; + m_bScissor = false; + m_nLeft = -1; + m_nTop = -1; + m_nRight = -1; + m_nBottom = -1; + m_nShadowQuality = 0; + } + + Vector m_vecLightOrigin; + Quaternion m_quatOrientation; + float m_NearZ; + float m_FarZ; + float m_fHorizontalFOVDegrees; + float m_fVerticalFOVDegrees; + float m_fQuadraticAtten; + float m_fLinearAtten; + float m_fConstantAtten; + float m_Color[4]; + ITexture *m_pSpotlightTexture; + int m_nSpotlightTextureFrame; + + // Shadow depth mapping parameters + bool m_bEnableShadows; + bool m_bDrawShadowFrustum; + float m_flShadowMapResolution; + float m_flShadowFilterSize; + float m_flShadowSlopeScaleDepthBias; + float m_flShadowDepthBias; + float m_flShadowJitterSeed; + float m_flShadowAtten; + int m_nShadowQuality; + + // Getters for scissor members + bool DoScissor() { return m_bScissor; } + int GetLeft() { return m_nLeft; } + int GetTop() { return m_nTop; } + int GetRight() { return m_nRight; } + int GetBottom() { return m_nBottom; } + +private: + + friend class CShadowMgr; + + bool m_bScissor; + int m_nLeft; + int m_nTop; + int m_nRight; + int m_nBottom; +}; + +//----------------------------------------------------------------------------- +// Flags to be used with the Init call +//----------------------------------------------------------------------------- +enum MaterialInitFlags_t +{ + MATERIAL_INIT_ALLOCATE_FULLSCREEN_TEXTURE = 0x2, + MATERIAL_INIT_REFERENCE_RASTERIZER = 0x4, +}; + +//----------------------------------------------------------------------------- +// Flags to specify type of depth buffer used with RT +//----------------------------------------------------------------------------- + +// GR - this is to add RT with no depth buffer bound + +enum MaterialRenderTargetDepth_t +{ + MATERIAL_RT_DEPTH_SHARED = 0x0, + MATERIAL_RT_DEPTH_SEPARATE = 0x1, + MATERIAL_RT_DEPTH_NONE = 0x2, + MATERIAL_RT_DEPTH_ONLY = 0x3, +}; + +//----------------------------------------------------------------------------- +// A function to be called when we need to release all vertex buffers +// NOTE: The restore function will tell the caller if all the vertex formats +// changed so that it can flush caches, etc. if it needs to (for dxlevel support) +//----------------------------------------------------------------------------- +enum RestoreChangeFlags_t +{ + MATERIAL_RESTORE_VERTEX_FORMAT_CHANGED = 0x1, +}; + + +// NOTE: All size modes will force the render target to be smaller than or equal to +// the size of the framebuffer. +enum RenderTargetSizeMode_t +{ + RT_SIZE_NO_CHANGE=0, // Only allowed for render targets that don't want a depth buffer + // (because if they have a depth buffer, the render target must be less than or equal to the size of the framebuffer). + RT_SIZE_DEFAULT=1, // Don't play with the specified width and height other than making sure it fits in the framebuffer. + RT_SIZE_PICMIP=2, // Apply picmip to the render target's width and height. + RT_SIZE_HDR=3, // frame_buffer_width / 4 + RT_SIZE_FULL_FRAME_BUFFER=4, // Same size as frame buffer, or next lower power of 2 if we can't do that. + RT_SIZE_OFFSCREEN=5, // Target of specified size, don't mess with dimensions + RT_SIZE_FULL_FRAME_BUFFER_ROUNDED_UP=6, // Same size as the frame buffer, rounded up if necessary for systems that can't do non-power of two textures. + RT_SIZE_REPLAY_SCREENSHOT = 7 // Rounded down to power of 2, essentially... +}; + +typedef void (*MaterialBufferReleaseFunc_t)( ); +typedef void (*MaterialBufferRestoreFunc_t)( int nChangeFlags ); // see RestoreChangeFlags_t +typedef void (*ModeChangeCallbackFunc_t)( void ); + +typedef int VertexBufferHandle_t; +typedef unsigned short MaterialHandle_t; + +DECLARE_POINTER_HANDLE( OcclusionQueryObjectHandle_t ); +#define INVALID_OCCLUSION_QUERY_OBJECT_HANDLE ( (OcclusionQueryObjectHandle_t)0 ) + +class IMaterialProxyFactory; +class ITexture; +class IMaterialSystemHardwareConfig; +class CShadowMgr; + +DECLARE_POINTER_HANDLE( MaterialLock_t ); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +abstract_class IMaterialSystem : public IAppSystem +{ +public: + + // Placeholder for API revision + virtual bool Connect( CreateInterfaceFn factory ) = 0; + virtual void Disconnect() = 0; + virtual void *QueryInterface( const char *pInterfaceName ) = 0; + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; + + //--------------------------------------------------------- + // Initialization and shutdown + //--------------------------------------------------------- + + // Call this to initialize the material system + // returns a method to create interfaces in the shader dll + virtual CreateInterfaceFn Init( char const* pShaderAPIDLL, + IMaterialProxyFactory *pMaterialProxyFactory, + CreateInterfaceFn fileSystemFactory, + CreateInterfaceFn cvarFactory=NULL ) = 0; + + // Call this to set an explicit shader version to use + // Must be called before Init(). + virtual void SetShaderAPI( char const *pShaderAPIDLL ) = 0; + + // Must be called before Init(), if you're going to call it at all... + virtual void SetAdapter( int nAdapter, int nFlags ) = 0; + + // Call this when the mod has been set up, which may occur after init + // At this point, the game + gamebin paths have been set up + virtual void ModInit() = 0; + virtual void ModShutdown() = 0; + + //--------------------------------------------------------- + // + //--------------------------------------------------------- + virtual void SetThreadMode( MaterialThreadMode_t mode, int nServiceThread = -1 ) = 0; + virtual MaterialThreadMode_t GetThreadMode( ) = 0; + virtual bool IsRenderThreadSafe( ) = 0; + virtual void ExecuteQueued() = 0; + + //--------------------------------------------------------- + // Config management + //--------------------------------------------------------- + + virtual IMaterialSystemHardwareConfig *GetHardwareConfig( const char *pVersion, int *returnCode ) = 0; + + + // 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 bForceUpdate ) = 0; + + // Force this to be the config; update all material system convars to match the state + // return true if lightmaps need to be redownloaded + virtual bool OverrideConfig( const MaterialSystem_Config_t &config, bool bForceUpdate ) = 0; + + // Get the current config for this video card (as last set by UpdateConfig) + virtual const MaterialSystem_Config_t &GetCurrentConfigForVideoCard() const = 0; + + // Gets *recommended* configuration information associated with the display card, + // given a particular dx level to run under. + // Use dxlevel 0 to use the recommended dx level. + // The function returns false if an invalid dxlevel was specified + + // UNDONE: To find out all convars affected by configuration, we'll need to change + // the dxsupport.pl program to output all column headers into a single keyvalue block + // and then we would read that in, and send it back to the client + virtual bool GetRecommendedConfigurationInfo( int nDXLevel, KeyValues * pKeyValues ) = 0; + + + // ----------------------------------------------------------- + // Device methods + // ----------------------------------------------------------- + + // Gets the number of adapters... + virtual int GetDisplayAdapterCount() const = 0; + + // Returns the current adapter in use + virtual int GetCurrentAdapter() const = 0; + + // Returns info about each adapter + virtual void GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const = 0; + + // Returns the number of modes + virtual int GetModeCount( int adapter ) const = 0; + + // Returns mode information.. + virtual void GetModeInfo( int adapter, int mode, MaterialVideoMode_t& info ) const = 0; + + virtual void AddModeChangeCallBack( ModeChangeCallbackFunc_t func ) = 0; + + // Returns the mode info for the current display device + virtual void GetDisplayMode( MaterialVideoMode_t& mode ) const = 0; + + // Sets the mode... + virtual bool SetMode( void* hwnd, const MaterialSystem_Config_t &config ) = 0; + + virtual bool SupportsMSAAMode( int nMSAAMode ) = 0; + + // FIXME: REMOVE! Get video card identitier + virtual const MaterialSystemHardwareIdentifier_t &GetVideoCardIdentifier( void ) const = 0; + + // Use this to spew information about the 3D layer + virtual void SpewDriverInfo() const = 0; + + virtual void GetDXLevelDefaults(uint &max_dxlevel,uint &recommended_dxlevel) = 0; + + // Get the image format of the back buffer. . useful when creating render targets, etc. + virtual void GetBackBufferDimensions( int &width, int &height) const = 0; + virtual ImageFormat GetBackBufferFormat() const = 0; + + virtual bool SupportsHDRMode( HDRType_t nHDRModede ) = 0; + + + // ----------------------------------------------------------- + // Window methods + // ----------------------------------------------------------- + + // Creates/ destroys a child window + virtual bool AddView( void* hwnd ) = 0; + virtual void RemoveView( void* hwnd ) = 0; + + // Sets the view + virtual void SetView( void* hwnd ) = 0; + + + // ----------------------------------------------------------- + // Control flow + // ----------------------------------------------------------- + + virtual void BeginFrame( float frameTime ) = 0; + virtual void EndFrame( ) = 0; + virtual void Flush( bool flushHardware = false ) = 0; + + /// FIXME: This stuff needs to be cleaned up and abstracted. + // Stuff that gets exported to the launcher through the engine + virtual void SwapBuffers( ) = 0; + + // Flushes managed textures from the texture cacher + virtual void EvictManagedResources() = 0; + + virtual void ReleaseResources(void) = 0; + virtual void ReacquireResources(void ) = 0; + + + // ----------------------------------------------------------- + // Device loss/restore + // ----------------------------------------------------------- + + // Installs a function to be called when we need to release vertex buffers + textures + virtual void AddReleaseFunc( MaterialBufferReleaseFunc_t func ) = 0; + virtual void RemoveReleaseFunc( MaterialBufferReleaseFunc_t func ) = 0; + + // Installs a function to be called when we need to restore vertex buffers + virtual void AddRestoreFunc( MaterialBufferRestoreFunc_t func ) = 0; + virtual void RemoveRestoreFunc( MaterialBufferRestoreFunc_t func ) = 0; + + // Release temporary HW memory... + virtual void ResetTempHWMemory( bool bExitingLevel = false ) = 0; + + // For dealing with device lost in cases where SwapBuffers isn't called all the time (Hammer) + virtual void HandleDeviceLost() = 0; + + + // ----------------------------------------------------------- + // Shaders + // ----------------------------------------------------------- + + // Used to iterate over all shaders for editing purposes + // GetShaders returns the number of shaders it actually found + virtual int ShaderCount() const = 0; + virtual int GetShaders( int nFirstShader, int nMaxCount, IShader **ppShaderList ) const = 0; + + // FIXME: Is there a better way of doing this? + // Returns shader flag names for editors to be able to edit them + virtual int ShaderFlagCount() const = 0; + virtual const char * ShaderFlagName( int nIndex ) const = 0; + + // Gets the actual shader fallback for a particular shader + virtual void GetShaderFallback( const char *pShaderName, char *pFallbackShader, int nFallbackLength ) = 0; + + + // ----------------------------------------------------------- + // Material proxies + // ----------------------------------------------------------- + + virtual IMaterialProxyFactory *GetMaterialProxyFactory() = 0; + + // Sets the material proxy factory. Calling this causes all materials to be uncached. + virtual void SetMaterialProxyFactory( IMaterialProxyFactory* pFactory ) = 0; + + + // ----------------------------------------------------------- + // Editor mode + // ----------------------------------------------------------- + + // Used to enable editor materials. Must be called before Init. + virtual void EnableEditorMaterials() = 0; + + + // ----------------------------------------------------------- + // Stub mode mode + // ----------------------------------------------------------- + + // Force it to ignore Draw calls. + virtual void SetInStubMode( bool bInStubMode ) = 0; + + + //--------------------------------------------------------- + // Debug support + //--------------------------------------------------------- + + virtual void DebugPrintUsedMaterials( const char *pSearchSubString, bool bVerbose ) = 0; + virtual void DebugPrintUsedTextures( void ) = 0; + + virtual void ToggleSuppressMaterial( char const* pMaterialName ) = 0; + virtual void ToggleDebugMaterial( char const* pMaterialName ) = 0; + + + //--------------------------------------------------------- + // Misc features + //--------------------------------------------------------- + //returns whether fast clipping is being used or not - needed to be exposed for better per-object clip behavior + virtual bool UsingFastClipping( void ) = 0; + + virtual int StencilBufferBits( void ) = 0; //number of bits per pixel in the stencil buffer + + + //--------------------------------------------------------- + // Material and texture management + //--------------------------------------------------------- + + // uncache all materials. . good for forcing reload of materials. + virtual void UncacheAllMaterials( ) = 0; + + // Remove any materials from memory that aren't in use as determined + // by the IMaterial's reference count. + virtual void UncacheUnusedMaterials( bool bRecomputeStateSnapshots = false ) = 0; + + // Load any materials into memory that are to be used as determined + // by the IMaterial's reference count. + virtual void CacheUsedMaterials( ) = 0; + + // Force all textures to be reloaded from disk. + virtual void ReloadTextures( ) = 0; + + // Reloads materials + virtual void ReloadMaterials( const char *pSubString = NULL ) = 0; + + // Create a procedural material. The keyvalues looks like a VMT file + virtual IMaterial * CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues ) = 0; + + // 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" + // + // Most of the texture groups for pTextureGroupName are listed in texture_group_names.h. + // + // Note: if the material can't be found, this returns a checkerboard material. You can + // find out if you have that material by calling IMaterial::IsErrorMaterial(). + // (Or use the global IsErrorMaterial function, which checks if it's null too). + virtual IMaterial * FindMaterial( char const* pMaterialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL ) = 0; + + // Query whether a material is loaded (eg, whether FindMaterial will be nonblocking) + virtual bool IsMaterialLoaded( char const* pMaterialName ) = 0; + + //--------------------------------- + // 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 = 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 = 0; + + // This is the invalid material + virtual MaterialHandle_t InvalidMaterial() const = 0; + + // Returns a particular material + virtual IMaterial* GetMaterial( MaterialHandle_t h ) const = 0; + + // Get the total number of materials in the system. These aren't just the used + // materials, but the complete collection. + virtual int GetNumMaterials( ) const = 0; + + //--------------------------------- + + virtual void SetAsyncTextureLoadCache( void* hFileCache ) = 0; + + virtual ITexture * FindTexture( char const* pTextureName, const char *pTextureGroupName, bool complain = true, int nAdditionalCreationFlags = 0 ) = 0; + + // Checks to see if a particular texture is loaded + virtual bool IsTextureLoaded( char const* pTextureName ) const = 0; + + // Creates a procedural texture + virtual ITexture * CreateProceduralTexture( const char *pTextureName, + const char *pTextureGroupName, + int w, + int h, + ImageFormat fmt, + int nFlags ) = 0; + + // + // Render targets + // + virtual void BeginRenderTargetAllocation() = 0; + virtual void EndRenderTargetAllocation() = 0; // Simulate an Alt-Tab in here, which causes a release/restore of all resources + + // Creates a render target + // If depth == true, a depth buffer is also allocated. If not, then + // the screen's depth buffer is used. + // Creates a texture for use as a render target + 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 = MATERIAL_RT_DEPTH_SHARED ) = 0; + + 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 ) = 0; + + 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 = MATERIAL_RT_DEPTH_SHARED, + bool bClampTexCoords = true, + bool bAutoMipMap = false ) = 0; + + // Must be called between the above Begin-End calls! + virtual 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 ) = 0; + + // ----------------------------------------------------------- + // Lightmaps + // ----------------------------------------------------------- + + // 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( ) = 0; + virtual void EndLightmapAllocation( ) = 0; + + // returns the sorting id for this surface + virtual int AllocateLightmap( int width, int height, + int offsetIntoLightmapPage[2], + IMaterial *pMaterial ) = 0; + // returns the sorting id for this surface + virtual int AllocateWhiteLightmap( IMaterial *pMaterial ) = 0; + + // 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 ) = 0; + + // fixme: could just be an array of ints for lightmapPageIDs since the material + // for a surface is already known. + virtual int GetNumSortIDs( ) = 0; + virtual void GetSortInfo( MaterialSystem_SortInfo_t *sortInfoArray ) = 0; + + // Read the page size of an existing lightmap by sort id (returned from AllocateLightmap()) + virtual void GetLightmapPageSize( int lightmap, int *width, int *height ) const = 0; + + virtual void ResetMaterialLightmapPageInfo() = 0; + + + + virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil = false ) = 0; + + // ----------------------------------------------------------- + // X360 specifics + // ----------------------------------------------------------- + +#if defined( _X360 ) + virtual void ListUsedMaterials( void ) = 0; + virtual HXUIFONT OpenTrueTypeFont( const char *pFontname, int tall, int style ) = 0; + virtual void CloseTrueTypeFont( HXUIFONT hFont ) = 0; + virtual bool GetTrueTypeFontMetrics( HXUIFONT hFont, XUIFontMetrics *pFontMetrics, XUICharMetrics charMetrics[256] ) = 0; + // Render a sequence of characters and extract the data into a buffer + // For each character, provide the width+height of the font texture subrect, + // an offset to apply when rendering the glyph, and an offset into a buffer to receive the RGBA data + virtual bool GetTrueTypeGlyphs( HXUIFONT hFont, int numChars, wchar_t *pWch, int *pOffsetX, int *pOffsetY, int *pWidth, int *pHeight, unsigned char *pRGBA, int *pRGBAOffset ) = 0; + virtual void PersistDisplay() = 0; + virtual void *GetD3DDevice() = 0; + virtual bool OwnGPUResources( bool bEnable ) = 0; +#endif + + // ----------------------------------------------------------- + // Access the render contexts + // ----------------------------------------------------------- + virtual IMatRenderContext * GetRenderContext() = 0; + + virtual bool SupportsShadowDepthTextures( void ) = 0; + virtual void BeginUpdateLightmaps( void ) = 0; + virtual void EndUpdateLightmaps( void ) = 0; + + // ----------------------------------------------------------- + // Methods to force the material system into non-threaded, non-queued mode + // ----------------------------------------------------------- + virtual MaterialLock_t Lock() = 0; + virtual void Unlock( MaterialLock_t ) = 0; + + // Vendor-dependent shadow depth texture format + virtual ImageFormat GetShadowDepthTextureFormat() = 0; + + virtual bool SupportsFetch4( void ) = 0; + + // Create a custom render context. Cannot be used to create MATERIAL_HARDWARE_CONTEXT + virtual IMatRenderContext *CreateRenderContext( MaterialContextType_t type ) = 0; + + // Set a specified render context to be the global context for the thread. Returns the prior context. + virtual IMatRenderContext *SetRenderContext( IMatRenderContext * ) = 0; + + virtual bool SupportsCSAAMode( int nNumSamples, int nQualityLevel ) = 0; + + virtual void RemoveModeChangeCallBack( ModeChangeCallbackFunc_t func ) = 0; + + // Finds or create a procedural material. + virtual IMaterial * FindProceduralMaterial( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ) = 0; + + virtual ImageFormat GetNullTextureFormat() = 0; + + virtual void AddTextureAlias( const char *pAlias, const char *pRealName ) = 0; + virtual void RemoveTextureAlias( const char *pAlias ) = 0; + + // returns a lightmap page ID for this allocation, -1 if none available + // frameID is a number that should be changed every frame to prevent locking any textures that are + // being used to draw in the previous frame + virtual int AllocateDynamicLightmap( int lightmapSize[2], int *pOutOffsetIntoPage, int frameID ) = 0; + + virtual void SetExcludedTextures( const char *pScriptName ) = 0; + virtual void UpdateExcludedTextures( void ) = 0; + + virtual bool IsInFrame( ) const = 0; + + virtual void CompactMemory() = 0; + + // 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 ) = 0; + virtual bool AllowThreading( bool bAllow, int nServiceThread ) = 0; + + // Extended version of FindMaterial(). + // Contains context in so it can make decisions (i.e. if it's a model, ignore certain cheat parameters) + virtual IMaterial * FindMaterialEx( char const* pMaterialName, const char *pTextureGroupName, int nContext, bool complain = true, const char *pComplainPrefix = NULL ) = 0; + +#ifdef DX_TO_GL_ABSTRACTION + virtual void DoStartupShaderPreloading( void ) = 0; +#endif +}; + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +abstract_class IMatRenderContext : public IRefCounted +{ +public: + virtual void BeginRender() = 0; + virtual void EndRender() = 0; + + virtual void Flush( bool flushHardware = false ) = 0; + + virtual void BindLocalCubemap( ITexture *pTexture ) = 0; + + // pass in an ITexture (that is build with "rendertarget" "1") or + // pass in NULL for the regular backbuffer. + virtual void SetRenderTarget( ITexture *pTexture ) = 0; + virtual ITexture * GetRenderTarget( void ) = 0; + + virtual void GetRenderTargetDimensions( int &width, int &height) const = 0; + + // Bind a material is current for rendering. + virtual void Bind( IMaterial *material, void *proxyData = 0 ) = 0; + // Bind a lightmap page current for rendering. You only have to + // do this for materials that require lightmaps. + virtual void BindLightmapPage( int lightmapPageID ) = 0; + + // inputs are between 0 and 1 + virtual void DepthRange( float zNear, float zFar ) = 0; + + virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil = false ) = 0; + + // read to a unsigned char rgb image. + virtual void ReadPixels( int x, int y, int width, int height, unsigned char *data, ImageFormat dstFormat ) = 0; + + // Sets lighting + virtual void SetAmbientLight( float r, float g, float b ) = 0; + virtual void SetLight( int lightNum, const LightDesc_t& desc ) = 0; + + // The faces of the cube are specified in the same order as cubemap textures + virtual void SetAmbientLightCube( Vector4D cube[6] ) = 0; + + // Blit the backbuffer to the framebuffer texture + virtual void CopyRenderTargetToTexture( ITexture *pTexture ) = 0; + + // Set the current texture that is a copy of the framebuffer. + virtual void SetFrameBufferCopyTexture( ITexture *pTexture, int textureIndex = 0 ) = 0; + virtual ITexture *GetFrameBufferCopyTexture( int textureIndex ) = 0; + + // + // end vertex array api + // + + // matrix api + virtual void MatrixMode( MaterialMatrixMode_t matrixMode ) = 0; + virtual void PushMatrix( void ) = 0; + virtual void PopMatrix( void ) = 0; + virtual void LoadMatrix( VMatrix const& matrix ) = 0; + virtual void LoadMatrix( matrix3x4_t const& matrix ) = 0; + virtual void MultMatrix( VMatrix const& matrix ) = 0; + virtual void MultMatrix( matrix3x4_t const& matrix ) = 0; + virtual void MultMatrixLocal( VMatrix const& matrix ) = 0; + virtual void MultMatrixLocal( matrix3x4_t const& matrix ) = 0; + virtual void GetMatrix( MaterialMatrixMode_t matrixMode, VMatrix *matrix ) = 0; + virtual void GetMatrix( MaterialMatrixMode_t matrixMode, matrix3x4_t *matrix ) = 0; + virtual void LoadIdentity( void ) = 0; + virtual void Ortho( double left, double top, double right, double bottom, double zNear, double zFar ) = 0; + virtual void PerspectiveX( double fovx, double aspect, double zNear, double zFar ) = 0; + virtual void PickMatrix( int x, int y, int width, int height ) = 0; + virtual void Rotate( float angle, float x, float y, float z ) = 0; + virtual void Translate( float x, float y, float z ) = 0; + virtual void Scale( float x, float y, float z ) = 0; + // end matrix api + + // Sets/gets the viewport + virtual void Viewport( int x, int y, int width, int height ) = 0; + virtual void GetViewport( int& x, int& y, int& width, int& height ) const = 0; + + // The cull mode + virtual void CullMode( MaterialCullMode_t cullMode ) = 0; + + // end matrix api + + // This could easily be extended to a general user clip plane + virtual void SetHeightClipMode( MaterialHeightClipMode_t nHeightClipMode ) = 0; + // garymcthack : fog z is always used for heightclipz for now. + virtual void SetHeightClipZ( float z ) = 0; + + // Fog methods... + virtual void FogMode( MaterialFogMode_t fogMode ) = 0; + virtual void FogStart( float fStart ) = 0; + virtual void FogEnd( float fEnd ) = 0; + virtual void SetFogZ( float fogZ ) = 0; + virtual MaterialFogMode_t GetFogMode( void ) = 0; + + virtual void FogColor3f( float r, float g, float b ) = 0; + virtual void FogColor3fv( float const* rgb ) = 0; + virtual void FogColor3ub( unsigned char r, unsigned char g, unsigned char b ) = 0; + virtual void FogColor3ubv( unsigned char const* rgb ) = 0; + + virtual void GetFogColor( unsigned char *rgb ) = 0; + + // Sets the number of bones for skinning + virtual void SetNumBoneWeights( int numBones ) = 0; + + // Creates/destroys Mesh + virtual IMesh* CreateStaticMesh( VertexFormat_t fmt, const char *pTextureBudgetGroup, IMaterial * pMaterial = NULL ) = 0; + virtual void DestroyStaticMesh( IMesh* mesh ) = 0; + + // 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 buffered = true, + IMesh* pVertexOverride = 0, + IMesh* pIndexOverride = 0, + IMaterial *pAutoBind = 0 ) = 0; + + // ------------ New Vertex/Index Buffer interface ---------------------------- + // Do we need support for bForceTempMesh and bSoftwareVertexShader? + // I don't think we use bSoftwareVertexShader anymore. .need to look into bForceTempMesh. + virtual IVertexBuffer *CreateStaticVertexBuffer( VertexFormat_t fmt, int nVertexCount, const char *pTextureBudgetGroup ) = 0; + virtual IIndexBuffer *CreateStaticIndexBuffer( MaterialIndexFormat_t fmt, int nIndexCount, const char *pTextureBudgetGroup ) = 0; + virtual void DestroyVertexBuffer( IVertexBuffer * ) = 0; + virtual void DestroyIndexBuffer( IIndexBuffer * ) = 0; + // 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 ) = 0; + virtual IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true ) = 0; + virtual void BindVertexBuffer( int streamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, int nFirstVertex, int nVertexCount, VertexFormat_t fmt, int nRepetitions = 1 ) = 0; + virtual void BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes ) = 0; + virtual void Draw( MaterialPrimitiveType_t primitiveType, int firstIndex, int numIndices ) = 0; + // ------------ End ---------------------------- + + // Selection mode methods + virtual int SelectionMode( bool selectionMode ) = 0; + virtual void SelectionBuffer( unsigned int* pBuffer, int size ) = 0; + virtual void ClearSelectionNames( ) = 0; + virtual void LoadSelectionName( int name ) = 0; + virtual void PushSelectionName( int name ) = 0; + virtual void PopSelectionName() = 0; + + // Sets the Clear Color for ClearBuffer.... + virtual void ClearColor3ub( unsigned char r, unsigned char g, unsigned char b ) = 0; + virtual void ClearColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) = 0; + + // Allows us to override the depth buffer setting of a material + virtual void OverrideDepthEnable( bool bEnable, bool bDepthEnable ) = 0; + + // FIXME: This is a hack required for NVidia/XBox, can they fix in drivers? + virtual void DrawScreenSpaceQuad( IMaterial* pMaterial ) = 0; + + // For debugging and building recording files. This will stuff a token into the recording file, + // then someone doing a playback can watch for the token. + virtual void SyncToken( const char *pToken ) = 0; + + // FIXME: REMOVE THIS FUNCTION! + // The only reason why it's not gone is because we're a week from ship when I found the bug in it + // and everything's tuned to use it. + // It's returning values which are 2x too big (it's returning sphere diameter x2) + // Use ComputePixelDiameterOfSphere below in all new code instead. + virtual float ComputePixelWidthOfSphere( const Vector& origin, float flRadius ) = 0; + + // + // Occlusion query support + // + + // Allocate and delete query objects. + virtual OcclusionQueryObjectHandle_t CreateOcclusionQueryObject( void ) = 0; + virtual void DestroyOcclusionQueryObject( OcclusionQueryObjectHandle_t ) = 0; + + // Bracket drawing with begin and end so that we can get counts next frame. + virtual void BeginOcclusionQueryDrawing( OcclusionQueryObjectHandle_t ) = 0; + virtual void EndOcclusionQueryDrawing( OcclusionQueryObjectHandle_t ) = 0; + + // Get the number of pixels rendered between begin and end on an earlier frame. + // Calling this in the same frame is a huge perf hit! + virtual int OcclusionQuery_GetNumPixelsRendered( OcclusionQueryObjectHandle_t ) = 0; + + virtual void SetFlashlightMode( bool bEnable ) = 0; + + virtual void SetFlashlightState( const FlashlightState_t &state, const VMatrix &worldToTexture ) = 0; + + // Gets the current height clip mode + virtual MaterialHeightClipMode_t GetHeightClipMode( ) = 0; + + // This returns the diameter of the sphere in pixels based on + // the current model, view, + projection matrices and viewport. + virtual float ComputePixelDiameterOfSphere( const Vector& vecAbsOrigin, float flRadius ) = 0; + + // By default, the material system applies the VIEW and PROJECTION matrices to the user clip + // planes (which are specified in world space) to generate projection-space user clip planes + // Occasionally (for the particle system in hl2, for example), we want to override that + // behavior and explictly specify a ViewProj transform for user clip planes + virtual void EnableUserClipTransformOverride( bool bEnable ) = 0; + virtual void UserClipTransform( const VMatrix &worldToView ) = 0; + + virtual bool GetFlashlightMode() const = 0; + + // Used to make the handle think it's never had a successful query before + virtual void ResetOcclusionQueryObject( OcclusionQueryObjectHandle_t ) = 0; + + // FIXME: Remove + virtual void Unused3() {} + + // Creates/destroys morph data associated w/ a particular material + virtual IMorph *CreateMorph( MorphFormat_t format, const char *pDebugName ) = 0; + virtual void DestroyMorph( IMorph *pMorph ) = 0; + + // Binds the morph data for use in rendering + virtual void BindMorph( IMorph *pMorph ) = 0; + + // Sets flexweights for rendering + virtual void SetFlexWeights( int nFirstWeight, int nCount, const MorphWeight_t* pWeights ) = 0; + + // FIXME: Remove + virtual void Unused4() {}; + virtual void Unused5() {}; + virtual void Unused6() {}; + virtual void Unused7() {}; + virtual void Unused8() {}; + + // Read w/ stretch to a host-memory buffer + virtual void ReadPixelsAndStretch( Rect_t *pSrcRect, Rect_t *pDstRect, unsigned char *pBuffer, ImageFormat dstFormat, int nDstStride ) = 0; + + // Gets the window size + virtual void GetWindowSize( int &width, int &height ) const = 0; + + // This function performs a texture map from one texture map to the render destination, doing + // all the necessary pixel/texel coordinate fix ups. fractional values can be used for the + // src_texture coordinates to get linear sampling - integer values should produce 1:1 mappings + // for non-scaled operations. + virtual void DrawScreenSpaceRectangle( + IMaterial *pMaterial, + int destx, int desty, + int width, int height, + float src_texture_x0, float src_texture_y0, // which texel you want to appear at + // destx/y + float src_texture_x1, float src_texture_y1, // which texel you want to appear at + // destx+width-1, desty+height-1 + int src_texture_width, int src_texture_height, // needed for fixup + void *pClientRenderable = NULL, + int nXDice = 1, + int nYDice = 1 )=0; + + virtual void LoadBoneMatrix( int boneIndex, const matrix3x4_t& matrix ) = 0; + + // This version will push the current rendertarget + current viewport onto the stack + virtual void PushRenderTargetAndViewport( ) = 0; + + // This version will push a new rendertarget + a maximal viewport for that rendertarget onto the stack + virtual void PushRenderTargetAndViewport( ITexture *pTexture ) = 0; + + // This version will push a new rendertarget + a specified viewport onto the stack + virtual void PushRenderTargetAndViewport( ITexture *pTexture, int nViewX, int nViewY, int nViewW, int nViewH ) = 0; + + // This version will push a new rendertarget + a specified viewport onto the stack + virtual void PushRenderTargetAndViewport( ITexture *pTexture, ITexture *pDepthTexture, int nViewX, int nViewY, int nViewW, int nViewH ) = 0; + + // This will pop a rendertarget + viewport + virtual void PopRenderTargetAndViewport( void ) = 0; + + // Binds a particular texture as the current lightmap + virtual void BindLightmapTexture( ITexture *pLightmapTexture ) = 0; + + // 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 ) = 0; + virtual void CopyTextureToRenderTargetEx( int nRenderTargetID, ITexture *pTexture, Rect_t *pSrcRect, Rect_t *pDstRect = NULL ) = 0; + + // Special off-center perspective matrix for DoF, MSAA jitter and poster rendering + virtual void PerspectiveOffCenterX( double fovx, double aspect, double zNear, double zFar, double bottom, double top, double left, double right ) = 0; + + // Rendering parameters control special drawing modes withing the material system, shader + // system, shaders, and engine. renderparm.h has their definitions. + virtual void SetFloatRenderingParameter(int parm_number, float value) = 0; + virtual void SetIntRenderingParameter(int parm_number, int value) = 0; + virtual void SetVectorRenderingParameter(int parm_number, Vector const &value) = 0; + + // stencil buffer operations. + virtual void SetStencilEnable(bool onoff) = 0; + virtual void SetStencilFailOperation(StencilOperation_t op) = 0; + virtual void SetStencilZFailOperation(StencilOperation_t op) = 0; + virtual void SetStencilPassOperation(StencilOperation_t op) = 0; + virtual void SetStencilCompareFunction(StencilComparisonFunction_t cmpfn) = 0; + virtual void SetStencilReferenceValue(int ref) = 0; + virtual void SetStencilTestMask(uint32 msk) = 0; + virtual void SetStencilWriteMask(uint32 msk) = 0; + virtual void ClearStencilBufferRectangle(int xmin, int ymin, int xmax, int ymax,int value) =0; + + virtual void SetRenderTargetEx( int nRenderTargetID, ITexture *pTexture ) = 0; + + // rendering clip planes, beware that only the most recently pushed plane will actually be used in a sizeable chunk of hardware configurations + // and that changes to the clip planes mid-frame while UsingFastClipping() is true will result unresolvable depth inconsistencies + virtual void PushCustomClipPlane( const float *pPlane ) = 0; + virtual void PopCustomClipPlane( void ) = 0; + + // Returns the number of vertices + indices we can render using the dynamic mesh + // Passing true in the second parameter will return the max # of vertices + indices + // we can use before a flush is provoked and may return different values + // if called multiple times in succession. + // Passing false into the second parameter will return + // the maximum possible vertices + indices that can be rendered in a single batch + virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ) = 0; + + // Returns the max possible vertices + indices to render in a single draw call + virtual int GetMaxVerticesToRender( IMaterial *pMaterial ) = 0; + virtual int GetMaxIndicesToRender( ) = 0; + virtual void DisableAllLocalLights() = 0; + virtual int CompareMaterialCombos( IMaterial *pMaterial1, IMaterial *pMaterial2, int lightMapID1, int lightMapID2 ) = 0; + + virtual IMesh *GetFlexMesh() = 0; + + virtual void SetFlashlightStateEx( const FlashlightState_t &state, const VMatrix &worldToTexture, ITexture *pFlashlightDepthTexture ) = 0; + + // Returns the currently bound local cubemap + virtual ITexture *GetLocalCubemap( ) = 0; + + // This is a version of clear buffers which will only clear the buffer at pixels which pass the stencil test + virtual void ClearBuffersObeyStencil( bool bClearColor, bool bClearDepth ) = 0; + + //enables/disables all entered clipping planes, returns the input from the last time it was called. + virtual bool EnableClipping( bool bEnable ) = 0; + + //get fog distances entered with FogStart(), FogEnd(), and SetFogZ() + virtual void GetFogDistances( float *fStart, float *fEnd, float *fFogZ ) = 0; + + // Hooks for firing PIX events from outside the Material System... + virtual void BeginPIXEvent( unsigned long color, const char *szName ) = 0; + virtual void EndPIXEvent() = 0; + virtual void SetPIXMarker( unsigned long color, const char *szName ) = 0; + + // Batch API + // from changelist 166623: + // - replaced obtuse material system batch usage with an explicit and easier to thread API + virtual void BeginBatch( IMesh* pIndices ) = 0; + virtual void BindBatch( IMesh* pVertices, IMaterial *pAutoBind = NULL ) = 0; + virtual void DrawBatch(int firstIndex, int numIndices ) = 0; + virtual void EndBatch() = 0; + + // Raw access to the call queue, which can be NULL if not in a queued mode + virtual ICallQueue *GetCallQueue() = 0; + + // Returns the world-space camera position + virtual void GetWorldSpaceCameraPosition( Vector *pCameraPos ) = 0; + virtual void GetWorldSpaceCameraVectors( Vector *pVecForward, Vector *pVecRight, Vector *pVecUp ) = 0; + + // Tone mapping + virtual void ResetToneMappingScale( float monoscale) = 0; // set scale to monoscale instantly with no chasing + virtual void SetGoalToneMappingScale( float monoscale) = 0; // set scale to monoscale instantly with no chasing + + // call TurnOnToneMapping before drawing the 3d scene to get the proper interpolated brightness + // value set. + virtual void TurnOnToneMapping() = 0; + + // Set a linear vector color scale for all 3D rendering. + // A value of [1.0f, 1.0f, 1.0f] should match non-tone-mapped rendering. + virtual void SetToneMappingScaleLinear( const Vector &scale ) = 0; + + virtual Vector GetToneMappingScaleLinear( void ) = 0; + virtual void SetShadowDepthBiasFactors( float fSlopeScaleDepthBias, float fDepthBias ) = 0; + + // Apply stencil operations to every pixel on the screen without disturbing depth or color buffers + virtual void PerformFullScreenStencilOperation( void ) = 0; + + // Sets lighting origin for the current model (needed to convert directional lights to points) + virtual void SetLightingOrigin( Vector vLightingOrigin ) = 0; + + // Set scissor rect for rendering + virtual void SetScissorRect( const int nLeft, const int nTop, const int nRight, const int nBottom, const bool bEnableScissor ) = 0; + + // Methods used to build the morph accumulator that is read from when HW morph<ing is enabled. + virtual void BeginMorphAccumulation() = 0; + virtual void EndMorphAccumulation() = 0; + virtual void AccumulateMorph( IMorph* pMorph, int nMorphCount, const MorphWeight_t* pWeights ) = 0; + + virtual void PushDeformation( DeformationBase_t const *Deformation ) = 0; + virtual void PopDeformation( ) = 0; + virtual int GetNumActiveDeformations() const = 0; + + virtual bool GetMorphAccumulatorTexCoord( Vector2D *pTexCoord, IMorph *pMorph, int nVertex ) = 0; + + // Version of get dynamic mesh that specifies a specific vertex format + virtual IMesh* GetDynamicMeshEx( VertexFormat_t vertexFormat, bool bBuffered = true, + IMesh* pVertexOverride = 0, IMesh* pIndexOverride = 0, IMaterial *pAutoBind = 0 ) = 0; + + virtual void FogMaxDensity( float flMaxDensity ) = 0; + +#if defined( _X360 ) + //Seems best to expose GPR allocation to scene rendering code. 128 total to split between vertex/pixel shaders (pixel will be set to 128 - vertex). Minimum value of 16. More GPR's = more threads. + virtual void PushVertexShaderGPRAllocation( int iVertexShaderCount = 64 ) = 0; + virtual void PopVertexShaderGPRAllocation( void ) = 0; +#endif + + virtual IMaterial *GetCurrentMaterial() = 0; + virtual int GetCurrentNumBones() const = 0; + virtual void *GetCurrentProxy() = 0; + + // Color correction related methods.. + // Client cannot call IColorCorrectionSystem directly because it is not thread-safe + // FIXME: Make IColorCorrectionSystem threadsafe? + virtual void EnableColorCorrection( bool bEnable ) = 0; + virtual ColorCorrectionHandle_t AddLookup( const char *pName ) = 0; + virtual bool RemoveLookup( ColorCorrectionHandle_t handle ) = 0; + virtual void LockLookup( ColorCorrectionHandle_t handle ) = 0; + virtual void LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ) = 0; + virtual void UnlockLookup( ColorCorrectionHandle_t handle ) = 0; + virtual void SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ) = 0; + virtual void ResetLookupWeights( ) = 0; + virtual void SetResetable( ColorCorrectionHandle_t handle, bool bResetable ) = 0; + + //There are some cases where it's simply not reasonable to update the full screen depth texture (mostly on PC). + //Use this to mark it as invalid and use a dummy texture for depth reads. + virtual void SetFullScreenDepthTextureValidityFlag( bool bIsValid ) = 0; + + // 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 ) = 0; + virtual void SetNonInteractiveTempFullscreenBuffer( ITexture *pTexture, MaterialNonInteractiveMode_t mode ) = 0; + virtual void EnableNonInteractiveMode( MaterialNonInteractiveMode_t mode ) = 0; + virtual void RefreshFrontBufferNonInteractive() = 0; + // Allocates temp render data. Renderdata goes out of scope at frame end in multicore + // Renderdata goes out of scope after refcount goes to zero in singlecore. + // Locking/unlocking increases + decreases refcount + virtual void * LockRenderData( int nSizeInBytes ) = 0; + virtual void UnlockRenderData( void *pData ) = 0; + + // Typed version. If specified, pSrcData is copied into the locked memory. + template< class E > E* LockRenderDataTyped( int nCount, const E* pSrcData = NULL ); + + // Temp render data gets immediately freed after it's all unlocked in single core. + // This prevents it from being freed + virtual void AddRefRenderData() = 0; + virtual void ReleaseRenderData() = 0; + + // Returns whether a pointer is render data. NOTE: passing NULL returns true + virtual bool IsRenderData( const void *pData ) const = 0; + virtual void PrintfVA( char *fmt, va_list vargs ) = 0; + virtual void Printf( PRINTF_FORMAT_STRING char *fmt, ... ) = 0; + virtual float Knob( char *knobname, float *setvalue = NULL ) = 0; + // Allows us to override the alpha write setting of a material + virtual void OverrideAlphaWriteEnable( bool bEnable, bool bAlphaWriteEnable ) = 0; + virtual void OverrideColorWriteEnable( bool bOverrideEnable, bool bColorWriteEnable ) = 0; + + virtual void ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth ) = 0; +}; + +template< class E > inline E* IMatRenderContext::LockRenderDataTyped( int nCount, const E* pSrcData ) +{ + int nSizeInBytes = nCount * sizeof(E); + E *pDstData = (E*)LockRenderData( nSizeInBytes ); + if ( pSrcData && pDstData ) + { + memcpy( pDstData, pSrcData, nSizeInBytes ); + } + return pDstData; +} + + +//----------------------------------------------------------------------------- +// Utility class for addreffing/releasing render data (prevents freeing on single core) +//----------------------------------------------------------------------------- +class CMatRenderDataReference +{ +public: + CMatRenderDataReference(); + CMatRenderDataReference( IMatRenderContext* pRenderContext ); + ~CMatRenderDataReference(); + void Lock( IMatRenderContext *pRenderContext ); + void Release(); + +private: + IMatRenderContext *m_pRenderContext; +}; + + +inline CMatRenderDataReference::CMatRenderDataReference() +{ + m_pRenderContext = NULL; +} + +inline CMatRenderDataReference::CMatRenderDataReference( IMatRenderContext* pRenderContext ) +{ + m_pRenderContext = NULL; + Lock( pRenderContext ); +} + +inline CMatRenderDataReference::~CMatRenderDataReference() +{ + Release(); +} + +inline void CMatRenderDataReference::Lock( IMatRenderContext* pRenderContext ) +{ + if ( !m_pRenderContext ) + { + m_pRenderContext = pRenderContext; + m_pRenderContext->AddRefRenderData( ); + } +} + +inline void CMatRenderDataReference::Release() +{ + if ( m_pRenderContext ) + { + m_pRenderContext->ReleaseRenderData( ); + m_pRenderContext = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Utility class for locking/unlocking render data +//----------------------------------------------------------------------------- +template< typename E > +class CMatRenderData +{ +public: + CMatRenderData( IMatRenderContext* pRenderContext ); + CMatRenderData( IMatRenderContext* pRenderContext, int nCount, const E *pSrcData = NULL ); + ~CMatRenderData(); + E* Lock( int nCount, const E* pSrcData = NULL ); + void Release(); + bool IsValid() const; + const E* Base() const; + E* Base(); + const E& operator[]( int i ) const; + E& operator[]( int i ); + +private: + IMatRenderContext* m_pRenderContext; + E *m_pRenderData; + int m_nCount; + bool m_bNeedsUnlock; +}; + +template< typename E > +inline CMatRenderData<E>::CMatRenderData( IMatRenderContext* pRenderContext ) +{ + m_pRenderContext = pRenderContext; + m_nCount = 0; + m_pRenderData = 0; + m_bNeedsUnlock = false; +} + +template< typename E > +inline CMatRenderData<E>::CMatRenderData( IMatRenderContext* pRenderContext, int nCount, const E* pSrcData ) +{ + m_pRenderContext = pRenderContext; + m_nCount = 0; + m_pRenderData = 0; + m_bNeedsUnlock = false; + Lock( nCount, pSrcData ); +} + +template< typename E > +inline CMatRenderData<E>::~CMatRenderData() +{ + Release(); +} + +template< typename E > +inline bool CMatRenderData<E>::IsValid() const +{ + return m_pRenderData != NULL; +} + +template< typename E > +inline E* CMatRenderData<E>::Lock( int nCount, const E* pSrcData ) +{ + m_nCount = nCount; + if ( pSrcData && m_pRenderContext->IsRenderData( pSrcData ) ) + { + // Yes, we're const-casting away, but that should be ok since + // the src data is render data + m_pRenderData = const_cast<E*>( pSrcData ); + m_pRenderContext->AddRefRenderData(); + m_bNeedsUnlock = false; + return m_pRenderData; + } + m_pRenderData = m_pRenderContext->LockRenderDataTyped<E>( nCount, pSrcData ); + m_bNeedsUnlock = true; + return m_pRenderData; +} + +template< typename E > +inline void CMatRenderData<E>::Release() +{ + if ( m_pRenderContext && m_pRenderData ) + { + if ( m_bNeedsUnlock ) + { + m_pRenderContext->UnlockRenderData( m_pRenderData ); + } + else + { + m_pRenderContext->ReleaseRenderData(); + } + } + m_pRenderData = NULL; + m_nCount = 0; + m_bNeedsUnlock = false; +} + +template< typename E > +inline E* CMatRenderData<E>::Base() +{ + return m_pRenderData; +} + +template< typename E > +inline const E* CMatRenderData<E>::Base() const +{ + return m_pRenderData; +} + +template< typename E > +inline E& CMatRenderData<E>::operator[]( int i ) +{ + Assert( ( i >= 0 ) && ( i < m_nCount ) ); + return m_pRenderData[i]; +} + +template< typename E > +inline const E& CMatRenderData<E>::operator[]( int i ) const +{ + Assert( ( i >= 0 ) && ( i < m_nCount ) ); + return m_pRenderData[i]; +} + + +//----------------------------------------------------------------------------- + +class CMatRenderContextPtr : public CRefPtr<IMatRenderContext> +{ + typedef CRefPtr<IMatRenderContext> BaseClass; +public: + CMatRenderContextPtr() {} + CMatRenderContextPtr( IMatRenderContext *pInit ) : BaseClass( pInit ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->BeginRender(); } + CMatRenderContextPtr( IMaterialSystem *pFrom ) : BaseClass( pFrom->GetRenderContext() ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->BeginRender(); } + ~CMatRenderContextPtr() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); } + + IMatRenderContext *operator=( IMatRenderContext *p ) { if ( p ) p->BeginRender(); return BaseClass::operator=( p ); } + + void SafeRelease() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); BaseClass::SafeRelease(); } + void AssignAddRef( IMatRenderContext *pFrom ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); BaseClass::AssignAddRef( pFrom ); BaseClass::m_pObject->BeginRender(); } + + void GetFrom( IMaterialSystem *pFrom ) { AssignAddRef( pFrom->GetRenderContext() ); } + + +private: + CMatRenderContextPtr( const CMatRenderContextPtr &from ); + void operator=( const CMatRenderContextPtr &from ); + +}; + +//----------------------------------------------------------------------------- +// Helper class for begin/end of pix event via constructor/destructor +//----------------------------------------------------------------------------- +#define PIX_VALVE_ORANGE 0xFFF5940F + +class PIXEvent +{ +public: + PIXEvent( IMatRenderContext *pRenderContext, const char *szName, unsigned long color = PIX_VALVE_ORANGE ) + { + m_pRenderContext = pRenderContext; + Assert( m_pRenderContext ); + Assert( szName ); + m_pRenderContext->BeginPIXEvent( color, szName ); + } + ~PIXEvent() + { + m_pRenderContext->EndPIXEvent(); + } +private: + IMatRenderContext *m_pRenderContext; +}; + + +// Also be sure to enable PIX_INSTRUMENTATION in shaderdevicedx8.h +//#define PIX_ENABLE 1 // set this to 1 and build engine/studiorender to enable pix events in the engine + +#if PIX_ENABLE +# define PIXEVENT PIXEvent _pixEvent +#else +# define PIXEVENT +#endif + +//----------------------------------------------------------------------------- + +#ifdef MATERIAL_SYSTEM_DEBUG_CALL_QUEUE +#include "tier1/callqueue.h" +#include "tier1/fmtstr.h" +static void DoMatSysQueueMark( IMaterialSystem *pMaterialSystem, const char *psz ) +{ + CMatRenderContextPtr pRenderContext( pMaterialSystem ); + if ( pRenderContext->GetCallQueue() ) + pRenderContext->GetCallQueue()->QueueCall( Plat_DebugString, CUtlEnvelope<const char *>( psz ) ); +} + +#define MatSysQueueMark( pMaterialSystem, ...) DoMatSysQueueMark( pMaterialSystem, CFmtStr( __VA_ARGS__ ) ) +#else +#define MatSysQueueMark( msg, ...) ((void)0) +#endif + +//----------------------------------------------------------------------------- + +extern IMaterialSystem *materials; +extern IMaterialSystem *g_pMaterialSystem; + +#endif // IMATERIALSYSTEM_H diff --git a/mp/src/public/materialsystem/imaterialsystemhardwareconfig.h b/mp/src/public/materialsystem/imaterialsystemhardwareconfig.h index 4aef4228..699b9bdf 100644 --- a/mp/src/public/materialsystem/imaterialsystemhardwareconfig.h +++ b/mp/src/public/materialsystem/imaterialsystemhardwareconfig.h @@ -1,212 +1,212 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $Header: $
-// $NoKeywords: $
-//===========================================================================//
-
-#ifndef IMATERIALSYSTEMHARDWARECONFIG_H
-#define IMATERIALSYSTEMHARDWARECONFIG_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#include "tier1/interface.h"
-
-//-----------------------------------------------------------------------------
-// GL helpers
-//-----------------------------------------------------------------------------
-FORCEINLINE bool IsEmulatingGL()
-{
- static bool bIsEmulatingGL = ( Plat_GetCommandLineA() ) ? ( strstr( Plat_GetCommandLineA(), "-r_emulate_gl" ) != NULL ) : false;
- return bIsEmulatingGL;
-}
-
-FORCEINLINE bool IsOpenGL( void )
-{
- return IsPlatformOpenGL() || IsEmulatingGL();
-}
-
-//-----------------------------------------------------------------------------
-// Material system interface version
-//-----------------------------------------------------------------------------
-#define MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION "MaterialSystemHardwareConfig012"
-
-// HDRFIXME NOTE: must match common_ps_fxc.h
-enum HDRType_t
-{
- HDR_TYPE_NONE,
- HDR_TYPE_INTEGER,
- HDR_TYPE_FLOAT,
-};
-
-// For now, vertex compression is simply "on or off" (for the sake of simplicity
-// and MeshBuilder perf.), but later we may support multiple flavours.
-enum VertexCompressionType_t
-{
- // This indicates an uninitialized VertexCompressionType_t value
- VERTEX_COMPRESSION_INVALID = 0xFFFFFFFF,
-
- // 'VERTEX_COMPRESSION_NONE' means that no elements of a vertex are compressed
- VERTEX_COMPRESSION_NONE = 0,
-
- // Currently (more stuff may be added as needed), 'VERTEX_COMPRESSION_ON' means:
- // - if a vertex contains VERTEX_ELEMENT_NORMAL, this is compressed
- // (see CVertexBuilder::CompressedNormal3f)
- // - if a vertex contains VERTEX_ELEMENT_USERDATA4 (and a normal - together defining a tangent
- // frame, with the binormal reconstructed in the vertex shader), this is compressed
- // (see CVertexBuilder::CompressedUserData)
- // - if a vertex contains VERTEX_ELEMENT_BONEWEIGHTSx, this is compressed
- // (see CVertexBuilder::CompressedBoneWeight3fv)
- VERTEX_COMPRESSION_ON = 1
-};
-
-
-// use DEFCONFIGMETHOD to define time-critical methods that we want to make just return constants
-// on the 360, so that the checks will happen at compile time. Not all methods are defined this way
-// - just the ones that I perceive as being called often in the frame interval.
-#ifdef _X360
-#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \
-FORCEINLINE ret_type method const \
-{ \
- return xbox_return_value; \
-}
-
-
-#else
-#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \
-virtual ret_type method const = 0;
-#endif
-
-
-
-//-----------------------------------------------------------------------------
-// Material system configuration
-//-----------------------------------------------------------------------------
-class IMaterialSystemHardwareConfig
-{
-public:
- // on xbox, some methods are inlined to return constants
-
- DEFCONFIGMETHOD( bool, HasDestAlphaBuffer(), true );
- DEFCONFIGMETHOD( bool, HasStencilBuffer(), true );
- virtual int GetFrameBufferColorDepth() const = 0;
- virtual int GetSamplerCount() const = 0;
- virtual bool HasSetDeviceGammaRamp() const = 0;
- DEFCONFIGMETHOD( bool, SupportsCompressedTextures(), true );
- virtual VertexCompressionType_t SupportsCompressedVertices() const = 0;
- DEFCONFIGMETHOD( bool, SupportsNormalMapCompression(), true );
- DEFCONFIGMETHOD( bool, SupportsVertexAndPixelShaders(), true );
- DEFCONFIGMETHOD( bool, SupportsPixelShaders_1_4(), true );
- DEFCONFIGMETHOD( bool, SupportsStaticControlFlow(), true );
- DEFCONFIGMETHOD( bool, SupportsPixelShaders_2_0(), true );
- DEFCONFIGMETHOD( bool, SupportsVertexShaders_2_0(), true );
- virtual int MaximumAnisotropicLevel() const = 0; // 0 means no anisotropic filtering
- virtual int MaxTextureWidth() const = 0;
- virtual int MaxTextureHeight() const = 0;
- virtual int TextureMemorySize() const = 0;
- virtual bool SupportsOverbright() const = 0;
- virtual bool SupportsCubeMaps() const = 0;
- virtual bool SupportsMipmappedCubemaps() const = 0;
- virtual bool SupportsNonPow2Textures() const = 0;
-
- // The number of texture stages represents the number of computations
- // we can do in the fixed-function pipeline, it is *not* related to the
- // simultaneous number of textures we can use
- virtual int GetTextureStageCount() const = 0;
- virtual int NumVertexShaderConstants() const = 0;
- virtual int NumPixelShaderConstants() const = 0;
- virtual int MaxNumLights() const = 0;
- virtual bool SupportsHardwareLighting() const = 0;
- virtual int MaxBlendMatrices() const = 0;
- virtual int MaxBlendMatrixIndices() const = 0;
- virtual int MaxTextureAspectRatio() const = 0;
- virtual int MaxVertexShaderBlendMatrices() const = 0;
- virtual int MaxUserClipPlanes() const = 0;
- virtual bool UseFastClipping() const = 0;
-
- // This here should be the major item looked at when checking for compat
- // from anywhere other than the material system shaders
- DEFCONFIGMETHOD( int, GetDXSupportLevel(), 98 );
- virtual const char *GetShaderDLLName() const = 0;
-
- virtual bool ReadPixelsFromFrontBuffer() const = 0;
-
- // Are dx dynamic textures preferred?
- virtual bool PreferDynamicTextures() const = 0;
-
- DEFCONFIGMETHOD( bool, SupportsHDR(), true );
-
- virtual bool HasProjectedBumpEnv() const = 0;
- virtual bool SupportsSpheremapping() const = 0;
- virtual bool NeedsAAClamp() const = 0;
- virtual bool NeedsATICentroidHack() const = 0;
-
- virtual bool SupportsColorOnSecondStream() const = 0;
- virtual bool SupportsStaticPlusDynamicLighting() const = 0;
-
- // Does our card have a hard time with fillrate
- // relative to other cards w/ the same dx level?
- virtual bool PreferReducedFillrate() const = 0;
-
- // This is the max dx support level supported by the card
- virtual int GetMaxDXSupportLevel() const = 0;
-
- // Does the card specify fog color in linear space when sRGBWrites are enabled?
- virtual bool SpecifiesFogColorInLinearSpace() const = 0;
-
- // Does the card support sRGB reads/writes?
- DEFCONFIGMETHOD( bool, SupportsSRGB(), true );
- DEFCONFIGMETHOD( bool, FakeSRGBWrite(), false );
- DEFCONFIGMETHOD( bool, CanDoSRGBReadFromRTs(), true );
-
- virtual bool SupportsGLMixedSizeTargets() const = 0;
-
- virtual bool IsAAEnabled() const = 0; // Is antialiasing being used?
-
- // NOTE: Anything after this was added after shipping HL2.
- virtual int GetVertexTextureCount() const = 0;
- virtual int GetMaxVertexTextureDimension() const = 0;
-
- virtual int MaxTextureDepth() const = 0;
-
- virtual HDRType_t GetHDRType() const = 0;
- virtual HDRType_t GetHardwareHDRType() const = 0;
-
- DEFCONFIGMETHOD( bool, SupportsPixelShaders_2_b(), true );
- virtual bool SupportsStreamOffset() const = 0;
-
- virtual int StencilBufferBits() const = 0;
- virtual int MaxViewports() const = 0;
-
- virtual void OverrideStreamOffsetSupport( bool bOverrideEnabled, bool bEnableSupport ) = 0;
-
- virtual int GetShadowFilterMode() const = 0;
-
- virtual int NeedsShaderSRGBConversion() const = 0;
-
- DEFCONFIGMETHOD( bool, UsesSRGBCorrectBlending(), true );
-
- virtual bool SupportsShaderModel_3_0() const = 0;
- virtual bool HasFastVertexTextures() const = 0;
- virtual int MaxHWMorphBatchCount() const = 0;
-
- // Does the board actually support this?
- DEFCONFIGMETHOD( bool, ActuallySupportsPixelShaders_2_b(), true );
-
- virtual bool SupportsHDRMode( HDRType_t nHDRMode ) const = 0;
-
- virtual bool GetHDREnabled( void ) const = 0;
- virtual void SetHDREnabled( bool bEnable ) = 0;
-
- virtual bool SupportsBorderColor( void ) const = 0;
- virtual bool SupportsFetch4( void ) const = 0;
-
- inline bool ShouldAlwaysUseShaderModel2bShaders() const { return IsOpenGL(); }
- inline bool PlatformRequiresNonNullPixelShaders() const { return IsOpenGL(); }
-};
-
-#endif // IMATERIALSYSTEMHARDWARECONFIG_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#ifndef IMATERIALSYSTEMHARDWARECONFIG_H +#define IMATERIALSYSTEMHARDWARECONFIG_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier1/interface.h" + +//----------------------------------------------------------------------------- +// GL helpers +//----------------------------------------------------------------------------- +FORCEINLINE bool IsEmulatingGL() +{ + static bool bIsEmulatingGL = ( Plat_GetCommandLineA() ) ? ( strstr( Plat_GetCommandLineA(), "-r_emulate_gl" ) != NULL ) : false; + return bIsEmulatingGL; +} + +FORCEINLINE bool IsOpenGL( void ) +{ + return IsPlatformOpenGL() || IsEmulatingGL(); +} + +//----------------------------------------------------------------------------- +// Material system interface version +//----------------------------------------------------------------------------- +#define MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION "MaterialSystemHardwareConfig012" + +// HDRFIXME NOTE: must match common_ps_fxc.h +enum HDRType_t +{ + HDR_TYPE_NONE, + HDR_TYPE_INTEGER, + HDR_TYPE_FLOAT, +}; + +// For now, vertex compression is simply "on or off" (for the sake of simplicity +// and MeshBuilder perf.), but later we may support multiple flavours. +enum VertexCompressionType_t +{ + // This indicates an uninitialized VertexCompressionType_t value + VERTEX_COMPRESSION_INVALID = 0xFFFFFFFF, + + // 'VERTEX_COMPRESSION_NONE' means that no elements of a vertex are compressed + VERTEX_COMPRESSION_NONE = 0, + + // Currently (more stuff may be added as needed), 'VERTEX_COMPRESSION_ON' means: + // - if a vertex contains VERTEX_ELEMENT_NORMAL, this is compressed + // (see CVertexBuilder::CompressedNormal3f) + // - if a vertex contains VERTEX_ELEMENT_USERDATA4 (and a normal - together defining a tangent + // frame, with the binormal reconstructed in the vertex shader), this is compressed + // (see CVertexBuilder::CompressedUserData) + // - if a vertex contains VERTEX_ELEMENT_BONEWEIGHTSx, this is compressed + // (see CVertexBuilder::CompressedBoneWeight3fv) + VERTEX_COMPRESSION_ON = 1 +}; + + +// use DEFCONFIGMETHOD to define time-critical methods that we want to make just return constants +// on the 360, so that the checks will happen at compile time. Not all methods are defined this way +// - just the ones that I perceive as being called often in the frame interval. +#ifdef _X360 +#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \ +FORCEINLINE ret_type method const \ +{ \ + return xbox_return_value; \ +} + + +#else +#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \ +virtual ret_type method const = 0; +#endif + + + +//----------------------------------------------------------------------------- +// Material system configuration +//----------------------------------------------------------------------------- +class IMaterialSystemHardwareConfig +{ +public: + // on xbox, some methods are inlined to return constants + + DEFCONFIGMETHOD( bool, HasDestAlphaBuffer(), true ); + DEFCONFIGMETHOD( bool, HasStencilBuffer(), true ); + virtual int GetFrameBufferColorDepth() const = 0; + virtual int GetSamplerCount() const = 0; + virtual bool HasSetDeviceGammaRamp() const = 0; + DEFCONFIGMETHOD( bool, SupportsCompressedTextures(), true ); + virtual VertexCompressionType_t SupportsCompressedVertices() const = 0; + DEFCONFIGMETHOD( bool, SupportsNormalMapCompression(), true ); + DEFCONFIGMETHOD( bool, SupportsVertexAndPixelShaders(), true ); + DEFCONFIGMETHOD( bool, SupportsPixelShaders_1_4(), true ); + DEFCONFIGMETHOD( bool, SupportsStaticControlFlow(), true ); + DEFCONFIGMETHOD( bool, SupportsPixelShaders_2_0(), true ); + DEFCONFIGMETHOD( bool, SupportsVertexShaders_2_0(), true ); + virtual int MaximumAnisotropicLevel() const = 0; // 0 means no anisotropic filtering + virtual int MaxTextureWidth() const = 0; + virtual int MaxTextureHeight() const = 0; + virtual int TextureMemorySize() const = 0; + virtual bool SupportsOverbright() const = 0; + virtual bool SupportsCubeMaps() const = 0; + virtual bool SupportsMipmappedCubemaps() const = 0; + virtual bool SupportsNonPow2Textures() const = 0; + + // The number of texture stages represents the number of computations + // we can do in the fixed-function pipeline, it is *not* related to the + // simultaneous number of textures we can use + virtual int GetTextureStageCount() const = 0; + virtual int NumVertexShaderConstants() const = 0; + virtual int NumPixelShaderConstants() const = 0; + virtual int MaxNumLights() const = 0; + virtual bool SupportsHardwareLighting() const = 0; + virtual int MaxBlendMatrices() const = 0; + virtual int MaxBlendMatrixIndices() const = 0; + virtual int MaxTextureAspectRatio() const = 0; + virtual int MaxVertexShaderBlendMatrices() const = 0; + virtual int MaxUserClipPlanes() const = 0; + virtual bool UseFastClipping() const = 0; + + // This here should be the major item looked at when checking for compat + // from anywhere other than the material system shaders + DEFCONFIGMETHOD( int, GetDXSupportLevel(), 98 ); + virtual const char *GetShaderDLLName() const = 0; + + virtual bool ReadPixelsFromFrontBuffer() const = 0; + + // Are dx dynamic textures preferred? + virtual bool PreferDynamicTextures() const = 0; + + DEFCONFIGMETHOD( bool, SupportsHDR(), true ); + + virtual bool HasProjectedBumpEnv() const = 0; + virtual bool SupportsSpheremapping() const = 0; + virtual bool NeedsAAClamp() const = 0; + virtual bool NeedsATICentroidHack() const = 0; + + virtual bool SupportsColorOnSecondStream() const = 0; + virtual bool SupportsStaticPlusDynamicLighting() const = 0; + + // Does our card have a hard time with fillrate + // relative to other cards w/ the same dx level? + virtual bool PreferReducedFillrate() const = 0; + + // This is the max dx support level supported by the card + virtual int GetMaxDXSupportLevel() const = 0; + + // Does the card specify fog color in linear space when sRGBWrites are enabled? + virtual bool SpecifiesFogColorInLinearSpace() const = 0; + + // Does the card support sRGB reads/writes? + DEFCONFIGMETHOD( bool, SupportsSRGB(), true ); + DEFCONFIGMETHOD( bool, FakeSRGBWrite(), false ); + DEFCONFIGMETHOD( bool, CanDoSRGBReadFromRTs(), true ); + + virtual bool SupportsGLMixedSizeTargets() const = 0; + + virtual bool IsAAEnabled() const = 0; // Is antialiasing being used? + + // NOTE: Anything after this was added after shipping HL2. + virtual int GetVertexTextureCount() const = 0; + virtual int GetMaxVertexTextureDimension() const = 0; + + virtual int MaxTextureDepth() const = 0; + + virtual HDRType_t GetHDRType() const = 0; + virtual HDRType_t GetHardwareHDRType() const = 0; + + DEFCONFIGMETHOD( bool, SupportsPixelShaders_2_b(), true ); + virtual bool SupportsStreamOffset() const = 0; + + virtual int StencilBufferBits() const = 0; + virtual int MaxViewports() const = 0; + + virtual void OverrideStreamOffsetSupport( bool bOverrideEnabled, bool bEnableSupport ) = 0; + + virtual int GetShadowFilterMode() const = 0; + + virtual int NeedsShaderSRGBConversion() const = 0; + + DEFCONFIGMETHOD( bool, UsesSRGBCorrectBlending(), true ); + + virtual bool SupportsShaderModel_3_0() const = 0; + virtual bool HasFastVertexTextures() const = 0; + virtual int MaxHWMorphBatchCount() const = 0; + + // Does the board actually support this? + DEFCONFIGMETHOD( bool, ActuallySupportsPixelShaders_2_b(), true ); + + virtual bool SupportsHDRMode( HDRType_t nHDRMode ) const = 0; + + virtual bool GetHDREnabled( void ) const = 0; + virtual void SetHDREnabled( bool bEnable ) = 0; + + virtual bool SupportsBorderColor( void ) const = 0; + virtual bool SupportsFetch4( void ) const = 0; + + inline bool ShouldAlwaysUseShaderModel2bShaders() const { return IsOpenGL(); } + inline bool PlatformRequiresNonNullPixelShaders() const { return IsOpenGL(); } +}; + +#endif // IMATERIALSYSTEMHARDWARECONFIG_H diff --git a/mp/src/public/materialsystem/imaterialsystemstub.h b/mp/src/public/materialsystem/imaterialsystemstub.h index 6ff48f35..b289e1b9 100644 --- a/mp/src/public/materialsystem/imaterialsystemstub.h +++ b/mp/src/public/materialsystem/imaterialsystemstub.h @@ -1,31 +1,31 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef IMATERIALSYSTEMSTUB_H
-#define IMATERIALSYSTEMSTUB_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#include "materialsystem/imaterialsystem.h"
-
-
-// If you get this interface out of the material system, it'll return an IMaterialSystem
-// with everything stubbed. This is used for running the client in text mode.
-#define MATERIAL_SYSTEM_STUB_INTERFACE_VERSION "VMaterialSystemStub001"
-
-
-class IMaterialSystemStub : public IMaterialSystem
-{
-public:
- // If this is called, then the stub will call through to the real material
- // system in some functions.
- virtual void SetRealMaterialSystem( IMaterialSystem *pSys ) = 0;
-};
-
-
-#endif // IMATERIALSYSTEMSTUB_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef IMATERIALSYSTEMSTUB_H +#define IMATERIALSYSTEMSTUB_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "materialsystem/imaterialsystem.h" + + +// If you get this interface out of the material system, it'll return an IMaterialSystem +// with everything stubbed. This is used for running the client in text mode. +#define MATERIAL_SYSTEM_STUB_INTERFACE_VERSION "VMaterialSystemStub001" + + +class IMaterialSystemStub : public IMaterialSystem +{ +public: + // If this is called, then the stub will call through to the real material + // system in some functions. + virtual void SetRealMaterialSystem( IMaterialSystem *pSys ) = 0; +}; + + +#endif // IMATERIALSYSTEMSTUB_H diff --git a/mp/src/public/materialsystem/imaterialvar.h b/mp/src/public/materialsystem/imaterialvar.h index 69412e8f..4918d246 100644 --- a/mp/src/public/materialsystem/imaterialvar.h +++ b/mp/src/public/materialsystem/imaterialvar.h @@ -1,245 +1,245 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-
-#ifndef IMATERIALVAR_H
-#define IMATERIALVAR_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-#include "tier1/utlsymbol.h"
-#include "mathlib/vector4d.h"
-class IMaterial;
-class VMatrix;
-class ITexture;
-
-#define MAKE_MATERIALVAR_FOURCC(ch0, ch1, ch2, ch3) \
- ((unsigned long)(ch0) | ((unsigned long)(ch1) << 8) | \
- ((unsigned long)(ch2) << 16) | ((unsigned long)(ch3) << 24 ))
-
-// This fourcc is reserved.
-#define FOURCC_UNKNOWN MAKE_MATERIALVAR_FOURCC('U','N','K','N')
-
-
-//-----------------------------------------------------------------------------
-// Various material var types
-//-----------------------------------------------------------------------------
-enum MaterialVarType_t
-{
- MATERIAL_VAR_TYPE_FLOAT = 0,
- MATERIAL_VAR_TYPE_STRING,
- MATERIAL_VAR_TYPE_VECTOR,
- MATERIAL_VAR_TYPE_TEXTURE,
- MATERIAL_VAR_TYPE_INT,
- MATERIAL_VAR_TYPE_FOURCC,
- MATERIAL_VAR_TYPE_UNDEFINED,
- MATERIAL_VAR_TYPE_MATRIX,
- MATERIAL_VAR_TYPE_MATERIAL,
-};
-
-typedef unsigned short MaterialVarSym_t;
-
-class IMaterialVar
-{
-public:
- typedef unsigned long FourCC;
-
-protected:
- // base data and accessors
- char* m_pStringVal;
- int m_intVal;
- Vector4D m_VecVal;
-
- // member data. total = 4 bytes
- uint8 m_Type : 4;
- uint8 m_nNumVectorComps : 3;
- uint8 m_bFakeMaterialVar : 1;
- uint8 m_nTempIndex;
- CUtlSymbol m_Name;
-
-public:
- // class factory methods
- static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, VMatrix const& matrix );
- static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, char const* pVal );
- static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, float* pVal, int numcomps );
- static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, float val );
- static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, int val );
- static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey );
- static void Destroy( IMaterialVar* pVar );
- static MaterialVarSym_t GetSymbol( char const* pName );
- static MaterialVarSym_t FindSymbol( char const* pName );
- static bool SymbolMatches( char const* pName, MaterialVarSym_t symbol );
- static void DeleteUnreferencedTextures( bool enable );
-
- virtual ITexture *GetTextureValue( void ) = 0;
-
- virtual char const * GetName( void ) const = 0;
- virtual MaterialVarSym_t GetNameAsSymbol() const = 0;
-
- virtual void SetFloatValue( float val ) = 0;
-
- virtual void SetIntValue( int val ) = 0;
-
- virtual void SetStringValue( char const *val ) = 0;
- virtual char const * GetStringValue( void ) const = 0;
-
- // 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 ) = 0;
- virtual void GetFourCCValue( FourCC *type, void **ppData ) = 0;
-
- // Vec (dim 2-4)
- virtual void SetVecValue( float const* val, int numcomps ) = 0;
- virtual void SetVecValue( float x, float y ) = 0;
- virtual void SetVecValue( float x, float y, float z ) = 0;
- virtual void SetVecValue( float x, float y, float z, float w ) = 0;
- virtual void GetLinearVecValue( float *val, int numcomps ) const = 0;
-
- // revisit: is this a good interface for textures?
- virtual void SetTextureValue( ITexture * ) = 0;
-
- virtual IMaterial * GetMaterialValue( void ) = 0;
- virtual void SetMaterialValue( IMaterial * ) = 0;
-
- virtual bool IsDefined() const = 0;
- virtual void SetUndefined() = 0;
-
- // Matrix
- virtual void SetMatrixValue( VMatrix const& matrix ) = 0;
- virtual const VMatrix &GetMatrixValue( ) = 0;
- virtual bool MatrixIsIdentity() const = 0;
-
- // Copy....
- virtual void CopyFrom( IMaterialVar *pMaterialVar ) = 0;
-
- virtual void SetValueAutodetectType( char const *val ) = 0;
-
- virtual IMaterial * GetOwningMaterial() = 0;
-
- //set just 1 component
- virtual void SetVecComponentValue( float fVal, int nComponent ) = 0;
-
-protected:
- virtual int GetIntValueInternal( void ) const = 0;
- virtual float GetFloatValueInternal( void ) const = 0;
- virtual float const* GetVecValueInternal( ) const = 0;
- virtual void GetVecValueInternal( float *val, int numcomps ) const = 0;
- virtual int VectorSizeInternal() const = 0;
-
-public:
- FORCEINLINE MaterialVarType_t GetType( void ) const
- {
- return ( MaterialVarType_t )m_Type;
- }
-
- FORCEINLINE bool IsTexture() const
- {
- return m_Type == MATERIAL_VAR_TYPE_TEXTURE;
- }
-
- FORCEINLINE operator ITexture*()
- {
- return GetTextureValue();
- }
-
- // NOTE: Fast methods should only be called in thread-safe situations
- FORCEINLINE int GetIntValueFast( void ) const
- {
- // Set methods for float and vector update this
- return m_intVal;
- }
-
- FORCEINLINE float GetFloatValueFast( void ) const
- {
- return m_VecVal[0];
- }
-
- FORCEINLINE float const* GetVecValueFast( ) const
- {
- return m_VecVal.Base();
- }
-
- FORCEINLINE void GetVecValueFast( float *val, int numcomps ) const
- {
- Assert( ( numcomps >0 ) && ( numcomps <= 4 ) );
- for( int i=0 ; i < numcomps; i++ )
- {
- val[i] = m_VecVal[ i ];
- }
- }
-
- FORCEINLINE int VectorSizeFast() const
- {
- return m_nNumVectorComps;
- }
-
-#ifdef FAST_MATERIALVAR_ACCESS
- FORCEINLINE int GetIntValue( void ) const
- {
- return GetIntValueFast();
- }
-
- FORCEINLINE float GetFloatValue( void ) const
- {
- return GetFloatValueFast();
- }
-
- FORCEINLINE float const* GetVecValue( ) const
- {
- return GetVecValueFast();
- }
-
- FORCEINLINE void GetVecValue( float *val, int numcomps ) const
- {
- GetVecValueFast( val, numcomps );
- }
-
- FORCEINLINE int VectorSize() const
- {
- return VectorSizeFast();
- }
-#else // !FAST_MATERIALVAR_ACCESS
- FORCEINLINE int GetIntValue( void ) const
- {
- return GetIntValueInternal();
- }
-
- FORCEINLINE float GetFloatValue( void ) const
- {
- return GetFloatValueInternal();
- }
-
- FORCEINLINE float const* GetVecValue( ) const
- {
- return GetVecValueInternal();
- }
-
- FORCEINLINE void GetVecValue( float *val, int numcomps ) const
- {
- return GetVecValueInternal( val, numcomps );
- }
-
- FORCEINLINE int VectorSize() const
- {
- return VectorSizeInternal();
- }
-#endif
-
-private:
- FORCEINLINE void SetTempIndex( int nIndex )
- {
- m_nTempIndex = nIndex;
- }
-
- friend void EnableThreadedMaterialVarAccess( bool bEnable, IMaterialVar **ppParams, int nVarCount );
-};
-
-#endif // IMATERIALVAR_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef IMATERIALVAR_H +#define IMATERIALVAR_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "tier1/utlsymbol.h" +#include "mathlib/vector4d.h" +class IMaterial; +class VMatrix; +class ITexture; + +#define MAKE_MATERIALVAR_FOURCC(ch0, ch1, ch2, ch3) \ + ((unsigned long)(ch0) | ((unsigned long)(ch1) << 8) | \ + ((unsigned long)(ch2) << 16) | ((unsigned long)(ch3) << 24 )) + +// This fourcc is reserved. +#define FOURCC_UNKNOWN MAKE_MATERIALVAR_FOURCC('U','N','K','N') + + +//----------------------------------------------------------------------------- +// Various material var types +//----------------------------------------------------------------------------- +enum MaterialVarType_t +{ + MATERIAL_VAR_TYPE_FLOAT = 0, + MATERIAL_VAR_TYPE_STRING, + MATERIAL_VAR_TYPE_VECTOR, + MATERIAL_VAR_TYPE_TEXTURE, + MATERIAL_VAR_TYPE_INT, + MATERIAL_VAR_TYPE_FOURCC, + MATERIAL_VAR_TYPE_UNDEFINED, + MATERIAL_VAR_TYPE_MATRIX, + MATERIAL_VAR_TYPE_MATERIAL, +}; + +typedef unsigned short MaterialVarSym_t; + +class IMaterialVar +{ +public: + typedef unsigned long FourCC; + +protected: + // base data and accessors + char* m_pStringVal; + int m_intVal; + Vector4D m_VecVal; + + // member data. total = 4 bytes + uint8 m_Type : 4; + uint8 m_nNumVectorComps : 3; + uint8 m_bFakeMaterialVar : 1; + uint8 m_nTempIndex; + CUtlSymbol m_Name; + +public: + // class factory methods + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, VMatrix const& matrix ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, char const* pVal ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, float* pVal, int numcomps ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, float val ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, int val ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey ); + static void Destroy( IMaterialVar* pVar ); + static MaterialVarSym_t GetSymbol( char const* pName ); + static MaterialVarSym_t FindSymbol( char const* pName ); + static bool SymbolMatches( char const* pName, MaterialVarSym_t symbol ); + static void DeleteUnreferencedTextures( bool enable ); + + virtual ITexture *GetTextureValue( void ) = 0; + + virtual char const * GetName( void ) const = 0; + virtual MaterialVarSym_t GetNameAsSymbol() const = 0; + + virtual void SetFloatValue( float val ) = 0; + + virtual void SetIntValue( int val ) = 0; + + virtual void SetStringValue( char const *val ) = 0; + virtual char const * GetStringValue( void ) const = 0; + + // 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 ) = 0; + virtual void GetFourCCValue( FourCC *type, void **ppData ) = 0; + + // Vec (dim 2-4) + virtual void SetVecValue( float const* val, int numcomps ) = 0; + virtual void SetVecValue( float x, float y ) = 0; + virtual void SetVecValue( float x, float y, float z ) = 0; + virtual void SetVecValue( float x, float y, float z, float w ) = 0; + virtual void GetLinearVecValue( float *val, int numcomps ) const = 0; + + // revisit: is this a good interface for textures? + virtual void SetTextureValue( ITexture * ) = 0; + + virtual IMaterial * GetMaterialValue( void ) = 0; + virtual void SetMaterialValue( IMaterial * ) = 0; + + virtual bool IsDefined() const = 0; + virtual void SetUndefined() = 0; + + // Matrix + virtual void SetMatrixValue( VMatrix const& matrix ) = 0; + virtual const VMatrix &GetMatrixValue( ) = 0; + virtual bool MatrixIsIdentity() const = 0; + + // Copy.... + virtual void CopyFrom( IMaterialVar *pMaterialVar ) = 0; + + virtual void SetValueAutodetectType( char const *val ) = 0; + + virtual IMaterial * GetOwningMaterial() = 0; + + //set just 1 component + virtual void SetVecComponentValue( float fVal, int nComponent ) = 0; + +protected: + virtual int GetIntValueInternal( void ) const = 0; + virtual float GetFloatValueInternal( void ) const = 0; + virtual float const* GetVecValueInternal( ) const = 0; + virtual void GetVecValueInternal( float *val, int numcomps ) const = 0; + virtual int VectorSizeInternal() const = 0; + +public: + FORCEINLINE MaterialVarType_t GetType( void ) const + { + return ( MaterialVarType_t )m_Type; + } + + FORCEINLINE bool IsTexture() const + { + return m_Type == MATERIAL_VAR_TYPE_TEXTURE; + } + + FORCEINLINE operator ITexture*() + { + return GetTextureValue(); + } + + // NOTE: Fast methods should only be called in thread-safe situations + FORCEINLINE int GetIntValueFast( void ) const + { + // Set methods for float and vector update this + return m_intVal; + } + + FORCEINLINE float GetFloatValueFast( void ) const + { + return m_VecVal[0]; + } + + FORCEINLINE float const* GetVecValueFast( ) const + { + return m_VecVal.Base(); + } + + FORCEINLINE void GetVecValueFast( float *val, int numcomps ) const + { + Assert( ( numcomps >0 ) && ( numcomps <= 4 ) ); + for( int i=0 ; i < numcomps; i++ ) + { + val[i] = m_VecVal[ i ]; + } + } + + FORCEINLINE int VectorSizeFast() const + { + return m_nNumVectorComps; + } + +#ifdef FAST_MATERIALVAR_ACCESS + FORCEINLINE int GetIntValue( void ) const + { + return GetIntValueFast(); + } + + FORCEINLINE float GetFloatValue( void ) const + { + return GetFloatValueFast(); + } + + FORCEINLINE float const* GetVecValue( ) const + { + return GetVecValueFast(); + } + + FORCEINLINE void GetVecValue( float *val, int numcomps ) const + { + GetVecValueFast( val, numcomps ); + } + + FORCEINLINE int VectorSize() const + { + return VectorSizeFast(); + } +#else // !FAST_MATERIALVAR_ACCESS + FORCEINLINE int GetIntValue( void ) const + { + return GetIntValueInternal(); + } + + FORCEINLINE float GetFloatValue( void ) const + { + return GetFloatValueInternal(); + } + + FORCEINLINE float const* GetVecValue( ) const + { + return GetVecValueInternal(); + } + + FORCEINLINE void GetVecValue( float *val, int numcomps ) const + { + return GetVecValueInternal( val, numcomps ); + } + + FORCEINLINE int VectorSize() const + { + return VectorSizeInternal(); + } +#endif + +private: + FORCEINLINE void SetTempIndex( int nIndex ) + { + m_nTempIndex = nIndex; + } + + friend void EnableThreadedMaterialVarAccess( bool bEnable, IMaterialVar **ppParams, int nVarCount ); +}; + +#endif // IMATERIALVAR_H diff --git a/mp/src/public/materialsystem/imesh.h b/mp/src/public/materialsystem/imesh.h index 7ee35de9..b71be4d9 100644 --- a/mp/src/public/materialsystem/imesh.h +++ b/mp/src/public/materialsystem/imesh.h @@ -1,4047 +1,4047 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//===========================================================================//
-
-#ifndef IMESH_H
-#define IMESH_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier1/interface.h"
-#include "materialsystem/imaterial.h"
-#include <float.h>
-#include <string.h>
-#include "tier0/dbg.h"
-#include "tier2/meshutils.h"
-#include "mathlib/mathlib.h"
-
-#if defined( DX_TO_GL_ABSTRACTION )
-// Swap these so that we do color swapping on 10.6.2, which doesn't have EXT_vertex_array_bgra
-#define OPENGL_SWAP_COLORS
-#endif
-
-//-----------------------------------------------------------------------------
-// forward declarations
-//-----------------------------------------------------------------------------
-class IMaterial;
-class CMeshBuilder;
-class IMaterialVar;
-typedef uint64 VertexFormat_t;
-
-
-//-----------------------------------------------------------------------------
-// Define this to find write-combine problems
-//-----------------------------------------------------------------------------
-#ifdef _DEBUG
-//#ifndef DEBUG_WRITE_COMBINE
-//#define DEBUG_WRITE_COMBINE 1
-//#endif
-#endif
-
-
-//-----------------------------------------------------------------------------
-// The Vertex Buffer interface
-//-----------------------------------------------------------------------------
-enum
-{
- VERTEX_MAX_TEXTURE_COORDINATES = 8,
- BONE_MATRIX_INDEX_INVALID = 255
-};
-
-// Internal maximums for sizes. Don't use directly, use IMaterialSystem::GetMaxToRender()
-enum
-{
- INDEX_BUFFER_SIZE = 32768,
- DYNAMIC_VERTEX_BUFFER_MEMORY = ( 1024 + 512 ) * 1024,
- DYNAMIC_VERTEX_BUFFER_MEMORY_SMALL = 384 * 1024, // Only allocate this much during map transitions
-};
-
-// Vertex fields must be written in well-defined order to achieve write combining,
-// which is a perf booster
-enum WriteCombineOrdering_t
-{
- MB_FIELD_NONE = -1,
- MB_FIELD_POSITION = 0,
- MB_FIELD_BONE_WEIGHTS,
- MB_FIELD_BONE_INDEX,
- MB_FIELD_NORMAL,
- MB_FIELD_COLOR,
- MB_FIELD_SPECULAR,
- MB_FIELD_TEXCOORD_FIRST,
- MB_FIELD_TEXCOORD_LAST = MB_FIELD_TEXCOORD_FIRST + VERTEX_MAX_TEXTURE_COORDINATES - 1,
- MB_FIELD_TANGENT_S,
- MB_FIELD_TANGENT_T,
- MB_FIELD_USERDATA,
-};
-
-#define MB_FIELD_TEXCOORD( nStage ) ( MB_FIELD_TEXCOORD_FIRST + ( nStage ) )
-
-struct VertexDesc_t
-{
- // These can be set to zero if there are pointers to dummy buffers, when the
- // actual buffer format doesn't contain the data but it needs to be safe to
- // use all the CMeshBuilder functions.
- int m_VertexSize_Position;
- int m_VertexSize_BoneWeight;
- int m_VertexSize_BoneMatrixIndex;
- int m_VertexSize_Normal;
- int m_VertexSize_Color;
- int m_VertexSize_Specular;
- int m_VertexSize_TexCoord[VERTEX_MAX_TEXTURE_COORDINATES];
- int m_VertexSize_TangentS;
- int m_VertexSize_TangentT;
- int m_VertexSize_Wrinkle;
-
- int m_VertexSize_UserData;
-
- int m_ActualVertexSize; // Size of the vertices.. Some of the m_VertexSize_ elements above
- // are set to this value and some are set to zero depending on which
- // fields exist in a buffer's vertex format.
-
- // The type of compression applied to this vertex data
- VertexCompressionType_t m_CompressionType;
-
- // Number of bone weights per vertex...
- int m_NumBoneWeights;
-
- // Pointers to our current vertex data
- float *m_pPosition;
-
- float *m_pBoneWeight;
-
-#ifndef NEW_SKINNING
- unsigned char *m_pBoneMatrixIndex;
-#else
- float *m_pBoneMatrixIndex;
-#endif
-
- float *m_pNormal;
-
- unsigned char *m_pColor;
- unsigned char *m_pSpecular;
- float *m_pTexCoord[VERTEX_MAX_TEXTURE_COORDINATES];
-
- // Tangent space *associated with one particular set of texcoords*
- float *m_pTangentS;
- float *m_pTangentT;
-
- float *m_pWrinkle;
-
- // user data
- float *m_pUserData;
-
- // The first vertex index (used for buffered vertex buffers, or cards that don't support stream offset)
- int m_nFirstVertex;
-
- // The offset in bytes of the memory we're writing into
- // from the start of the D3D buffer (will be 0 for static meshes)
- unsigned int m_nOffset;
-
-#ifdef DEBUG_WRITE_COMBINE
- int m_nLastWrittenField;
- unsigned char* m_pLastWrittenAddress;
-#endif
-};
-
-struct IndexDesc_t
-{
- // Pointers to the index data
- unsigned short *m_pIndices;
-
- // The offset in bytes of the memory we're writing into
- // from the start of the D3D buffer (will be 0 for static meshes)
- unsigned int m_nOffset;
-
- // The first index (used for buffered index buffers, or cards that don't support stream offset)
- unsigned int m_nFirstIndex;
-
- // 1 if the device is active, 0 if the device isn't active.
- // Faster than doing if checks for null m_pIndices if someone is
- // trying to write the m_pIndices while the device is inactive.
- unsigned char m_nIndexSize;
-};
-
-
-//-----------------------------------------------------------------------------
-// The Mesh memory descriptor
-//-----------------------------------------------------------------------------
-struct MeshDesc_t : public VertexDesc_t, public IndexDesc_t
-{
-};
-
-
-//-----------------------------------------------------------------------------
-// Standard vertex formats for models
-//-----------------------------------------------------------------------------
-struct ModelVertexDX7_t
-{
- Vector m_vecPosition;
- Vector2D m_flBoneWeights;
- unsigned int m_nBoneIndices;
- Vector m_vecNormal;
- unsigned int m_nColor; // ARGB
- Vector2D m_vecTexCoord;
-};
-
-struct ModelVertexDX8_t : public ModelVertexDX7_t
-{
- Vector4D m_vecUserData;
-};
-
-
-//-----------------------------------------------------------------------------
-// Utility methods for buffer builders
-//-----------------------------------------------------------------------------
-inline float *OffsetFloatPointer( float *pBufferPointer, int nVertexCount, int vertexSize )
-{
- return reinterpret_cast<float *>(
- reinterpret_cast<unsigned char *>(pBufferPointer) +
- nVertexCount * vertexSize);
-}
-
-inline const float *OffsetFloatPointer( const float *pBufferPointer, int nVertexCount, int vertexSize )
-{
- return reinterpret_cast<const float*>(
- reinterpret_cast<unsigned char const*>(pBufferPointer) +
- nVertexCount * vertexSize);
-}
-
-inline void IncrementFloatPointer( float* &pBufferPointer, int vertexSize )
-{
- pBufferPointer = reinterpret_cast<float*>( reinterpret_cast<unsigned char*>( pBufferPointer ) + vertexSize );
-}
-
-
-//-----------------------------------------------------------------------------
-// Used in lists of indexed primitives.
-//-----------------------------------------------------------------------------
-class CPrimList
-{
-public:
- CPrimList();
- CPrimList( int nFirstIndex, int nIndexCount );
-
- int m_FirstIndex;
- int m_NumIndices;
-};
-
-inline CPrimList::CPrimList()
-{
-}
-
-inline CPrimList::CPrimList( int nFirstIndex, int nIndexCount )
-{
- m_FirstIndex = nFirstIndex;
- m_NumIndices = nIndexCount;
-}
-
-abstract_class IVertexBuffer
-{
-public:
- // Add a virtual destructor to silence the clang warning.
- // This is harmless but not important since the only derived class
- // doesn't have a destructor.
- virtual ~IVertexBuffer() {}
-
- // NOTE: The following two methods are only valid for static vertex buffers
- // Returns the number of vertices and the format of the vertex buffer
- virtual int VertexCount() const = 0;
- virtual VertexFormat_t GetVertexFormat() const = 0;
-
- // Is this vertex buffer dynamic?
- virtual bool IsDynamic() const = 0;
-
- // NOTE: For dynamic vertex buffers only!
- // Casts the memory of the dynamic vertex buffer to the appropriate type
- virtual void BeginCastBuffer( VertexFormat_t format ) = 0;
- virtual void EndCastBuffer() = 0;
-
- // Returns the number of vertices that can still be written into the buffer
- virtual int GetRoomRemaining() const = 0;
-
- virtual bool Lock( int nVertexCount, bool bAppend, VertexDesc_t &desc ) = 0;
- virtual void Unlock( int nVertexCount, VertexDesc_t &desc ) = 0;
-
- // Spews the mesh data
- virtual void Spew( int nVertexCount, const VertexDesc_t &desc ) = 0;
-
- // Call this in debug mode to make sure our data is good.
- virtual void ValidateData( int nVertexCount, const VertexDesc_t & desc ) = 0;
-};
-
-abstract_class IIndexBuffer
-{
-public:
- // Add a virtual destructor to silence the clang warning.
- // This is harmless but not important since the only derived class
- // doesn't have a destructor.
- virtual ~IIndexBuffer() {}
-
- // NOTE: The following two methods are only valid for static index buffers
- // Returns the number of indices and the format of the index buffer
- virtual int IndexCount() const = 0;
- virtual MaterialIndexFormat_t IndexFormat() const = 0;
-
- // Is this index buffer dynamic?
- virtual bool IsDynamic() const = 0;
-
- // NOTE: For dynamic index buffers only!
- // Casts the memory of the dynamic index buffer to the appropriate type
- virtual void BeginCastBuffer( MaterialIndexFormat_t format ) = 0;
- virtual void EndCastBuffer() = 0;
-
- // Returns the number of indices that can still be written into the buffer
- virtual int GetRoomRemaining() const = 0;
-
- // Locks, unlocks the index buffer
- virtual bool Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t &desc ) = 0;
- virtual void Unlock( int nWrittenIndexCount, IndexDesc_t &desc ) = 0;
-
- // FIXME: Remove this!!
- // Locks, unlocks the index buffer for modify
- virtual void ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t& desc ) = 0;
- virtual void ModifyEnd( IndexDesc_t& desc ) = 0;
-
- // Spews the mesh data
- virtual void Spew( int nIndexCount, const IndexDesc_t &desc ) = 0;
-
- // Ensures the data in the index buffer is valid
- virtual void ValidateData( int nIndexCount, const IndexDesc_t &desc ) = 0;
-};
-
-
-//-----------------------------------------------------------------------------
-// Interface to the mesh - needs to contain an IVertexBuffer and an IIndexBuffer to emulate old mesh behavior
-//-----------------------------------------------------------------------------
-abstract_class IMesh : public IVertexBuffer, public IIndexBuffer
-{
-public:
- // -----------------------------------
-
- // Sets/gets the primitive type
- virtual void SetPrimitiveType( MaterialPrimitiveType_t type ) = 0;
-
- // Draws the mesh
- virtual void Draw( int nFirstIndex = -1, int nIndexCount = 0 ) = 0;
-
- virtual void SetColorMesh( IMesh *pColorMesh, int nVertexOffset ) = 0;
-
- // 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 ) = 0;
-
- // 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 ) = 0;
-
- // Spews the mesh data
- virtual void Spew( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ) = 0;
-
- // Call this in debug mode to make sure our data is good.
- virtual void ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ) = 0;
-
- // New version
- // 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 ) = 0;
- virtual void ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t& desc ) = 0;
- virtual void ModifyEnd( MeshDesc_t& desc ) = 0;
- virtual void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) = 0;
-
- virtual void ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ) = 0;
-
- virtual void SetFlexMesh( IMesh *pMesh, int nVertexOffset ) = 0;
-
- virtual void DisableFlexMesh() = 0;
-
- virtual void MarkAsDrawn() = 0;
-
- virtual unsigned ComputeMemoryUsed() = 0;
-};
-
-
-#include "meshreader.h"
-
-#define INVALID_BUFFER_OFFSET 0xFFFFFFFFUL
-
-// flags for advancevertex optimization
-#define VTX_HAVEPOS 1
-#define VTX_HAVENORMAL 2
-#define VTX_HAVECOLOR 4
-#define VTX_HAVEALL ( VTX_HAVEPOS | VTX_HAVENORMAL | VTX_HAVECOLOR )
-
-
-//-----------------------------------------------------------------------------
-//
-// Helper class used to define vertex buffers
-//
-//-----------------------------------------------------------------------------
-class CVertexBuilder : private VertexDesc_t
-{
-public:
- CVertexBuilder();
- CVertexBuilder( IVertexBuffer *pVertexBuffer, VertexFormat_t fmt = 0 );
- ~CVertexBuilder();
-
- // Begins, ends modification of the index buffer (returns true if the lock succeeded)
- // A lock may not succeed if append is set to true and there isn't enough room
- // NOTE: Append is only used with dynamic index buffers; it's ignored for static buffers
- bool Lock( int nMaxIndexCount, bool bAppend = false );
- void Unlock();
-
- // Spews the current data
- // NOTE: Can only be called during a lock/unlock block
- void SpewData();
-
- // Returns the number of indices we can fit into the buffer without needing to discard
- int GetRoomRemaining() const;
-
- // Binds this vertex buffer
- void Bind( IMatRenderContext *pContext, int nStreamID, VertexFormat_t usage = 0 );
-
- // Returns the byte offset
- int Offset() const;
-
- // This must be called before Begin, if a vertex buffer with a compressed format is to be used
- void SetCompressionType( VertexCompressionType_t compressionType );
- void ValidateCompressionType();
-
- void Begin( IVertexBuffer *pVertexBuffer, int nVertexCount, int *nFirstVertex );
- void Begin( IVertexBuffer *pVertexBuffer, int nVertexCount );
-
- // Use this when you're done writing
- // Set bDraw to true to call m_pMesh->Draw automatically.
- void End( bool bSpewData = false );
-
- // Locks the vertex buffer to modify existing data
- // Passing nVertexCount == -1 says to lock all the vertices for modification.
- void BeginModify( IVertexBuffer *pVertexBuffer, int nFirstVertex = 0, int nVertexCount = -1 );
- void EndModify( bool bSpewData = false );
-
- // returns the number of vertices
- int VertexCount() const;
-
- // Returns the total number of vertices across all Locks()
- int TotalVertexCount() const;
-
- // Resets the mesh builder so it points to the start of everything again
- void Reset();
-
- // Returns the size of the vertex
- int VertexSize() { return m_ActualVertexSize; }
-
- // returns the data size of a given texture coordinate
- int TextureCoordinateSize( int nTexCoordNumber ) { return m_VertexSize_TexCoord[ nTexCoordNumber ]; }
-
- // Returns the base vertex memory pointer
- void* BaseVertexData();
-
- // Selects the nth Vertex and Index
- void SelectVertex( int idx );
-
- // Advances the current vertex and index by one
- void AdvanceVertex( void );
- template<int nFlags, int nNumTexCoords> void AdvanceVertexF( void );
- void AdvanceVertices( int nVerts );
-
- int GetCurrentVertex() const;
- int GetFirstVertex() const;
-
- // Data retrieval...
- const float *Position() const;
-
- const float *Normal() const;
-
- unsigned int Color() const;
-
- unsigned char *Specular() const;
-
- const float *TexCoord( int stage ) const;
-
- const float *TangentS() const;
- const float *TangentT() const;
-
- const float *BoneWeight() const;
- float Wrinkle() const;
-
- int NumBoneWeights() const;
-#ifndef NEW_SKINNING
- unsigned char *BoneMatrix() const;
-#else
- float *BoneMatrix() const;
-#endif
-
- // position setting
- void Position3f( float x, float y, float z );
- void Position3fv( const float *v );
-
- // normal setting
- void Normal3f( float nx, float ny, float nz );
- void Normal3fv( const float *n );
- void NormalDelta3fv( const float *n );
- void NormalDelta3f( float nx, float ny, float nz );
- // normal setting (templatized for code which needs to support compressed vertices)
- template <VertexCompressionType_t T> void CompressedNormal3f( float nx, float ny, float nz );
- template <VertexCompressionType_t T> void CompressedNormal3fv( const float *n );
-
- // color setting
- void Color3f( float r, float g, float b );
- void Color3fv( const float *rgb );
- void Color4f( float r, float g, float b, float a );
- void Color4fv( const float *rgba );
-
- // Faster versions of color
- void Color3ub( unsigned char r, unsigned char g, unsigned char b );
- void Color3ubv( unsigned char const* rgb );
- void Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a );
- void Color4ubv( unsigned char const* rgba );
-
- // specular color setting
- void Specular3f( float r, float g, float b );
- void Specular3fv( const float *rgb );
- void Specular4f( float r, float g, float b, float a );
- void Specular4fv( const float *rgba );
-
- // Faster version of specular
- void Specular3ub( unsigned char r, unsigned char g, unsigned char b );
- void Specular3ubv( unsigned char const *c );
- void Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a );
- void Specular4ubv( unsigned char const *c );
-
- // texture coordinate setting
- void TexCoord1f( int stage, float s );
- void TexCoord2f( int stage, float s, float t );
- void TexCoord2fv( int stage, const float *st );
- void TexCoord3f( int stage, float s, float t, float u );
- void TexCoord3fv( int stage, const float *stu );
- void TexCoord4f( int stage, float s, float t, float u, float w );
- void TexCoord4fv( int stage, const float *stuv );
-
- void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT );
- void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale );
-
- // tangent space
- void TangentS3f( float sx, float sy, float sz );
- void TangentS3fv( const float* s );
-
- void TangentT3f( float tx, float ty, float tz );
- void TangentT3fv( const float* t );
-
- // Wrinkle
- void Wrinkle1f( float flWrinkle );
-
- // bone weights
- void BoneWeight( int idx, float weight );
- // bone weights (templatized for code which needs to support compressed vertices)
- template <VertexCompressionType_t T> void CompressedBoneWeight3fv( const float * pWeights );
-
- // bone matrix index
- void BoneMatrix( int idx, int matrixIndex );
-
- // Generic per-vertex data
- void UserData( const float* pData );
- // Generic per-vertex data (templatized for code which needs to support compressed vertices)
- template <VertexCompressionType_t T> void CompressedUserData( const float* pData );
-
- // Fast Vertex! No need to call advance vertex, and no random access allowed.
- // WARNING - these are low level functions that are intended only for use
- // in the software vertex skinner.
- void FastVertex( const ModelVertexDX7_t &vertex );
- void FastVertexSSE( const ModelVertexDX7_t &vertex );
-
- // store 4 dx7 vertices fast. for special sse dx7 pipeline
- void Fast4VerticesSSE(
- ModelVertexDX7_t const *vtx_a,
- ModelVertexDX7_t const *vtx_b,
- ModelVertexDX7_t const *vtx_c,
- ModelVertexDX7_t const *vtx_d);
-
- void FastVertex( const ModelVertexDX8_t &vertex );
- void FastVertexSSE( const ModelVertexDX8_t &vertex );
-
- // Add number of verts and current vert since FastVertex routines do not update.
- void FastAdvanceNVertices( int n );
-
-#if defined( _X360 )
- void VertexDX8ToX360( const ModelVertexDX8_t &vertex );
-#endif
-
- // FIXME: Remove! Backward compat so we can use this from a CMeshBuilder.
- void AttachBegin( IMesh* pMesh, int nMaxVertexCount, const MeshDesc_t &desc );
- void AttachEnd();
- void AttachBeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, const MeshDesc_t &desc );
- void AttachEndModify();
-
-private:
- // The vertex buffer we're modifying
- IVertexBuffer *m_pVertexBuffer;
-
- // Used to make sure Begin/End calls and BeginModify/EndModify calls match.
- bool m_bModify;
-
- // Max number of indices and vertices
- int m_nMaxVertexCount;
-
- // Number of indices and vertices
- int m_nVertexCount;
-
- // The current vertex and index
- mutable int m_nCurrentVertex;
-
- // Optimization: Pointer to the current pos, norm, texcoord, and color
- mutable float *m_pCurrPosition;
- mutable float *m_pCurrNormal;
- mutable float *m_pCurrTexCoord[VERTEX_MAX_TEXTURE_COORDINATES];
- mutable unsigned char *m_pCurrColor;
-
- // Total number of vertices appended
- int m_nTotalVertexCount;
-
- // First vertex buffer offset + index
- unsigned int m_nBufferOffset;
- unsigned int m_nBufferFirstVertex;
-
-#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 )
- // Debug checks to make sure we write userdata4/tangents AFTER normals
- bool m_bWrittenNormal : 1;
- bool m_bWrittenUserData : 1;
-#endif
-
- friend class CMeshBuilder;
-};
-
-
-//-----------------------------------------------------------------------------
-//
-// Inline methods of CVertexBuilder
-//
-//-----------------------------------------------------------------------------
-inline CVertexBuilder::CVertexBuilder()
-{
- m_pVertexBuffer = NULL;
- m_nBufferOffset = INVALID_BUFFER_OFFSET;
- m_nBufferFirstVertex = 0;
- m_nVertexCount = 0;
- m_nCurrentVertex = 0;
- m_nMaxVertexCount = 0;
- m_nTotalVertexCount = 0;
- m_CompressionType = VERTEX_COMPRESSION_INVALID;
-
-#ifdef _DEBUG
- m_pCurrPosition = NULL;
- m_pCurrNormal = NULL;
- m_pCurrColor = NULL;
- memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) );
- m_bModify = false;
-#endif
-}
-
-inline CVertexBuilder::CVertexBuilder( IVertexBuffer *pVertexBuffer, VertexFormat_t fmt )
-{
- m_pVertexBuffer = pVertexBuffer;
- m_nBufferOffset = INVALID_BUFFER_OFFSET;
- m_nBufferFirstVertex = 0;
- m_nVertexCount = 0;
- m_nCurrentVertex = 0;
- m_nMaxVertexCount = 0;
- m_nTotalVertexCount = 0;
- m_CompressionType = VERTEX_COMPRESSION_INVALID;
-
- if ( m_pVertexBuffer->IsDynamic() )
- {
- m_pVertexBuffer->BeginCastBuffer( fmt );
- }
- else
- {
- Assert( m_pVertexBuffer->GetVertexFormat() == fmt );
- }
-
-#ifdef _DEBUG
- m_pCurrPosition = NULL;
- m_pCurrNormal = NULL;
- m_pCurrColor = NULL;
- memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) );
- m_bModify = false;
-#endif
-}
-
-inline CVertexBuilder::~CVertexBuilder()
-{
- if ( m_pVertexBuffer && m_pVertexBuffer->IsDynamic() )
- {
- m_pVertexBuffer->EndCastBuffer();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Begins, ends modification of the index buffer
-//-----------------------------------------------------------------------------
-inline bool CVertexBuilder::Lock( int nMaxVertexCount, bool bAppend )
-{
- Assert( m_pVertexBuffer );
- m_bModify = false;
- m_nMaxVertexCount = nMaxVertexCount;
- bool bFirstLock = ( m_nBufferOffset == INVALID_BUFFER_OFFSET );
- if ( bFirstLock )
- {
- bAppend = false;
- }
- if ( !bAppend )
- {
- m_nTotalVertexCount = 0;
- }
-
- // Lock the vertex buffer
- if ( !m_pVertexBuffer->Lock( m_nMaxVertexCount, bAppend, *this ) )
- {
- m_nMaxVertexCount = 0;
- return false;
- }
-
- Reset();
-
- if ( bFirstLock )
- {
- m_nBufferOffset = m_nOffset;
- m_nBufferFirstVertex = m_nFirstVertex;
- }
-
- return true;
-}
-
-inline void CVertexBuilder::Unlock()
-{
- Assert( !m_bModify && m_pVertexBuffer );
-
-#ifdef _DEBUG
- m_pVertexBuffer->ValidateData( m_nVertexCount, *this );
-#endif
-
- m_pVertexBuffer->Unlock( m_nVertexCount, *this );
- m_nTotalVertexCount += m_nVertexCount;
-
- m_nMaxVertexCount = 0;
-
-#ifdef _DEBUG
- // Null out our data...
- m_pCurrPosition = NULL;
- m_pCurrNormal = NULL;
- m_pCurrColor = NULL;
- memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) );
- memset( static_cast<VertexDesc_t*>( this ), 0, sizeof(VertexDesc_t) );
-#endif
-}
-
-inline void CVertexBuilder::SpewData()
-{
- m_pVertexBuffer->Spew( m_nVertexCount, *this );
-}
-
-
-//-----------------------------------------------------------------------------
-// Binds this vertex buffer
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::Bind( IMatRenderContext *pContext, int nStreamID, VertexFormat_t usage )
-{
- if ( m_pVertexBuffer && ( m_nBufferOffset != INVALID_BUFFER_OFFSET ) )
- {
- pContext->BindVertexBuffer( nStreamID, m_pVertexBuffer, m_nBufferOffset,
- m_nFirstVertex, m_nTotalVertexCount, usage ? usage : m_pVertexBuffer->GetVertexFormat() );
- }
- else
- {
- pContext->BindVertexBuffer( nStreamID, NULL, 0, 0, 0, 0 );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the byte offset
-//-----------------------------------------------------------------------------
-inline int CVertexBuilder::Offset() const
-{
- return m_nBufferOffset;
-}
-
-inline int CVertexBuilder::GetFirstVertex() const
-{
- return m_nBufferFirstVertex;
-}
-
-//-----------------------------------------------------------------------------
-// Specify the type of vertex compression that this CMeshBuilder will perform
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::SetCompressionType( VertexCompressionType_t compressionType )
-{
- // The real purpose of this method is to allow us to emit a Warning in Begin()
- m_CompressionType = compressionType;
-}
-
-inline void CVertexBuilder::ValidateCompressionType()
-{
-#ifdef _DEBUG
- VertexCompressionType_t vbCompressionType = CompressionType( m_pVertexBuffer->GetVertexFormat() );
- if ( vbCompressionType != VERTEX_COMPRESSION_NONE )
- {
- Assert( m_CompressionType == vbCompressionType );
- if ( m_CompressionType != vbCompressionType )
- {
- Warning( "ERROR: CVertexBuilder::SetCompressionType() must be called to specify the same vertex compression type (%s) as the vertex buffer being modified."
- "Junk vertices will be rendered, or there will be a crash in CVertexBuilder!\n",
- vbCompressionType == VERTEX_COMPRESSION_ON ? "VERTEX_COMPRESSION_ON" : "VERTEX_COMPRESSION_NONE" );
- }
- // Never use vertex compression for dynamic VBs (the conversions can really hurt perf)
- Assert( !m_pVertexBuffer->IsDynamic() );
- }
-#endif
-}
-
-inline void CVertexBuilder::Begin( IVertexBuffer *pVertexBuffer, int nVertexCount )
-{
- Assert( pVertexBuffer && (!m_pVertexBuffer) );
-
- m_pVertexBuffer = pVertexBuffer;
- m_bModify = false;
-
- m_nMaxVertexCount = nVertexCount;
- m_nVertexCount = 0;
-
- // Make sure SetCompressionType was called correctly, if this VB is compressed
- ValidateCompressionType();
-
- // Lock the vertex and index buffer
- m_pVertexBuffer->Lock( m_nMaxVertexCount, false, *this );
-
- // Point to the start of the buffers..
- Reset();
-}
-
-
-//-----------------------------------------------------------------------------
-// Use this when you're done modifying the mesh
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::End( bool bSpewData )
-{
- // Make sure they called Begin()
- Assert( !m_bModify );
-
- if ( bSpewData )
- {
- m_pVertexBuffer->Spew( m_nVertexCount, *this );
- }
-
-#ifdef _DEBUG
- m_pVertexBuffer->ValidateData( m_nVertexCount, *this );
-#endif
-
- // Unlock our buffers
- m_pVertexBuffer->Unlock( m_nVertexCount, *this );
-
- m_pVertexBuffer = 0;
- m_nMaxVertexCount = 0;
-
- m_CompressionType = VERTEX_COMPRESSION_INVALID;
-
-#ifdef _DEBUG
- // Null out our pointers...
- m_pCurrPosition = NULL;
- m_pCurrNormal = NULL;
- m_pCurrColor = NULL;
- memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) );
- memset( static_cast< VertexDesc_t* >( this ), 0, sizeof(VertexDesc_t) );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// FIXME: Remove! Backward compat so we can use this from a CMeshBuilder.
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::AttachBegin( IMesh* pMesh, int nMaxVertexCount, const MeshDesc_t &desc )
-{
- VertexCompressionType_t compressionType = m_CompressionType;
-
- m_pVertexBuffer = pMesh;
- memcpy( static_cast<VertexDesc_t*>( this ), static_cast<const VertexDesc_t*>( &desc ), sizeof(VertexDesc_t) );
- m_nMaxVertexCount = nMaxVertexCount;
- m_NumBoneWeights = m_NumBoneWeights == 0 ? 0 : 2; // Two weights if any
- m_nVertexCount = 0;
- m_bModify = false;
-
- if ( compressionType != VERTEX_COMPRESSION_INVALID )
- m_CompressionType = compressionType;
-
- // Make sure SetCompressionType was called correctly, if this VB is compressed
- ValidateCompressionType();
-
- if ( m_nBufferOffset == INVALID_BUFFER_OFFSET )
- {
- m_nTotalVertexCount = 0;
- m_nBufferOffset = static_cast< const VertexDesc_t* >( &desc )->m_nOffset;
- m_nBufferFirstVertex = desc.m_nFirstVertex;
- }
-}
-
-inline void CVertexBuilder::AttachEnd()
-{
- // Make sure they called Begin()
- Assert( !m_bModify );
-
- m_nMaxVertexCount = 0;
- m_pVertexBuffer = NULL;
-
- m_CompressionType = VERTEX_COMPRESSION_INVALID;
-
-#ifdef _DEBUG
- // Null out our pointers...
- m_pCurrPosition = NULL;
- m_pCurrNormal = NULL;
- m_pCurrColor = NULL;
- memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) );
- memset( static_cast<VertexDesc_t*>( this ), 0, sizeof(VertexDesc_t) );
-#endif
-}
-
-inline void CVertexBuilder::AttachBeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, const MeshDesc_t &desc )
-{
- Assert( pMesh && (!m_pVertexBuffer) );
-
- m_pVertexBuffer = pMesh;
- memcpy( static_cast<VertexDesc_t*>( this ), static_cast<const VertexDesc_t*>( &desc ), sizeof(VertexDesc_t) );
- m_nMaxVertexCount = m_nVertexCount = nVertexCount;
- m_NumBoneWeights = m_NumBoneWeights == 0 ? 0 : 2; // Two weights if any
- m_bModify = true;
-
- // Make sure SetCompressionType was called correctly, if this VB is compressed
- ValidateCompressionType();
-}
-
-inline void CVertexBuilder::AttachEndModify()
-{
- Assert( m_pVertexBuffer );
- Assert( m_bModify ); // Make sure they called BeginModify.
-
- m_pVertexBuffer = 0;
- m_nMaxVertexCount = 0;
-
- m_CompressionType = VERTEX_COMPRESSION_INVALID;
-
-#ifdef _DEBUG
- // Null out our pointers...
- m_pCurrPosition = NULL;
- m_pCurrNormal = NULL;
- m_pCurrColor = NULL;
- memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) );
- memset( static_cast<VertexDesc_t*>( this ), 0, sizeof(VertexDesc_t) );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Computes the first min non-null address
-//-----------------------------------------------------------------------------
-inline unsigned char* FindMinAddress( void *pAddress1, void *pAddress2, int nAddress2Size )
-{
- if ( nAddress2Size == 0 )
- return (unsigned char*)pAddress1;
- if ( !pAddress1 )
- return (unsigned char*)pAddress2;
- return ( pAddress1 < pAddress2 ) ? (unsigned char*)pAddress1 : (unsigned char*)pAddress2;
-}
-
-//-----------------------------------------------------------------------------
-// Resets the vertex buffer builder so it points to the start of everything again
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::Reset()
-{
- m_nCurrentVertex = 0;
-
- m_pCurrPosition = m_pPosition;
- m_pCurrNormal = m_pNormal;
- for ( int i = 0; i < NELEMS( m_pCurrTexCoord ); i++ )
- {
- m_pCurrTexCoord[i] = m_pTexCoord[i];
- }
- m_pCurrColor = m_pColor;
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-
-#ifdef DEBUG_WRITE_COMBINE
- // Logic for m_pLastWrittenAddress is tricky. It really wants the min of the
- // non-null address pointers.
- m_nLastWrittenField = MB_FIELD_NONE;
- m_pLastWrittenAddress = NULL;
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pPosition, m_VertexSize_Position );
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pBoneWeight, m_VertexSize_BoneWeight );
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pBoneMatrixIndex, m_VertexSize_BoneMatrixIndex );
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pNormal, m_VertexSize_Normal );
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pColor, m_VertexSize_Color );
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pSpecular, m_VertexSize_Specular );
- for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i )
- {
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTexCoord[i], m_VertexSize_TexCoord[i] );
- }
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTangentS, m_VertexSize_TangentS );
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTangentT, m_VertexSize_TangentT );
- m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pUserData, m_VertexSize_UserData );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// returns the number of vertices
-//-----------------------------------------------------------------------------
-inline int CVertexBuilder::VertexCount() const
-{
- return m_nVertexCount;
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the total number of vertices across all Locks()
-//-----------------------------------------------------------------------------
-inline int CVertexBuilder::TotalVertexCount() const
-{
- return m_nTotalVertexCount;
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the base vertex memory pointer
-//-----------------------------------------------------------------------------
-inline void* CVertexBuilder::BaseVertexData()
-{
- // FIXME: If there's no position specified, we need to find
- // the base address
- Assert( m_pPosition );
- return m_pPosition;
-}
-
-
-//-----------------------------------------------------------------------------
-// Selects the current vertex
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::SelectVertex( int nIndex )
-{
- // NOTE: This index is expected to be relative
- Assert( (nIndex >= 0) && (nIndex < m_nMaxVertexCount) );
- m_nCurrentVertex = nIndex;
-
- m_pCurrPosition = OffsetFloatPointer( m_pPosition, m_nCurrentVertex, m_VertexSize_Position );
- m_pCurrNormal = OffsetFloatPointer( m_pNormal, m_nCurrentVertex, m_VertexSize_Normal );
-
- COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 );
- m_pCurrTexCoord[0] = OffsetFloatPointer( m_pTexCoord[0], m_nCurrentVertex, m_VertexSize_TexCoord[0] );
- m_pCurrTexCoord[1] = OffsetFloatPointer( m_pTexCoord[1], m_nCurrentVertex, m_VertexSize_TexCoord[1] );
- m_pCurrTexCoord[2] = OffsetFloatPointer( m_pTexCoord[2], m_nCurrentVertex, m_VertexSize_TexCoord[2] );
- m_pCurrTexCoord[3] = OffsetFloatPointer( m_pTexCoord[3], m_nCurrentVertex, m_VertexSize_TexCoord[3] );
- m_pCurrTexCoord[4] = OffsetFloatPointer( m_pTexCoord[4], m_nCurrentVertex, m_VertexSize_TexCoord[4] );
- m_pCurrTexCoord[5] = OffsetFloatPointer( m_pTexCoord[5], m_nCurrentVertex, m_VertexSize_TexCoord[5] );
- m_pCurrTexCoord[6] = OffsetFloatPointer( m_pTexCoord[6], m_nCurrentVertex, m_VertexSize_TexCoord[6] );
- m_pCurrTexCoord[7] = OffsetFloatPointer( m_pTexCoord[7], m_nCurrentVertex, m_VertexSize_TexCoord[7] );
- m_pCurrColor = m_pColor + m_nCurrentVertex * m_VertexSize_Color;
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Advances vertex after you're done writing to it.
-//-----------------------------------------------------------------------------
-
-template<int nFlags, int nNumTexCoords> FORCEINLINE void CVertexBuilder::AdvanceVertexF()
-{
- if ( ++m_nCurrentVertex > m_nVertexCount )
- {
- m_nVertexCount = m_nCurrentVertex;
- }
-
- if ( nFlags & VTX_HAVEPOS )
- IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position );
- if ( nFlags & VTX_HAVENORMAL )
- IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal );
- if ( nFlags & VTX_HAVECOLOR )
- m_pCurrColor += m_VertexSize_Color;
-
- COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 );
- if ( nNumTexCoords > 0 )
- IncrementFloatPointer( m_pCurrTexCoord[0], m_VertexSize_TexCoord[0] );
- if ( nNumTexCoords > 1 )
- IncrementFloatPointer( m_pCurrTexCoord[1], m_VertexSize_TexCoord[1] );
- if ( nNumTexCoords > 2 )
- IncrementFloatPointer( m_pCurrTexCoord[2], m_VertexSize_TexCoord[2] );
- if ( nNumTexCoords > 3 )
- IncrementFloatPointer( m_pCurrTexCoord[3], m_VertexSize_TexCoord[3] );
- if ( nNumTexCoords > 4 )
- IncrementFloatPointer( m_pCurrTexCoord[4], m_VertexSize_TexCoord[4] );
- if ( nNumTexCoords > 5 )
- IncrementFloatPointer( m_pCurrTexCoord[5], m_VertexSize_TexCoord[5] );
- if ( nNumTexCoords > 6 )
- IncrementFloatPointer( m_pCurrTexCoord[6], m_VertexSize_TexCoord[6] );
- if ( nNumTexCoords > 7 )
- IncrementFloatPointer( m_pCurrTexCoord[7], m_VertexSize_TexCoord[7] );
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-
-inline void CVertexBuilder::AdvanceVertex()
-{
- AdvanceVertexF<VTX_HAVEALL, 8>();
-}
-
-
-inline void CVertexBuilder::AdvanceVertices( int nVerts )
-{
- m_nCurrentVertex += nVerts;
- if ( m_nCurrentVertex > m_nVertexCount )
- {
- m_nVertexCount = m_nCurrentVertex;
- }
-
- IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position*nVerts );
- IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal*nVerts );
-
- COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 );
- IncrementFloatPointer( m_pCurrTexCoord[0], m_VertexSize_TexCoord[0]*nVerts );
- IncrementFloatPointer( m_pCurrTexCoord[1], m_VertexSize_TexCoord[1]*nVerts );
- IncrementFloatPointer( m_pCurrTexCoord[2], m_VertexSize_TexCoord[2]*nVerts );
- IncrementFloatPointer( m_pCurrTexCoord[3], m_VertexSize_TexCoord[3]*nVerts );
- IncrementFloatPointer( m_pCurrTexCoord[4], m_VertexSize_TexCoord[4]*nVerts );
- IncrementFloatPointer( m_pCurrTexCoord[5], m_VertexSize_TexCoord[5]*nVerts );
- IncrementFloatPointer( m_pCurrTexCoord[6], m_VertexSize_TexCoord[6]*nVerts );
- IncrementFloatPointer( m_pCurrTexCoord[7], m_VertexSize_TexCoord[7]*nVerts );
- m_pCurrColor += m_VertexSize_Color*nVerts;
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// For use with the FastVertex methods, advances the current vertex by N
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::FastAdvanceNVertices( int n )
-{
- m_nCurrentVertex += n;
- m_nVertexCount = m_nCurrentVertex;
-}
-
-
-
-#ifndef COMPILER_MSVC64
-// Implement for 64-bit Windows if needed.
-//-----------------------------------------------------------------------------
-// Fast Vertex! No need to call advance vertex, and no random access allowed
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::FastVertex( const ModelVertexDX7_t &vertex )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
-
-#if defined( _WIN32 ) && !defined( _X360 )
- const void *pRead = &vertex;
- void *pCurrPos = m_pCurrPosition;
-
- __asm
- {
- mov esi, pRead
- mov edi, pCurrPos
-
- movq mm0, [esi + 0]
- movq mm1, [esi + 8]
- movq mm2, [esi + 16]
- movq mm3, [esi + 24]
- movq mm4, [esi + 32]
- movq mm5, [esi + 40]
-
- movntq [edi + 0], mm0
- movntq [edi + 8], mm1
- movntq [edi + 16], mm2
- movntq [edi + 24], mm3
- movntq [edi + 32], mm4
- movntq [edi + 40], mm5
-
- emms
- }
-#elif defined(GNUC)
- const void *pRead = &vertex;
- void *pCurrPos = m_pCurrPosition;
- __asm__ __volatile__ (
- "movq (%0), %%mm0\n"
- "movq 8(%0), %%mm1\n"
- "movq 16(%0), %%mm2\n"
- "movq 24(%0), %%mm3\n"
- "movq 32(%0), %%mm4\n"
- "movq 40(%0), %%mm5\n"
- "movntq %%mm0, (%1)\n"
- "movntq %%mm1, 8(%1)\n"
- "movntq %%mm2, 16(%1)\n"
- "movntq %%mm3, 24(%1)\n"
- "movntq %%mm4, 32(%1)\n"
- "movntq %%mm5, 40(%1)\n"
- "emms\n"
- :: "r" (pRead), "r" (pCurrPos) : "memory");
-#else
- Error( "Implement CMeshBuilder::FastVertex(dx7) ");
-#endif
-
- IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position );
- //m_nVertexCount = ++m_nCurrentVertex;
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-
-inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
-
-#if defined( _WIN32 ) && !defined( _X360 )
- const void *pRead = &vertex;
- void *pCurrPos = m_pCurrPosition;
- __asm
- {
- mov esi, pRead
- mov edi, pCurrPos
-
- movaps xmm0, [esi + 0]
- movaps xmm1, [esi + 16]
- movaps xmm2, [esi + 32]
-
- movntps [edi + 0], xmm0
- movntps [edi + 16], xmm1
- movntps [edi + 32], xmm2
- }
-#elif defined(GNUC)
- const char *pRead = (char *)&vertex;
- char *pCurrPos = (char *)m_pCurrPosition;
- __m128 m1 = _mm_load_ps( (float *)pRead );
- __m128 m2 = _mm_load_ps( (float *)(pRead + 16) );
- __m128 m3 = _mm_load_ps( (float *)(pRead + 32) );
- _mm_stream_ps( (float *)pCurrPos, m1 );
- _mm_stream_ps( (float *)(pCurrPos + 16), m2 );
- _mm_stream_ps( (float *)(pCurrPos + 32), m3 );
-#else
- Error( "Implement CMeshBuilder::FastVertexSSE(dx7)" );
-#endif
-
- IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position );
- //m_nVertexCount = ++m_nCurrentVertex;
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-
-inline void CVertexBuilder::Fast4VerticesSSE(
- ModelVertexDX7_t const *vtx_a,
- ModelVertexDX7_t const *vtx_b,
- ModelVertexDX7_t const *vtx_c,
- ModelVertexDX7_t const *vtx_d)
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
- Assert( m_nCurrentVertex < m_nMaxVertexCount-3 );
-
-#if defined( _WIN32 ) && !defined( _X360 )
- void *pCurrPos = m_pCurrPosition;
- __asm
- {
- mov esi, vtx_a
- mov ecx, vtx_b
-
- mov edi, pCurrPos
- nop
-
- movaps xmm0, [esi + 0]
- movaps xmm1, [esi + 16]
- movaps xmm2, [esi + 32]
- movaps xmm3, [ecx + 0]
- movaps xmm4, [ecx + 16]
- movaps xmm5, [ecx + 32]
-
- mov esi, vtx_c
- mov ecx, vtx_d
-
- movntps [edi + 0], xmm0
- movntps [edi + 16], xmm1
- movntps [edi + 32], xmm2
- movntps [edi + 48], xmm3
- movntps [edi + 64], xmm4
- movntps [edi + 80], xmm5
-
- movaps xmm0, [esi + 0]
- movaps xmm1, [esi + 16]
- movaps xmm2, [esi + 32]
- movaps xmm3, [ecx + 0]
- movaps xmm4, [ecx + 16]
- movaps xmm5, [ecx + 32]
-
- movntps [edi + 0+96], xmm0
- movntps [edi + 16+96], xmm1
- movntps [edi + 32+96], xmm2
- movntps [edi + 48+96], xmm3
- movntps [edi + 64+96], xmm4
- movntps [edi + 80+96], xmm5
-
- }
-#else
- Error( "Implement CMeshBuilder::Fast4VerticesSSE\n");
-#endif
- IncrementFloatPointer( m_pCurrPosition, 4*m_VertexSize_Position );
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-
-inline void CVertexBuilder::FastVertex( const ModelVertexDX8_t &vertex )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
-
-#if defined( _WIN32 ) && !defined( _X360 )
- const void *pRead = &vertex;
- void *pCurrPos = m_pCurrPosition;
- __asm
- {
- mov esi, pRead
- mov edi, pCurrPos
-
- movq mm0, [esi + 0]
- movq mm1, [esi + 8]
- movq mm2, [esi + 16]
- movq mm3, [esi + 24]
- movq mm4, [esi + 32]
- movq mm5, [esi + 40]
- movq mm6, [esi + 48]
- movq mm7, [esi + 56]
-
- movntq [edi + 0], mm0
- movntq [edi + 8], mm1
- movntq [edi + 16], mm2
- movntq [edi + 24], mm3
- movntq [edi + 32], mm4
- movntq [edi + 40], mm5
- movntq [edi + 48], mm6
- movntq [edi + 56], mm7
-
- emms
- }
-#elif defined(GNUC)
- const void *pRead = &vertex;
- void *pCurrPos = m_pCurrPosition;
- __asm__ __volatile__ (
- "movq (%0), %%mm0\n"
- "movq 8(%0), %%mm1\n"
- "movq 16(%0), %%mm2\n"
- "movq 24(%0), %%mm3\n"
- "movq 32(%0), %%mm4\n"
- "movq 40(%0), %%mm5\n"
- "movq 48(%0), %%mm6\n"
- "movq 56(%0), %%mm7\n"
- "movntq %%mm0, (%1)\n"
- "movntq %%mm1, 8(%1)\n"
- "movntq %%mm2, 16(%1)\n"
- "movntq %%mm3, 24(%1)\n"
- "movntq %%mm4, 32(%1)\n"
- "movntq %%mm5, 40(%1)\n"
- "movntq %%mm6, 48(%1)\n"
- "movntq %%mm7, 56(%1)\n"
- "emms\n"
- :: "r" (pRead), "r" (pCurrPos) : "memory");
-#else
- Error( "Implement CMeshBuilder::FastVertex(dx8)" );
-#endif
-
- IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position );
- // m_nVertexCount = ++m_nCurrentVertex;
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-
-inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
-
-#if defined( _WIN32 ) && !defined( _X360 )
- const void *pRead = &vertex;
- void *pCurrPos = m_pCurrPosition;
- __asm
- {
- mov esi, pRead
- mov edi, pCurrPos
-
- movaps xmm0, [esi + 0]
- movaps xmm1, [esi + 16]
- movaps xmm2, [esi + 32]
- movaps xmm3, [esi + 48]
-
- movntps [edi + 0], xmm0
- movntps [edi + 16], xmm1
- movntps [edi + 32], xmm2
- movntps [edi + 48], xmm3
- }
-#elif defined(GNUC)
- const void *pRead = &vertex;
- void *pCurrPos = m_pCurrPosition;
- __asm__ __volatile__ (
- "movaps (%0), %%xmm0\n"
- "movaps 16(%0), %%xmm1\n"
- "movaps 32(%0), %%xmm2\n"
- "movaps 48(%0), %%xmm3\n"
- "movntps %%xmm0, (%1)\n"
- "movntps %%xmm1, 16(%1)\n"
- "movntps %%xmm2, 32(%1)\n"
- "movntps %%xmm3, 48(%1)\n"
- :: "r" (pRead), "r" (pCurrPos) : "memory");
-#else
- Error( "Implement CMeshBuilder::FastVertexSSE((dx8)" );
-#endif
-
- IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position );
- // m_nVertexCount = ++m_nCurrentVertex;
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-#endif // COMPILER_MSVC64
-
-
-//-----------------------------------------------------------------------------
-// Returns the current vertex
-//-----------------------------------------------------------------------------
-inline int CVertexBuilder::GetCurrentVertex() const
-{
- return m_nCurrentVertex;
-}
-
-
-//-----------------------------------------------------------------------------
-// Copies a vertex into the x360 format
-//-----------------------------------------------------------------------------
-#if defined( _X360 )
-inline void CVertexBuilder::VertexDX8ToX360( const ModelVertexDX8_t &vertex )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
-
- // get the start of the data
- unsigned char *pDst = (unsigned char*)m_pCurrPosition;
-
- Assert( m_VertexSize_Position > 0 ); // Assume position is always present
- Assert( GetVertexElementSize( VERTEX_ELEMENT_POSITION, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecPosition ) );
- memcpy( pDst, vertex.m_vecPosition.Base(), sizeof( vertex.m_vecPosition ) );
- pDst += sizeof( vertex.m_vecPosition );
-
- if ( m_VertexSize_BoneWeight )
- {
- Assert( vertex.m_flBoneWeights[0] >= 0 && vertex.m_flBoneWeights[0] <= 1.0f );
- Assert( vertex.m_flBoneWeights[1] >= 0 && vertex.m_flBoneWeights[1] <= 1.0f );
- Assert( GetVertexElementSize( VERTEX_ELEMENT_BONEWEIGHTS2, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_flBoneWeights ) );
- memcpy( pDst, vertex.m_flBoneWeights.Base(), sizeof( vertex.m_flBoneWeights ) );
- pDst += sizeof( vertex.m_flBoneWeights );
-
- if ( m_VertexSize_BoneMatrixIndex )
- {
- Assert( GetVertexElementSize( VERTEX_ELEMENT_BONEINDEX, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_nBoneIndices ) );
- *(unsigned int*)pDst = vertex.m_nBoneIndices;
- pDst += sizeof( vertex.m_nBoneIndices );
- }
- }
-
- if ( m_VertexSize_Normal )
- {
- Assert( GetVertexElementSize( VERTEX_ELEMENT_NORMAL, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecNormal ) );
- memcpy( pDst, vertex.m_vecNormal.Base(), sizeof( vertex.m_vecNormal ) );
- pDst += sizeof( vertex.m_vecNormal );
- }
-
- if ( m_VertexSize_Color )
- {
- Assert( GetVertexElementSize( VERTEX_ELEMENT_COLOR, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_nColor ) );
- *(unsigned int*)pDst = vertex.m_nColor;
- pDst += sizeof( vertex.m_nColor );
- }
-
- if ( m_VertexSize_TexCoord[0] )
- {
- Assert( GetVertexElementSize( VERTEX_ELEMENT_TEXCOORD2D_0, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecTexCoord ) );
- memcpy( pDst, vertex.m_vecTexCoord.Base(), sizeof( vertex.m_vecTexCoord ) );
- pDst += sizeof( vertex.m_vecTexCoord );
- }
-
- if ( m_VertexSize_UserData )
- {
- Assert( GetVertexElementSize( VERTEX_ELEMENT_USERDATA4, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecUserData ) );
- memcpy( pDst, vertex.m_vecUserData.Base(), sizeof( vertex.m_vecUserData ) );
- pDst += sizeof( vertex.m_vecUserData );
- }
-
- // ensure code is synced with the mesh builder that established the offsets
- Assert( pDst - (unsigned char*)m_pCurrPosition == m_VertexSize_Position );
-
- IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position );
-
-#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) )
- m_bWrittenNormal = false;
- m_bWrittenUserData = false;
-#endif
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Data retrieval...
-//-----------------------------------------------------------------------------
-inline const float* CVertexBuilder::Position() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return m_pCurrPosition;
-}
-
-inline const float* CVertexBuilder::Normal() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return m_pCurrNormal;
-}
-
-inline unsigned int CVertexBuilder::Color() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- // Swizzle it so it returns the same format as accepted by Color4ubv - rgba
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- unsigned int color;
- if ( IsPC() || !IsX360() )
- {
- color = (m_pCurrColor[3] << 24) | (m_pCurrColor[0] << 16) | (m_pCurrColor[1] << 8) | (m_pCurrColor[2]);
- }
- else
- {
- // in memory as argb, back to rgba
- color = (m_pCurrColor[1] << 24) | (m_pCurrColor[2] << 16) | (m_pCurrColor[3] << 8) | (m_pCurrColor[0]);
- }
- return color;
-}
-
-inline unsigned char *CVertexBuilder::Specular() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return m_pSpecular + m_nCurrentVertex * m_VertexSize_Specular;
-}
-
-inline const float* CVertexBuilder::TexCoord( int stage ) const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return m_pCurrTexCoord[stage];
-}
-
-inline const float* CVertexBuilder::TangentS() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS );
-}
-
-inline const float* CVertexBuilder::TangentT() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT );
-}
-
-inline float CVertexBuilder::Wrinkle() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return *OffsetFloatPointer( m_pWrinkle, m_nCurrentVertex, m_VertexSize_Wrinkle );
-}
-
-inline const float* CVertexBuilder::BoneWeight() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight );
-}
-
-inline int CVertexBuilder::NumBoneWeights() const
-{
- return m_NumBoneWeights;
-}
-
-#ifndef NEW_SKINNING
-inline unsigned char* CVertexBuilder::BoneMatrix() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return m_pBoneMatrixIndex + m_nCurrentVertex * m_VertexSize_BoneMatrixIndex;
-}
-#else
-inline float* CVertexBuilder::BoneMatrix() const
-{
- // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately)
- // for code that needs to access compressed data (and/or a return-by-value templatized accessor)
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE );
- Assert( m_nCurrentVertex < m_nMaxVertexCount );
- return m_pBoneMatrixIndex + m_nCurrentVertex * m_VertexSize_BoneMatrixIndex;
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Position setting methods
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::Position3f( float x, float y, float z )
-{
- Assert( m_pPosition && m_pCurrPosition );
- Assert( IsFinite(x) && IsFinite(y) && IsFinite(z) );
- float *pDst = m_pCurrPosition;
- *pDst++ = x;
- *pDst++ = y;
- *pDst = z;
-}
-
-inline void CVertexBuilder::Position3fv( const float *v )
-{
- Assert(v);
- Assert( m_pPosition && m_pCurrPosition );
-
- float *pDst = m_pCurrPosition;
- *pDst++ = *v++;
- *pDst++ = *v++;
- *pDst = *v;
-}
-
-
-//-----------------------------------------------------------------------------
-// Normal setting methods
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::Normal3f( float nx, float ny, float nz )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression
- Assert( m_pNormal );
- Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) );
- Assert( nx >= -1.05f && nx <= 1.05f );
- Assert( ny >= -1.05f && ny <= 1.05f );
- Assert( nz >= -1.05f && nz <= 1.05f );
-
- float *pDst = m_pCurrNormal;
- *pDst++ = nx;
- *pDst++ = ny;
- *pDst = nz;
-}
-
-inline void CVertexBuilder::Normal3fv( const float *n )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression
- Assert( n );
- Assert( m_pNormal && m_pCurrNormal );
- Assert( IsFinite(n[0]) && IsFinite(n[1]) && IsFinite(n[2]) );
- Assert( n[0] >= -1.05f && n[0] <= 1.05f );
- Assert( n[1] >= -1.05f && n[1] <= 1.05f );
- Assert( n[2] >= -1.05f && n[2] <= 1.05f );
-
- float *pDst = m_pCurrNormal;
- *pDst++ = *n++;
- *pDst++ = *n++;
- *pDst = *n;
-}
-
-inline void CVertexBuilder::NormalDelta3f( float nx, float ny, float nz )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression
- Assert( m_pNormal );
- Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) );
-
- float *pDst = m_pCurrNormal;
- *pDst++ = nx;
- *pDst++ = ny;
- *pDst = nz;
-}
-
-inline void CVertexBuilder::NormalDelta3fv( const float *n )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression
- Assert( n );
- Assert( m_pNormal && m_pCurrNormal );
- Assert( IsFinite(n[0]) && IsFinite(n[1]) && IsFinite(n[2]) );
-
- float *pDst = m_pCurrNormal;
- *pDst++ = *n++;
- *pDst++ = *n++;
- *pDst = *n;
-}
-
-//-----------------------------------------------------------------------------
-// Templatized normal setting methods which support compressed vertices
-//-----------------------------------------------------------------------------
-template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedNormal3f( float nx, float ny, float nz )
-{
- Assert( T == m_CompressionType );
- Assert( m_pNormal && m_pCurrNormal );
- Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) );
- Assert( nx >= -1.05f && nx <= 1.05f );
- Assert( ny >= -1.05f && ny <= 1.05f );
- Assert( nz >= -1.05f && nz <= 1.05f );
- // FIXME: studiorender is passing in non-unit normals
- //float lengthSqd = nx*nx + ny*ny + nz*nz;
- //Assert( lengthSqd >= 0.95f && lengthSqd <= 1.05f );
-
- if ( T == VERTEX_COMPRESSION_ON )
- {
-#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 )
- PackNormal_SHORT2( nx, ny, nz, (unsigned int *)m_pCurrNormal );
-
-#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 )
- // NOTE: write the normal into the lower 16 bits of a word, clearing the top 16 bits - a userdata4
- // tangent must be written into the upper 16 bits by CompressedUserData() *AFTER* this.
-#ifdef _DEBUG
- Assert( m_bWrittenUserData == false );
- m_bWrittenNormal = true;
-#endif
- PackNormal_UBYTE4( nx, ny, nz, (unsigned int *)m_pCurrNormal );
-#endif
- }
- else
- {
- float *pDst = m_pCurrNormal;
- *pDst++ = nx;
- *pDst++ = ny;
- *pDst = nz;
- }
-}
-
-template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedNormal3fv( const float *n )
-{
- Assert( n );
- CompressedNormal3f<T>( n[0], n[1], n[2] );
-}
-
-
-//-----------------------------------------------------------------------------
-// Color setting methods
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::Color3f( float r, float g, float b )
-{
- Assert( m_pColor && m_pCurrColor );
- Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) );
- Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) );
- Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) );
-
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000;
-#else
- int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000;
-#endif
- *(int*)m_pCurrColor = col;
-}
-
-inline void CVertexBuilder::Color3fv( const float *rgb )
-{
- Assert(rgb);
- Assert( m_pColor && m_pCurrColor );
- Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) );
- Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) );
- Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) );
-
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000;
-#else
- int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000;
-#endif
- *(int*)m_pCurrColor = col;
-}
-
-inline void CVertexBuilder::Color4f( float r, float g, float b, float a )
-{
- Assert( m_pColor && m_pCurrColor );
- Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) && IsFinite(a) );
- Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) && (a >= 0.0) );
- Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0) );
-
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24);
-#else
- int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24);
-#endif
- *(int*)m_pCurrColor = col;
-}
-
-inline void CVertexBuilder::Color4fv( const float *rgba )
-{
- Assert(rgba);
- Assert( m_pColor && m_pCurrColor );
- Assert( IsFinite(rgba[0]) && IsFinite(rgba[1]) && IsFinite(rgba[2]) && IsFinite(rgba[3]) );
- Assert( (rgba[0] >= 0.0) && (rgba[1] >= 0.0) && (rgba[2] >= 0.0) && (rgba[3] >= 0.0) );
- Assert( (rgba[0] <= 1.0) && (rgba[1] <= 1.0) && (rgba[2] <= 1.0) && (rgba[3] <= 1.0) );
-
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(rgba[0])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[2]) << 16) | (FastFToC(rgba[3]) << 24);
-#else
- int col = (FastFToC(rgba[2])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[0]) << 16) | (FastFToC(rgba[3]) << 24);
-#endif
- *(int*)m_pCurrColor = col;
-}
-
-
-//-----------------------------------------------------------------------------
-// Faster versions of color
-//-----------------------------------------------------------------------------
-
-// note that on the OSX target (OpenGL) whenever there is vertex data being written as bytes - they need to be written in R,G,B,A memory order
-
-inline void CVertexBuilder::Color3ub( unsigned char r, unsigned char g, unsigned char b )
-{
- Assert( m_pColor && m_pCurrColor );
- #ifdef OPENGL_SWAP_COLORS
- int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory
- #else
- int col = b | (g << 8) | (r << 16) | 0xFF000000;
- #endif
-
- *(int*)m_pCurrColor = col;
-}
-
-inline void CVertexBuilder::Color3ubv( unsigned char const* rgb )
-{
- Assert(rgb);
- Assert( m_pColor && m_pCurrColor );
- #ifdef OPENGL_SWAP_COLORS
- int col = rgb[0] | (rgb[1] << 8) | (rgb[2] << 16) | 0xFF000000; // r, g, b, a in memory
- #else
- int col = rgb[2] | (rgb[1] << 8) | (rgb[0] << 16) | 0xFF000000;
- #endif
-
- *(int*)m_pCurrColor = col;
-}
-
-inline void CVertexBuilder::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
-{
- Assert( m_pColor && m_pCurrColor );
- #ifdef OPENGL_SWAP_COLORS
- int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory
- #else
- int col = b | (g << 8) | (r << 16) | (a << 24);
- #endif
-
- *(int*)m_pCurrColor = col;
-}
-
-inline void CVertexBuilder::Color4ubv( unsigned char const* rgba )
-{
- Assert( rgba );
- Assert( m_pColor && m_pCurrColor );
- #ifdef OPENGL_SWAP_COLORS
- int col = rgba[0] | (rgba[1] << 8) | (rgba[2] << 16) | (rgba[3] << 24); // r, g, b, a in memory
- #else
- int col = rgba[2] | (rgba[1] << 8) | (rgba[0] << 16) | (rgba[3] << 24);
- #endif
- *(int*)m_pCurrColor = col;
-}
-
-inline void CVertexBuilder::Specular3f( float r, float g, float b )
-{
- Assert( m_pSpecular );
- Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) );
- Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) );
- Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) );
-
- unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000;
-#else
- int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000;
-#endif
- *(int*)pSpecular = col;
-}
-
-inline void CVertexBuilder::Specular3fv( const float *rgb )
-{
- Assert(rgb);
- Assert( m_pSpecular );
- Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) );
- Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) );
- Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) );
-
- unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000;
-#else
- int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000;
-#endif
- *(int*)pSpecular = col;
-}
-
-inline void CVertexBuilder::Specular4f( float r, float g, float b, float a )
-{
- Assert( m_pSpecular );
- Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) && IsFinite(a) );
- Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) && (a >= 0.0) );
- Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0f) );
-
- unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24);
-#else
- int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24);
-#endif
- *(int*)pSpecular = col;
-}
-
-inline void CVertexBuilder::Specular4fv( const float *rgb )
-{
- Assert(rgb);
- Assert( m_pSpecular );
- Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) && IsFinite(rgb[3]) );
- Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) && (rgb[3] >= 0.0) );
- Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) && (rgb[3] <= 1.0) );
-
- unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-#ifdef OPENGL_SWAP_COLORS
- int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | (FastFToC(rgb[3]) << 24);
-#else
- int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | (FastFToC(rgb[3]) << 24);
-#endif
- *(int*)pSpecular = col;
-}
-
-inline void CVertexBuilder::Specular3ub( unsigned char r, unsigned char g, unsigned char b )
-{
- Assert( m_pSpecular );
- unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-
- #ifdef OPENGL_SWAP_COLORS
- int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory
- #else
- int col = b | (g << 8) | (r << 16) | 0xFF000000;
- #endif
-
- *(int*)pSpecular = col;
-}
-
-inline void CVertexBuilder::Specular3ubv( unsigned char const *c )
-{
- Assert( m_pSpecular );
- unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-
- #ifdef OPENGL_SWAP_COLORS
- int col = c[0] | (c[1] << 8) | (c[2] << 16) | 0xFF000000; // r, g, b, a in memory
- #else
- int col = c[2] | (c[1] << 8) | (c[0] << 16) | 0xFF000000;
- #endif
-
- *(int*)pSpecular = col;
-}
-
-inline void CVertexBuilder::Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
-{
- Assert( m_pSpecular );
- unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-
- #ifdef OPENGL_SWAP_COLORS
- int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory
- #else
- int col = b | (g << 8) | (r << 16) | (a << 24);
- #endif
-
- *(int*)pSpecular = col;
-}
-
-inline void CVertexBuilder::Specular4ubv( unsigned char const *c )
-{
- Assert( m_pSpecular );
- unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular];
-
- #ifdef OPENGL_SWAP_COLORS
- int col = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
- #else
- int col = c[2] | (c[1] << 8) | (c[0] << 16) | (c[3] << 24);
- #endif
-
- *(int*)pSpecular = col;
-}
-
-
-//-----------------------------------------------------------------------------
-// Texture coordinate setting methods
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::TexCoord1f( int nStage, float s )
-{
- Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] );
- Assert( IsFinite(s) );
-
- float *pDst = m_pCurrTexCoord[nStage];
- *pDst = s;
-}
-
-inline void CVertexBuilder::TexCoord2f( int nStage, float s, float t )
-{
- Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] );
- Assert( IsFinite(s) && IsFinite(t) );
-
- float *pDst = m_pCurrTexCoord[nStage];
- *pDst++ = s;
- *pDst = t;
-}
-
-inline void CVertexBuilder::TexCoord2fv( int nStage, const float *st )
-{
- Assert(st);
- Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] );
- Assert( IsFinite(st[0]) && IsFinite(st[1]) );
-
- float *pDst = m_pCurrTexCoord[nStage];
- *pDst++ = *st++;
- *pDst = *st;
-}
-
-inline void CVertexBuilder::TexCoord3f( int stage, float s, float t, float u )
-{
- // Tried to add too much!
- Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] );
- Assert( IsFinite(s) && IsFinite(t) && IsFinite(u) );
- float *pDst = m_pCurrTexCoord[stage];
- *pDst++ = s;
- *pDst++ = t;
- *pDst = u;
-}
-
-inline void CVertexBuilder::TexCoord3fv( int stage, const float *stu )
-{
- Assert(stu);
- Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] );
- Assert( IsFinite(stu[0]) && IsFinite(stu[1]) && IsFinite(stu[2]) );
-
- float *pDst = m_pCurrTexCoord[stage];
- *pDst++ = *stu++;
- *pDst++ = *stu++;
- *pDst = *stu;
-}
-
-inline void CVertexBuilder::TexCoord4f( int stage, float s, float t, float u, float v )
-{
- // Tried to add too much!
- Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] );
- Assert( IsFinite(s) && IsFinite(t) && IsFinite(u) );
- float *pDst = m_pCurrTexCoord[stage];
- *pDst++ = s;
- *pDst++ = t;
- *pDst++ = u;
- *pDst = v;
-}
-
-inline void CVertexBuilder::TexCoord4fv( int stage, const float *stuv )
-{
- Assert(stuv);
- Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] );
- Assert( IsFinite(stuv[0]) && IsFinite(stuv[1]) && IsFinite(stuv[2]) );
-
- float *pDst = m_pCurrTexCoord[stage];
- *pDst++ = *stuv++;
- *pDst++ = *stuv++;
- *pDst++ = *stuv++;
- *pDst = *stuv;
-}
-
-
-inline void CVertexBuilder::TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT )
-{
- Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] );
- Assert( IsFinite(s) && IsFinite(t) );
-
- float *pDst = m_pCurrTexCoord[stage];
- *pDst++ = ( s * scaleS ) + offsetS;
- *pDst = ( t * scaleT ) + offsetT;
-}
-
-inline void CVertexBuilder::TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale )
-{
- Assert(st);
- Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] );
- Assert( IsFinite(st[0]) && IsFinite(st[1]) );
-
- float *pDst = m_pCurrTexCoord[stage];
- *pDst++ = ( *st++ * *scale++ ) + *offset++;
- *pDst = ( *st * *scale ) + *offset;
-}
-
-
-//-----------------------------------------------------------------------------
-// Tangent space setting methods
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::TangentS3f( float sx, float sy, float sz )
-{
- Assert( m_pTangentS );
- Assert( IsFinite(sx) && IsFinite(sy) && IsFinite(sz) );
-
- float* pTangentS = OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS );
- *pTangentS++ = sx;
- *pTangentS++ = sy;
- *pTangentS = sz;
-}
-
-inline void CVertexBuilder::TangentS3fv( const float* s )
-{
- Assert( s );
- Assert( m_pTangentS );
- Assert( IsFinite(s[0]) && IsFinite(s[1]) && IsFinite(s[2]) );
-
- float* pTangentS = OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS );
- *pTangentS++ = *s++;
- *pTangentS++ = *s++;
- *pTangentS = *s;
-}
-
-inline void CVertexBuilder::TangentT3f( float tx, float ty, float tz )
-{
- Assert( m_pTangentT );
- Assert( IsFinite(tx) && IsFinite(ty) && IsFinite(tz) );
-
- float* pTangentT = OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT );
- *pTangentT++ = tx;
- *pTangentT++ = ty;
- *pTangentT = tz;
-}
-
-inline void CVertexBuilder::TangentT3fv( const float* t )
-{
- Assert( t );
- Assert( m_pTangentT );
- Assert( IsFinite(t[0]) && IsFinite(t[1]) && IsFinite(t[2]) );
-
- float* pTangentT = OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT );
- *pTangentT++ = *t++;
- *pTangentT++ = *t++;
- *pTangentT = *t;
-}
-
-
-//-----------------------------------------------------------------------------
-// Wrinkle setting methods
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::Wrinkle1f( float flWrinkle )
-{
- Assert( m_pWrinkle );
- Assert( IsFinite(flWrinkle) );
-
- float *pWrinkle = OffsetFloatPointer( m_pWrinkle, m_nCurrentVertex, m_VertexSize_Wrinkle );
- *pWrinkle = flWrinkle;
-}
-
-
-//-----------------------------------------------------------------------------
-// Bone weight setting methods
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::BoneWeight( int idx, float weight )
-{
- Assert( m_pBoneWeight );
- Assert( IsFinite( weight ) );
- Assert( idx >= 0 );
- AssertOnce( m_NumBoneWeights == 2 );
-
- // This test is here because we store N-1 bone weights (the Nth is computed in
- // the vertex shader as "1 - C", where C is the sum of the (N-1) other weights)
- if ( idx < m_NumBoneWeights )
- {
- float* pBoneWeight = OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight );
- pBoneWeight[idx] = weight;
- }
-}
-
-static int sg_IndexSwap[4] = { 2, 1, 0, 3 };
-
-inline void CVertexBuilder::BoneMatrix( int idx, int matrixIdx )
-{
- Assert( m_pBoneMatrixIndex );
- Assert( idx >= 0 );
- Assert( idx < 4 );
-
- // garymcthack
- if ( matrixIdx == BONE_MATRIX_INDEX_INVALID )
- {
- matrixIdx = 0;
- }
- Assert( (matrixIdx >= 0) && (matrixIdx < 53) );
-
-#ifdef OPENGL_SWAP_COLORS
- idx = sg_IndexSwap[idx];
-#endif
-
-#ifndef NEW_SKINNING
- unsigned char* pBoneMatrix = &m_pBoneMatrixIndex[m_nCurrentVertex * m_VertexSize_BoneMatrixIndex];
- if ( IsX360() )
- {
- // store sequentially as wzyx order, gpu delivers as xyzw
- idx = 3-idx;
- }
- pBoneMatrix[idx] = (unsigned char)matrixIdx;
-#else
- float* pBoneMatrix = &m_pBoneMatrixIndex[m_nCurrentVertex * m_VertexSize_BoneMatrixIndex];
- pBoneMatrix[idx] = matrixIdx;
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Templatized bone weight setting methods which support compressed vertices
-//-----------------------------------------------------------------------------
-template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedBoneWeight3fv( const float * pWeights )
-{
- Assert( T == m_CompressionType );
- Assert( m_pBoneWeight );
- Assert( pWeights );
-
- float *pDestWeights = OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight );
-
- if ( T == VERTEX_COMPRESSION_ON )
- {
- // Quantize to 15 bits per weight (we use D3DDECLTYPE_SHORT2)
- // NOTE: we perform careful normalization (weights sum to 1.0f in the vertex shader), so
- // as to avoid cracking at boundaries between meshes with different numbers of weights
- // per vertex. For example, (1) needs to yield the same normalized weights as (1,0),
- // and (0.5,0.49) needs to normalize the same normalized weights as (0.5,0.49,0).
- // The key is that values which are *computed* in the shader (e.g. the second weight
- // in a 2-weight mesh) must exactly equal values which are *read* from the vertex
- // stream (e.g. the second weight in a 3-weight mesh).
-
- // Only 1 or 2 weights (SHORT2N) supported for compressed verts so far
- Assert( m_NumBoneWeights <= 2 );
-
- const int WEIGHT0_SHIFT = IsX360() ? 16 : 0;
- const int WEIGHT1_SHIFT = IsX360() ? 0 : 16;
- unsigned int *weights = (unsigned int *)pDestWeights;
-
- // We scale our weights so that they sum to 32768, then subtract 1 (which gets added
- // back in the shader), because dividing by 32767 introduces nasty rounding issues.
- Assert( IsFinite( pWeights[0] ) && ( pWeights[0] >= 0.0f ) && ( pWeights[0] <= 1.0f ) );
- unsigned int weight0 = Float2Int( pWeights[0] * 32768.0f );
- *weights = ( 0x0000FFFF & (weight0 - 1) ) << WEIGHT0_SHIFT;
-
-#ifdef DEBUG
- if ( m_NumBoneWeights == 1 )
- {
- // Double-check the validity of the values that were passed in
- Assert( IsFinite( pWeights[1] ) && ( pWeights[1] >= 0.0f ) && ( pWeights[1] <= 1.0f ) );
- unsigned int weight1 = Float2Int( pWeights[1] * 32768.0f );
- Assert( ( weight0 + weight1 ) <= 32768 );
- }
-#endif
-
- if ( m_NumBoneWeights > 1 )
- {
- // This path for 3 weights per vert (2 are stored and the 3rd is computed
- // in the shader - we do post-quantization normalization here in such a
- // way as to avoid mesh-boundary cracking)
- Assert( m_NumBoneWeights == 2 );
- Assert( IsFinite( pWeights[1] ) && ( pWeights[1] >= 0.0f ) && ( pWeights[1] <= 1.0f ) );
- Assert( IsFinite( pWeights[2] ) && ( pWeights[2] >= 0.0f ) && ( pWeights[2] <= 1.0f ) );
- unsigned int weight1 = Float2Int( pWeights[1] * 32768.0f );
- unsigned int weight2 = Float2Int( pWeights[2] * 32768.0f );
- Assert( ( weight0 + weight1 + weight2 ) <= 32768 );
- unsigned int residual = 32768 - ( weight0 + weight1 + weight2 );
- weight1 += residual; // Normalize
- *weights |= ( 0x0000FFFF & ( weight1 - 1 ) ) << WEIGHT1_SHIFT;
- }
- }
- else // Uncompressed path
- {
- pDestWeights[0] = pWeights[0];
- pDestWeights[1] = pWeights[1];
- }
-}
-
-//-----------------------------------------------------------------------------
-// Generic per-vertex data setting method
-//-----------------------------------------------------------------------------
-inline void CVertexBuilder::UserData( const float* pData )
-{
- Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression
- Assert( pData );
-
- int userDataSize = 4; // garymcthack
- float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData );
- memcpy( pUserData, pData, sizeof( float ) * userDataSize );
-}
-
-//-----------------------------------------------------------------------------
-// Templatized generic per-vertex data setting method which supports compressed vertices
-//-----------------------------------------------------------------------------
-template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedUserData( const float* pData )
-{
- Assert( T == m_CompressionType );
- Assert( pData );
- // This is always in fact a tangent vector, not generic 'userdata'
- Assert( IsFinite(pData[0]) && IsFinite(pData[1]) && IsFinite(pData[2]) );
- Assert( pData[0] >= -1.05f && pData[0] <= 1.05f );
- Assert( pData[1] >= -1.05f && pData[1] <= 1.05f );
- Assert( pData[2] >= -1.05f && pData[2] <= 1.05f );
- Assert( pData[3] == +1.0f || pData[3] == -1.0f );
- // FIXME: studiorender is passing in non-unit normals
- //float lengthSqd = pData[0]*pData[0] + pData[1]*pData[1] + pData[2]*pData[2];
- //Assert( lengthSqd >= 0.95f && lengthSqd <= 1.05f );
-
- if ( T == VERTEX_COMPRESSION_ON )
- {
- float binormalSign = pData[3];
-
-#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 )
- float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData );
- PackNormal_SHORT2( pData, (unsigned int *)pUserData, binormalSign );
-#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 )
- // FIXME: add a combined CompressedNormalAndTangent() accessor, to avoid reading back from write-combined memory here
- // The normal should have already been written into the lower 16
- // bits - here, we OR in the tangent into the upper 16 bits
- unsigned int existingNormalData = *(unsigned int *)m_pCurrNormal;
- Assert( ( existingNormalData & 0xFFFF0000 ) == 0 );
-#ifdef _DEBUG
- Assert( m_bWrittenNormal == true );
- m_bWrittenUserData = true;
-#endif
- bool bIsTangent = true;
- unsigned int tangentData = 0;
- PackNormal_UBYTE4( pData, &tangentData, bIsTangent, binormalSign );
- *(unsigned int *)m_pCurrNormal = existingNormalData | tangentData;
-#endif
- }
- else
- {
- int userDataSize = 4; // garymcthack
- float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData );
- memcpy( pUserData, pData, sizeof( float ) * userDataSize );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-//
-// Helper class used to define index buffers
-//
-//-----------------------------------------------------------------------------
-class CIndexBuilder : private IndexDesc_t
-{
-public:
- CIndexBuilder();
- CIndexBuilder( IIndexBuffer *pIndexBuffer, MaterialIndexFormat_t fmt = MATERIAL_INDEX_FORMAT_UNKNOWN );
- ~CIndexBuilder();
-
- // Begins, ends modification of the index buffer (returns true if the lock succeeded)
- // A lock may not succeed if append is set to true and there isn't enough room
- // NOTE: Append is only used with dynamic index buffers; it's ignored for static buffers
- bool Lock( int nMaxIndexCount, int nIndexOffset, bool bAppend = false );
- void Unlock();
-
- // Spews the current data
- // NOTE: Can only be called during a lock/unlock block
- void SpewData();
-
- // Returns the number of indices we can fit into the buffer without needing to discard
- int GetRoomRemaining() const;
-
- // Binds this index buffer
- void Bind( IMatRenderContext *pContext );
-
- // Returns the byte offset
- int Offset() const;
-
- // Begins, ends modification of the index buffer
- // NOTE: IndexOffset is the number to add to all indices written into the buffer;
- // useful when using dynamic vertex buffers.
- void Begin( IIndexBuffer *pIndexBuffer, int nMaxIndexCount, int nIndexOffset = 0 );
- void End( bool bSpewData = false );
-
- // Locks the index buffer to modify existing data
- // Passing nVertexCount == -1 says to lock all the vertices for modification.
- // Pass 0 for nIndexCount to not lock the index buffer.
- void BeginModify( IIndexBuffer *pIndexBuffer, int nFirstIndex = 0, int nIndexCount = 0, int nIndexOffset = 0 );
- void EndModify( bool bSpewData = false );
-
- // returns the number of indices
- int IndexCount() const;
-
- // Returns the total number of indices across all Locks()
- int TotalIndexCount() const;
-
- // Resets the mesh builder so it points to the start of everything again
- void Reset();
-
- // Selects the nth Index
- void SelectIndex( int nBufferIndex );
-
- // Advances the current index by one
- void AdvanceIndex();
- void AdvanceIndices( int nIndexCount );
-
- int GetCurrentIndex();
- int GetFirstIndex() const;
-
- unsigned short const* Index() const;
-
- // Used to define the indices (only used if you aren't using primitives)
- void Index( unsigned short nIndex );
-
- // Fast Index! No need to call advance index, and no random access allowed
- void FastIndex( unsigned short nIndex );
-
- // NOTE: This version is the one you really want to achieve write-combining;
- // Write combining only works if you write in 4 bytes chunks.
- void FastIndex2( unsigned short nIndex1, unsigned short nIndex2 );
-
- // Generates indices for a particular primitive type
- void GenerateIndices( MaterialPrimitiveType_t primitiveType, int nIndexCount );
-
- // FIXME: Remove! Backward compat so we can use this from a CMeshBuilder.
- void AttachBegin( IMesh* pMesh, int nMaxIndexCount, const MeshDesc_t &desc );
- void AttachEnd();
- void AttachBeginModify( IMesh* pMesh, int nFirstIndex, int nIndexCount, const MeshDesc_t &desc );
- void AttachEndModify();
-
- void FastTriangle( int startVert );
- void FastQuad( int startVert );
- void FastPolygon( int startVert, int numTriangles );
- void FastPolygonList( int startVert, int *pVertexCount, int polygonCount );
- void FastIndexList( const unsigned short *pIndexList, int startVert, int indexCount );
-
-private:
- // The mesh we're modifying
- IIndexBuffer *m_pIndexBuffer;
-
- // Max number of indices
- int m_nMaxIndexCount;
-
- // Number of indices
- int m_nIndexCount;
-
- // Offset to add to each index as it's written into the buffer
- int m_nIndexOffset;
-
- // The current index
- mutable int m_nCurrentIndex;
-
- // Total number of indices appended
- int m_nTotalIndexCount;
-
- // First index buffer offset + first index
- unsigned int m_nBufferOffset;
- unsigned int m_nBufferFirstIndex;
-
- // Used to make sure Begin/End calls and BeginModify/EndModify calls match.
- bool m_bModify;
-};
-
-
-//-----------------------------------------------------------------------------
-//
-// Inline methods related to CIndexBuilder
-//
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-inline CIndexBuilder::CIndexBuilder() : m_pIndexBuffer(0), m_nIndexCount(0),
- m_nCurrentIndex(0), m_nMaxIndexCount(0)
-{
- m_nTotalIndexCount = 0;
- m_nBufferOffset = INVALID_BUFFER_OFFSET;
- m_nBufferFirstIndex = 0;
-#ifdef _DEBUG
- m_bModify = false;
-#endif
-}
-
-inline CIndexBuilder::CIndexBuilder( IIndexBuffer *pIndexBuffer, MaterialIndexFormat_t fmt )
-{
- m_pIndexBuffer = pIndexBuffer;
- m_nBufferOffset = INVALID_BUFFER_OFFSET;
- m_nBufferFirstIndex = 0;
- m_nIndexCount = 0;
- m_nCurrentIndex = 0;
- m_nMaxIndexCount = 0;
- m_nTotalIndexCount = 0;
- if ( m_pIndexBuffer->IsDynamic() )
- {
- m_pIndexBuffer->BeginCastBuffer( fmt );
- }
- else
- {
- Assert( m_pIndexBuffer->IndexFormat() == fmt );
- }
-#ifdef _DEBUG
- m_bModify = false;
-#endif
-}
-
-inline CIndexBuilder::~CIndexBuilder()
-{
- if ( m_pIndexBuffer && m_pIndexBuffer->IsDynamic() )
- {
- m_pIndexBuffer->EndCastBuffer();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Begins, ends modification of the index buffer
-//-----------------------------------------------------------------------------
-inline bool CIndexBuilder::Lock( int nMaxIndexCount, int nIndexOffset, bool bAppend )
-{
- Assert( m_pIndexBuffer );
- m_bModify = false;
- m_nIndexOffset = nIndexOffset;
- m_nMaxIndexCount = nMaxIndexCount;
- bool bFirstLock = ( m_nBufferOffset == INVALID_BUFFER_OFFSET );
- if ( bFirstLock )
- {
- bAppend = false;
- }
- if ( !bAppend )
- {
- m_nTotalIndexCount = 0;
- }
- Reset();
-
- // Lock the index buffer
- if ( !m_pIndexBuffer->Lock( m_nMaxIndexCount, bAppend, *this ) )
- {
- m_nMaxIndexCount = 0;
- return false;
- }
-
- if ( bFirstLock )
- {
- m_nBufferOffset = m_nOffset;
- m_nBufferFirstIndex = m_nFirstIndex;
- }
-
- return true;
-}
-
-inline void CIndexBuilder::Unlock()
-{
- Assert( !m_bModify && m_pIndexBuffer );
-
- m_pIndexBuffer->Unlock( m_nIndexCount, *this );
- m_nTotalIndexCount += m_nIndexCount;
-
- m_nMaxIndexCount = 0;
-
-#ifdef _DEBUG
- // Null out our data...
- memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) );
-#endif
-}
-
-inline void CIndexBuilder::SpewData()
-{
- m_pIndexBuffer->Spew( m_nIndexCount, *this );
-}
-
-
-//-----------------------------------------------------------------------------
-// Binds this index buffer
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::Bind( IMatRenderContext *pContext )
-{
- if ( m_pIndexBuffer && ( m_nBufferOffset != INVALID_BUFFER_OFFSET ) )
- {
- pContext->BindIndexBuffer( m_pIndexBuffer, m_nBufferOffset );
- }
- else
- {
- pContext->BindIndexBuffer( NULL, 0 );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the byte offset
-//-----------------------------------------------------------------------------
-inline int CIndexBuilder::Offset() const
-{
- return m_nBufferOffset;
-}
-
-inline int CIndexBuilder::GetFirstIndex() const
-{
- return m_nBufferFirstIndex;
-}
-
-
-//-----------------------------------------------------------------------------
-// Begins, ends modification of the index buffer
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::Begin( IIndexBuffer *pIndexBuffer, int nMaxIndexCount, int nIndexOffset )
-{
- Assert( pIndexBuffer && (!m_pIndexBuffer) );
-
- m_pIndexBuffer = pIndexBuffer;
- m_nIndexCount = 0;
- m_nMaxIndexCount = nMaxIndexCount;
- m_nIndexOffset = nIndexOffset;
-
- m_bModify = false;
-
- // Lock the index buffer
- m_pIndexBuffer->Lock( m_nMaxIndexCount, false, *this );
-
- // Point to the start of the buffers..
- Reset();
-}
-
-inline void CIndexBuilder::End( bool bSpewData )
-{
- // Make sure they called Begin()
- Assert( !m_bModify );
-
- if ( bSpewData )
- {
- m_pIndexBuffer->Spew( m_nIndexCount, *this );
- }
-
- // Unlock our buffers
- m_pIndexBuffer->Unlock( m_nIndexCount, *this );
-
- m_pIndexBuffer = 0;
- m_nMaxIndexCount = 0;
-
-#ifdef _DEBUG
- // Null out our data...
- memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Begins, ends modification of an existing index buffer which has already been filled out
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::BeginModify( IIndexBuffer* pIndexBuffer, int nFirstIndex, int nIndexCount, int nIndexOffset )
-{
- m_pIndexBuffer = pIndexBuffer;
- m_nIndexCount = nIndexCount;
- m_nMaxIndexCount = nIndexCount;
- m_nIndexOffset = nIndexOffset;
- m_bModify = true;
-
- // Lock the vertex and index buffer
- m_pIndexBuffer->ModifyBegin( false, nFirstIndex, nIndexCount, *this );
-
- // Point to the start of the buffers..
- Reset();
-}
-
-inline void CIndexBuilder::EndModify( bool bSpewData )
-{
- Assert( m_pIndexBuffer );
- Assert( m_bModify ); // Make sure they called BeginModify.
-
- if ( bSpewData )
- {
- m_pIndexBuffer->Spew( m_nIndexCount, *this );
- }
-
- // Unlock our buffers
- m_pIndexBuffer->ModifyEnd( *this );
-
- m_pIndexBuffer = 0;
- m_nMaxIndexCount = 0;
-
-#ifdef _DEBUG
- // Null out our data...
- memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// FIXME: Remove! Backward compat so we can use this from a CMeshBuilder.
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::AttachBegin( IMesh* pMesh, int nMaxIndexCount, const MeshDesc_t &desc )
-{
- m_pIndexBuffer = pMesh;
- m_nIndexCount = 0;
- m_nMaxIndexCount = nMaxIndexCount;
-
- m_bModify = false;
-
- // Copy relevant data from the mesh desc
- m_nIndexOffset = desc.m_nFirstVertex;
- m_pIndices = desc.m_pIndices;
- m_nIndexSize = desc.m_nIndexSize;
-
- // Point to the start of the buffers..
- Reset();
-}
-
-inline void CIndexBuilder::AttachEnd()
-{
- Assert( m_pIndexBuffer );
- Assert( !m_bModify ); // Make sure they called AttachBegin.
-
- m_pIndexBuffer = 0;
- m_nMaxIndexCount = 0;
-
-#ifdef _DEBUG
- // Null out our data...
- memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) );
-#endif
-}
-
-inline void CIndexBuilder::AttachBeginModify( IMesh* pMesh, int nFirstIndex, int nIndexCount, const MeshDesc_t &desc )
-{
- m_pIndexBuffer = pMesh;
- m_nIndexCount = nIndexCount;
- m_nMaxIndexCount = nIndexCount;
- m_bModify = true;
-
- // Copy relevant data from the mesh desc
- m_nIndexOffset = desc.m_nFirstVertex;
- m_pIndices = desc.m_pIndices;
- m_nIndexSize = desc.m_nIndexSize;
-
- // Point to the start of the buffers..
- Reset();
-}
-
-inline void CIndexBuilder::AttachEndModify()
-{
- Assert( m_pIndexBuffer );
- Assert( m_bModify ); // Make sure they called AttachBeginModify.
-
- m_pIndexBuffer = 0;
- m_nMaxIndexCount = 0;
-
-#ifdef _DEBUG
- // Null out our data...
- memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Resets the index buffer builder so it points to the start of everything again
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::Reset()
-{
- m_nCurrentIndex = 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// returns the number of indices
-//-----------------------------------------------------------------------------
-inline int CIndexBuilder::IndexCount() const
-{
- return m_nIndexCount;
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the total number of indices across all Locks()
-//-----------------------------------------------------------------------------
-inline int CIndexBuilder::TotalIndexCount() const
-{
- return m_nTotalIndexCount;
-}
-
-
-//-----------------------------------------------------------------------------
-// Advances the current index
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::AdvanceIndex()
-{
- m_nCurrentIndex += m_nIndexSize;
- if ( m_nCurrentIndex > m_nIndexCount )
- {
- m_nIndexCount = m_nCurrentIndex;
- }
-}
-
-inline void CIndexBuilder::AdvanceIndices( int nIndices )
-{
- m_nCurrentIndex += nIndices * m_nIndexSize;
- if ( m_nCurrentIndex > m_nIndexCount )
- {
- m_nIndexCount = m_nCurrentIndex;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the current index
-//-----------------------------------------------------------------------------
-inline int CIndexBuilder::GetCurrentIndex()
-{
- return m_nCurrentIndex;
-}
-
-inline unsigned short const* CIndexBuilder::Index() const
-{
- Assert( m_nCurrentIndex < m_nMaxIndexCount );
- return &m_pIndices[m_nCurrentIndex];
-}
-
-inline void CIndexBuilder::SelectIndex( int nIndex )
-{
- Assert( ( nIndex >= 0 ) && ( nIndex < m_nIndexCount ) );
- m_nCurrentIndex = nIndex * m_nIndexSize;
-}
-
-
-//-----------------------------------------------------------------------------
-// Used to write data into the index buffer
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::Index( unsigned short nIndex )
-{
- Assert( m_pIndices );
- Assert( m_nCurrentIndex < m_nMaxIndexCount );
- m_pIndices[ m_nCurrentIndex ] = (unsigned short)( m_nIndexOffset + nIndex );
-}
-
-// Fast Index! No need to call advance index
-inline void CIndexBuilder::FastIndex( unsigned short nIndex )
-{
- Assert( m_pIndices );
- Assert( m_nCurrentIndex < m_nMaxIndexCount );
- m_pIndices[m_nCurrentIndex] = (unsigned short)( m_nIndexOffset + nIndex );
- m_nCurrentIndex += m_nIndexSize;
- m_nIndexCount = m_nCurrentIndex;
-}
-
-inline void CIndexBuilder::FastTriangle( int startVert )
-{
- startVert += m_nIndexOffset;
- m_pIndices[m_nCurrentIndex+0] = startVert;
- m_pIndices[m_nCurrentIndex+1] = startVert + 1;
- m_pIndices[m_nCurrentIndex+2] = startVert + 2;
-
- AdvanceIndices(3);
-}
-
-inline void CIndexBuilder::FastQuad( int startVert )
-{
- startVert += m_nIndexOffset;
- m_pIndices[m_nCurrentIndex+0] = startVert;
- m_pIndices[m_nCurrentIndex+1] = startVert + 1;
- m_pIndices[m_nCurrentIndex+2] = startVert + 2;
- m_pIndices[m_nCurrentIndex+3] = startVert;
- m_pIndices[m_nCurrentIndex+4] = startVert + 2;
- m_pIndices[m_nCurrentIndex+5] = startVert + 3;
- AdvanceIndices(6);
-}
-
-inline void CIndexBuilder::FastPolygon( int startVert, int triangleCount )
-{
- unsigned short *pIndex = &m_pIndices[m_nCurrentIndex];
- startVert += m_nIndexOffset;
- if ( !IsX360() )
- {
- // NOTE: IndexSize is 1 or 0 (0 for alt-tab)
- // This prevents us from writing into bogus memory
- Assert( m_nIndexSize == 0 || m_nIndexSize == 1 );
- triangleCount *= m_nIndexSize;
- }
- for ( int v = 0; v < triangleCount; ++v )
- {
- *pIndex++ = startVert;
- *pIndex++ = startVert + v + 1;
- *pIndex++ = startVert + v + 2;
- }
- AdvanceIndices(triangleCount*3);
-}
-
-inline void CIndexBuilder::FastPolygonList( int startVert, int *pVertexCount, int polygonCount )
-{
- unsigned short *pIndex = &m_pIndices[m_nCurrentIndex];
- startVert += m_nIndexOffset;
- int indexOut = 0;
-
- if ( !IsX360() )
- {
- // NOTE: IndexSize is 1 or 0 (0 for alt-tab)
- // This prevents us from writing into bogus memory
- Assert( m_nIndexSize == 0 || m_nIndexSize == 1 );
- polygonCount *= m_nIndexSize;
- }
-
- for ( int i = 0; i < polygonCount; i++ )
- {
- int vertexCount = pVertexCount[i];
- int triangleCount = vertexCount-2;
- for ( int v = 0; v < triangleCount; ++v )
- {
- *pIndex++ = startVert;
- *pIndex++ = startVert + v + 1;
- *pIndex++ = startVert + v + 2;
- }
- startVert += vertexCount;
- indexOut += triangleCount * 3;
- }
- AdvanceIndices(indexOut);
-}
-
-inline void CIndexBuilder::FastIndexList( const unsigned short *pIndexList, int startVert, int indexCount )
-{
- unsigned short *pIndexOut = &m_pIndices[m_nCurrentIndex];
- startVert += m_nIndexOffset;
- if ( !IsX360() )
- {
- // NOTE: IndexSize is 1 or 0 (0 for alt-tab)
- // This prevents us from writing into bogus memory
- Assert( m_nIndexSize == 0 || m_nIndexSize == 1 );
- indexCount *= m_nIndexSize;
- }
- for ( int i = 0; i < indexCount; ++i )
- {
- pIndexOut[i] = startVert + pIndexList[i];
- }
- AdvanceIndices(indexCount);
-}
-
-
-//-----------------------------------------------------------------------------
-// NOTE: This version is the one you really want to achieve write-combining;
-// Write combining only works if you write in 4 bytes chunks.
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::FastIndex2( unsigned short nIndex1, unsigned short nIndex2 )
-{
- Assert( m_pIndices );
- Assert( m_nCurrentIndex < m_nMaxIndexCount - 1 );
-// Assert( ( (int)( &m_pIndices[m_nCurrentIndex] ) & 0x3 ) == 0 );
-
-#ifndef _X360
- unsigned int nIndices = ( (unsigned int)nIndex1 + m_nIndexOffset ) | ( ( (unsigned int)nIndex2 + m_nIndexOffset ) << 16 );
-#else
- unsigned int nIndices = ( (unsigned int)nIndex2 + m_nIndexOffset ) | ( ( (unsigned int)nIndex1 + m_nIndexOffset ) << 16 );
-#endif
-
- *(int*)( &m_pIndices[m_nCurrentIndex] ) = nIndices;
- m_nCurrentIndex += m_nIndexSize + m_nIndexSize;
- m_nIndexCount = m_nCurrentIndex;
-}
-
-
-//-----------------------------------------------------------------------------
-// Generates indices for a particular primitive type
-//-----------------------------------------------------------------------------
-inline void CIndexBuilder::GenerateIndices( MaterialPrimitiveType_t primitiveType, int nIndexCount )
-{
- // FIXME: How to make this work with short vs int sized indices?
- // Don't generate indices if we've got an empty buffer
- if ( m_nIndexSize == 0 )
- return;
-
- int nMaxIndices = m_nMaxIndexCount - m_nCurrentIndex;
- nIndexCount = Min( nMaxIndices, nIndexCount );
- if ( nIndexCount == 0 )
- return;
-
- unsigned short *pIndices = &m_pIndices[m_nCurrentIndex];
-
- switch( primitiveType )
- {
- case MATERIAL_INSTANCED_QUADS:
- Assert(0); // Shouldn't get here (this primtype is unindexed)
- break;
- case MATERIAL_QUADS:
- GenerateQuadIndexBuffer( pIndices, nIndexCount, m_nIndexOffset );
- break;
- case MATERIAL_POLYGON:
- GeneratePolygonIndexBuffer( pIndices, nIndexCount, m_nIndexOffset );
- break;
- case MATERIAL_LINE_STRIP:
- GenerateLineStripIndexBuffer( pIndices, nIndexCount, m_nIndexOffset );
- break;
- case MATERIAL_LINE_LOOP:
- GenerateLineLoopIndexBuffer( pIndices, nIndexCount, m_nIndexOffset );
- break;
- case MATERIAL_POINTS:
- Assert(0); // Shouldn't get here (this primtype is unindexed)
- break;
- default:
- GenerateSequentialIndexBuffer( pIndices, nIndexCount, m_nIndexOffset );
- break;
- }
-
- AdvanceIndices( nIndexCount );
-}
-
-
-//-----------------------------------------------------------------------------
-//
-// Helper class used to define meshes
-//
-//-----------------------------------------------------------------------------
-//class CMeshBuilder : private MeshDesc_t
-// hack fixme
-class CMeshBuilder : public MeshDesc_t
-{
-public:
- CMeshBuilder();
- ~CMeshBuilder() { Assert(!m_pMesh); } // if this fires you did a Begin() without an End()
-
- operator CIndexBuilder&() { return m_IndexBuilder; }
-
- // This must be called before Begin, if a vertex buffer with a compressed format is to be used
- void SetCompressionType( VertexCompressionType_t compressionType );
-
- // Locks the vertex buffer
- // (*cannot* use the Index() call below)
- void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int numPrimitives );
-
- // Locks the vertex buffer, can specify arbitrary index lists
- // (must use the Index() call below)
- void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex );
- void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount );
-
- // forward compat
- void Begin( IVertexBuffer *pVertexBuffer, MaterialPrimitiveType_t type, int numPrimitives );
- void Begin( IVertexBuffer *pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex );
- void Begin( IVertexBuffer *pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount );
-
- // Use this when you're done writing
- // Set bDraw to true to call m_pMesh->Draw automatically.
- void End( bool bSpewData = false, bool bDraw = false );
-
- // Locks the vertex buffer to modify existing data
- // Passing nVertexCount == -1 says to lock all the vertices for modification.
- // Pass 0 for nIndexCount to not lock the index buffer.
- void BeginModify( IMesh *pMesh, int nFirstVertex = 0, int nVertexCount = -1, int nFirstIndex = 0, int nIndexCount = 0 );
- void EndModify( bool bSpewData = false );
-
- // A helper method since this seems to be done a whole bunch.
- void DrawQuad( IMesh* pMesh, const float *v1, const float *v2,
- const float *v3, const float *v4, unsigned char const *pColor, bool wireframe = false );
-
- // returns the number of indices and vertices
- int VertexCount() const;
- int IndexCount() const;
-
- // Resets the mesh builder so it points to the start of everything again
- void Reset();
-
- // Returns the size of the vertex
- int VertexSize() { return m_ActualVertexSize; }
-
- // returns the data size of a given texture coordinate
- int TextureCoordinateSize( int nTexCoordNumber ) { return m_VertexSize_TexCoord[ nTexCoordNumber ]; }
-
- // Returns the base vertex memory pointer
- void* BaseVertexData();
-
- // Selects the nth Vertex and Index
- void SelectVertex( int idx );
- void SelectIndex( int idx );
-
- // Given an index, point to the associated vertex
- void SelectVertexFromIndex( int idx );
-
- // Advances the current vertex and index by one
- void AdvanceVertex();
- template<int nFlags, int nNumTexCoords> void AdvanceVertexF();
- void AdvanceVertices( int nVerts );
- void AdvanceIndex();
- void AdvanceIndices( int nIndices );
-
- int GetCurrentVertex();
- int GetCurrentIndex();
-
- // Data retrieval...
- const float *Position() const;
-
- const float *Normal() const;
-
- unsigned int Color() const;
-
- unsigned char *Specular() const;
-
- const float *TexCoord( int stage ) const;
-
- const float *TangentS() const;
- const float *TangentT() const;
-
- const float *BoneWeight() const;
- float Wrinkle() const;
-
- int NumBoneWeights() const;
-#ifndef NEW_SKINNING
- unsigned char *BoneMatrix() const;
-#else
- float *BoneMatrix() const;
-#endif
- unsigned short const *Index() const;
-
- // position setting
- void Position3f( float x, float y, float z );
- void Position3fv( const float *v );
-
- // normal setting
- void Normal3f( float nx, float ny, float nz );
- void Normal3fv( const float *n );
- void NormalDelta3fv( const float *n );
- void NormalDelta3f( float nx, float ny, float nz );
-
- // normal setting (templatized for code which needs to support compressed vertices)
- template <VertexCompressionType_t T> void CompressedNormal3f( float nx, float ny, float nz );
- template <VertexCompressionType_t T> void CompressedNormal3fv( const float *n );
-
- // color setting
- void Color3f( float r, float g, float b );
- void Color3fv( const float *rgb );
- void Color4f( float r, float g, float b, float a );
- void Color4fv( const float *rgba );
-
- // Faster versions of color
- void Color3ub( unsigned char r, unsigned char g, unsigned char b );
- void Color3ubv( unsigned char const* rgb );
- void Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a );
- void Color4ubv( unsigned char const* rgba );
-
- // specular color setting
- void Specular3f( float r, float g, float b );
- void Specular3fv( const float *rgb );
- void Specular4f( float r, float g, float b, float a );
- void Specular4fv( const float *rgba );
-
- // Faster version of specular
- void Specular3ub( unsigned char r, unsigned char g, unsigned char b );
- void Specular3ubv( unsigned char const *c );
- void Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a );
- void Specular4ubv( unsigned char const *c );
-
- // texture coordinate setting
- void TexCoord1f( int stage, float s );
- void TexCoord2f( int stage, float s, float t );
- void TexCoord2fv( int stage, const float *st );
- void TexCoord3f( int stage, float s, float t, float u );
- void TexCoord3fv( int stage, const float *stu );
- void TexCoord4f( int stage, float s, float t, float u, float w );
- void TexCoord4fv( int stage, const float *stuv );
-
- void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT );
- void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale );
-
- // tangent space
- void TangentS3f( float sx, float sy, float sz );
- void TangentS3fv( const float *s );
-
- void TangentT3f( float tx, float ty, float tz );
- void TangentT3fv( const float *t );
-
- // Wrinkle
- void Wrinkle1f( float flWrinkle );
-
- // bone weights
- void BoneWeight( int idx, float weight );
- // bone weights (templatized for code which needs to support compressed vertices)
- template <VertexCompressionType_t T> void CompressedBoneWeight3fv( const float * pWeights );
-
- // bone matrix index
- void BoneMatrix( int idx, int matrixIndex );
-
- // Generic per-vertex data
- void UserData( const float *pData );
- // Generic per-vertex data (templatized for code which needs to support compressed vertices)
- template <VertexCompressionType_t T> void CompressedUserData( const float* pData );
-
- // Used to define the indices (only used if you aren't using primitives)
- void Index( unsigned short index );
-
- // NOTE: Use this one to get write combining! Much faster than the other version of FastIndex
- // Fast Index! No need to call advance index, and no random access allowed
- void FastIndex2( unsigned short nIndex1, unsigned short nIndex2 );
-
- // Fast Index! No need to call advance index, and no random access allowed
- void FastIndex( unsigned short index );
-
- // Fast Vertex! No need to call advance vertex, and no random access allowed.
- // WARNING - these are low level functions that are intended only for use
- // in the software vertex skinner.
- void FastVertex( const ModelVertexDX7_t &vertex );
- void FastVertexSSE( const ModelVertexDX7_t &vertex );
-
- // store 4 dx7 vertices fast. for special sse dx7 pipeline
- void Fast4VerticesSSE(
- ModelVertexDX7_t const *vtx_a,
- ModelVertexDX7_t const *vtx_b,
- ModelVertexDX7_t const *vtx_c,
- ModelVertexDX7_t const *vtx_d);
-
- void FastVertex( const ModelVertexDX8_t &vertex );
- void FastVertexSSE( const ModelVertexDX8_t &vertex );
-
- // Add number of verts and current vert since FastVertexxx routines do not update.
- void FastAdvanceNVertices(int n);
-
-#if defined( _X360 )
- void VertexDX8ToX360( const ModelVertexDX8_t &vertex );
-#endif
-
-private:
- // Computes number of verts and indices
- void ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices,
- MaterialPrimitiveType_t type, int nPrimitiveCount );
- int IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount );
-
- // The mesh we're modifying
- IMesh *m_pMesh;
-
- MaterialPrimitiveType_t m_Type;
-
- // Generate indices?
- bool m_bGenerateIndices;
-
- CIndexBuilder m_IndexBuilder;
- CVertexBuilder m_VertexBuilder;
-};
-
-
-//-----------------------------------------------------------------------------
-// Forward compat
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, MaterialPrimitiveType_t type, int numPrimitives )
-{
- Assert( 0 );
- // Begin( pVertexBuffer->GetMesh(), type, numPrimitives );
-}
-
-inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex )
-{
- Assert( 0 );
- // Begin( pVertexBuffer->GetMesh(), type, nVertexCount, nIndexCount, nFirstVertex );
-}
-
-inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount )
-{
- Assert( 0 );
- // Begin( pVertexBuffer->GetMesh(), type, nVertexCount, nIndexCount );
-}
-
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-inline CMeshBuilder::CMeshBuilder() : m_pMesh(0), m_bGenerateIndices(false)
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Computes the number of verts and indices based on primitive type and count
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices,
- MaterialPrimitiveType_t type, int nPrimitiveCount )
-{
- switch(type)
- {
- case MATERIAL_POINTS:
- *pMaxVertices = *pMaxIndices = nPrimitiveCount;
- break;
-
- case MATERIAL_LINES:
- *pMaxVertices = *pMaxIndices = nPrimitiveCount * 2;
- break;
-
- case MATERIAL_LINE_STRIP:
- *pMaxVertices = nPrimitiveCount + 1;
- *pMaxIndices = nPrimitiveCount * 2;
- break;
-
- case MATERIAL_LINE_LOOP:
- *pMaxVertices = nPrimitiveCount;
- *pMaxIndices = nPrimitiveCount * 2;
- break;
-
- case MATERIAL_TRIANGLES:
- *pMaxVertices = *pMaxIndices = nPrimitiveCount * 3;
- break;
-
- case MATERIAL_TRIANGLE_STRIP:
- *pMaxVertices = *pMaxIndices = nPrimitiveCount + 2;
- break;
-
- case MATERIAL_QUADS:
- *pMaxVertices = nPrimitiveCount * 4;
- *pMaxIndices = nPrimitiveCount * 6;
- break;
-
- case MATERIAL_INSTANCED_QUADS:
- *pMaxVertices = nPrimitiveCount;
- *pMaxIndices = 0; // This primtype is unindexed
- break;
-
- case MATERIAL_POLYGON:
- *pMaxVertices = nPrimitiveCount;
- *pMaxIndices = (nPrimitiveCount - 2) * 3;
- break;
-
- default:
- Assert(0);
- }
-
- // FIXME: need to get this from meshdx8.cpp, or move it to somewhere common
- Assert( *pMaxVertices <= 32768 );
- Assert( *pMaxIndices <= 32768 );
-}
-
-
-inline int CMeshBuilder::IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount )
-{
- switch( type )
- {
- case MATERIAL_QUADS:
- Assert( (nVertexCount & 0x3) == 0 );
- return (nVertexCount * 6) / 4;
-
- case MATERIAL_INSTANCED_QUADS:
- // This primtype is unindexed
- return 0;
-
- case MATERIAL_POLYGON:
- Assert( nVertexCount >= 3 );
- return (nVertexCount - 2) * 3;
-
- case MATERIAL_LINE_STRIP:
- Assert( nVertexCount >= 2 );
- return (nVertexCount - 1) * 2;
-
- case MATERIAL_LINE_LOOP:
- Assert( nVertexCount >= 3 );
- return nVertexCount * 2;
-
- default:
- return nVertexCount;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Specify the type of vertex compression that this CMeshBuilder will perform
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::SetCompressionType( VertexCompressionType_t vertexCompressionType )
-{
- m_VertexBuilder.SetCompressionType( vertexCompressionType );
-}
-
-//-----------------------------------------------------------------------------
-// Begins modifying the mesh
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int numPrimitives )
-{
- Assert( pMesh && (!m_pMesh) );
- Assert( type != MATERIAL_HETEROGENOUS );
-
- m_pMesh = pMesh;
- m_bGenerateIndices = true;
- m_Type = type;
-
- int nMaxVertexCount, nMaxIndexCount;
- ComputeNumVertsAndIndices( &nMaxVertexCount, &nMaxIndexCount, type, numPrimitives );
-
- switch( type )
- {
- case MATERIAL_INSTANCED_QUADS:
- m_pMesh->SetPrimitiveType( MATERIAL_INSTANCED_QUADS );
- break;
-
- case MATERIAL_QUADS:
- case MATERIAL_POLYGON:
- m_pMesh->SetPrimitiveType( MATERIAL_TRIANGLES );
- break;
-
- case MATERIAL_LINE_STRIP:
- case MATERIAL_LINE_LOOP:
- m_pMesh->SetPrimitiveType( MATERIAL_LINES );
- break;
-
- default:
- m_pMesh->SetPrimitiveType( type );
- }
-
- // Lock the mesh
- m_pMesh->LockMesh( nMaxVertexCount, nMaxIndexCount, *this );
-
- m_IndexBuilder.AttachBegin( pMesh, nMaxIndexCount, *this );
- m_VertexBuilder.AttachBegin( pMesh, nMaxVertexCount, *this );
-
- // Point to the start of the index and vertex buffers
- Reset();
-}
-
-inline void CMeshBuilder::Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex )
-{
- Begin( pMesh, type, nVertexCount, nIndexCount );
-
- *nFirstVertex = m_VertexBuilder.m_nFirstVertex * m_VertexBuilder.VertexSize();
-}
-
-inline void CMeshBuilder::Begin( IMesh* pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount )
-{
- Assert( pMesh && (!m_pMesh) );
-
- // NOTE: We can't specify the indices when we use quads, polygons, or
- // linestrips; they aren't actually directly supported by
- // the material system
- Assert( (type != MATERIAL_QUADS) && (type != MATERIAL_INSTANCED_QUADS) && (type != MATERIAL_POLYGON) &&
- (type != MATERIAL_LINE_STRIP) && (type != MATERIAL_LINE_LOOP));
-
- // Dx8 doesn't support indexed points...
- Assert( type != MATERIAL_POINTS );
-
- m_pMesh = pMesh;
- m_bGenerateIndices = false;
- m_Type = type;
-
- // Set the primitive type
- m_pMesh->SetPrimitiveType( type );
-
- // Lock the vertex and index buffer
- m_pMesh->LockMesh( nVertexCount, nIndexCount, *this );
-
- m_IndexBuilder.AttachBegin( pMesh, nIndexCount, *this );
- m_VertexBuilder.AttachBegin( pMesh, nVertexCount, *this );
-
- // Point to the start of the buffers..
- Reset();
-}
-
-
-//-----------------------------------------------------------------------------
-// Use this when you're done modifying the mesh
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::End( bool bSpewData, bool bDraw )
-{
- if ( m_bGenerateIndices )
- {
- int nIndexCount = IndicesFromVertices( m_Type, m_VertexBuilder.VertexCount() );
- m_IndexBuilder.GenerateIndices( m_Type, nIndexCount );
- }
-
- if ( bSpewData )
- {
- m_pMesh->Spew( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this );
- }
-
-#ifdef _DEBUG
- m_pMesh->ValidateData( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this );
-#endif
-
- // Unlock our buffers
- m_pMesh->UnlockMesh( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this );
-
- m_IndexBuilder.AttachEnd();
- m_VertexBuilder.AttachEnd();
-
- if ( bDraw )
- {
- m_pMesh->Draw();
- }
-
- m_pMesh = 0;
-
-#ifdef _DEBUG
- memset( (MeshDesc_t*)this, 0, sizeof(MeshDesc_t) );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Locks the vertex buffer to modify existing data
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::BeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount )
-{
- Assert( pMesh && (!m_pMesh) );
-
- if (nVertexCount < 0)
- {
- nVertexCount = pMesh->VertexCount();
- }
-
- m_pMesh = pMesh;
- m_bGenerateIndices = false;
-
- // Locks mesh for modifying
- pMesh->ModifyBeginEx( false, nFirstVertex, nVertexCount, nFirstIndex, nIndexCount, *this );
-
- m_IndexBuilder.AttachBeginModify( pMesh, nFirstIndex, nIndexCount, *this );
- m_VertexBuilder.AttachBeginModify( pMesh, nFirstVertex, nVertexCount, *this );
-
- // Point to the start of the buffers..
- Reset();
-}
-
-inline void CMeshBuilder::EndModify( bool bSpewData )
-{
- Assert( m_pMesh );
-
- if (bSpewData)
- {
- m_pMesh->Spew( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this );
- }
-#ifdef _DEBUG
- m_pMesh->ValidateData( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this );
-#endif
-
- // Unlocks mesh
- m_pMesh->ModifyEnd( *this );
- m_pMesh = 0;
-
- m_IndexBuilder.AttachEndModify();
- m_VertexBuilder.AttachEndModify();
-
-#ifdef _DEBUG
- // Null out our pointers...
- memset( (MeshDesc_t*)this, 0, sizeof(MeshDesc_t) );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Resets the mesh builder so it points to the start of everything again
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::Reset()
-{
- m_IndexBuilder.Reset();
- m_VertexBuilder.Reset();
-}
-
-
-//-----------------------------------------------------------------------------
-// Selects the current Vertex and Index
-//-----------------------------------------------------------------------------
-FORCEINLINE void CMeshBuilder::SelectVertex( int nIndex )
-{
- m_VertexBuilder.SelectVertex( nIndex );
-}
-
-inline void CMeshBuilder::SelectVertexFromIndex( int idx )
-{
- // NOTE: This index is expected to be relative
- int vertIdx = idx - m_nFirstVertex;
- SelectVertex( vertIdx );
-}
-
-FORCEINLINE void CMeshBuilder::SelectIndex( int idx )
-{
- m_IndexBuilder.SelectIndex( idx );
-}
-
-
-//-----------------------------------------------------------------------------
-// Advances the current vertex and index by one
-//-----------------------------------------------------------------------------
-template<int nFlags, int nNumTexCoords> FORCEINLINE void CMeshBuilder::AdvanceVertexF()
-{
- m_VertexBuilder.AdvanceVertexF<nFlags, nNumTexCoords>();
-}
-FORCEINLINE void CMeshBuilder::AdvanceVertex()
-{
- m_VertexBuilder.AdvanceVertex();
-}
-
-FORCEINLINE void CMeshBuilder::AdvanceVertices( int nVertexCount )
-{
- m_VertexBuilder.AdvanceVertices( nVertexCount );
-}
-
-FORCEINLINE void CMeshBuilder::AdvanceIndex()
-{
- m_IndexBuilder.AdvanceIndex();
-}
-
-FORCEINLINE void CMeshBuilder::AdvanceIndices( int nIndices )
-{
- m_IndexBuilder.AdvanceIndices( nIndices );
-}
-
-FORCEINLINE int CMeshBuilder::GetCurrentVertex()
-{
- return m_VertexBuilder.GetCurrentVertex();
-}
-
-FORCEINLINE int CMeshBuilder::GetCurrentIndex()
-{
- return m_IndexBuilder.GetCurrentIndex();
-}
-
-
-//-----------------------------------------------------------------------------
-// A helper method since this seems to be done a whole bunch.
-//-----------------------------------------------------------------------------
-inline void CMeshBuilder::DrawQuad( IMesh* pMesh, const float* v1, const float* v2,
- const float* v3, const float* v4, unsigned char const* pColor, bool wireframe )
-{
- if (!wireframe)
- {
- Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );
-
- Position3fv (v1);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
-
- Position3fv (v2);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
-
- Position3fv (v4);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
-
- Position3fv (v3);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
- }
- else
- {
- Begin( pMesh, MATERIAL_LINE_LOOP, 4 );
- Position3fv (v1);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
-
- Position3fv (v2);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
-
- Position3fv (v3);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
-
- Position3fv (v4);
- Color4ubv( pColor );
- AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>();
- }
-
- End();
- pMesh->Draw();
-}
-
-
-//-----------------------------------------------------------------------------
-// returns the number of indices and vertices
-//-----------------------------------------------------------------------------
-FORCEINLINE int CMeshBuilder::VertexCount() const
-{
- return m_VertexBuilder.VertexCount();
-}
-
-FORCEINLINE int CMeshBuilder::IndexCount() const
-{
- return m_IndexBuilder.IndexCount();
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the base vertex memory pointer
-//-----------------------------------------------------------------------------
-FORCEINLINE void* CMeshBuilder::BaseVertexData()
-{
- return m_VertexBuilder.BaseVertexData();
-}
-
-//-----------------------------------------------------------------------------
-// Data retrieval...
-//-----------------------------------------------------------------------------
-FORCEINLINE const float* CMeshBuilder::Position() const
-{
- return m_VertexBuilder.Position();
-}
-
-FORCEINLINE const float* CMeshBuilder::Normal() const
-{
- return m_VertexBuilder.Normal();
-}
-
-FORCEINLINE unsigned int CMeshBuilder::Color() const
-{
- return m_VertexBuilder.Color();
-}
-
-FORCEINLINE unsigned char *CMeshBuilder::Specular() const
-{
- return m_VertexBuilder.Specular();
-}
-
-FORCEINLINE const float* CMeshBuilder::TexCoord( int nStage ) const
-{
- return m_VertexBuilder.TexCoord( nStage );
-}
-
-FORCEINLINE const float* CMeshBuilder::TangentS() const
-{
- return m_VertexBuilder.TangentS();
-}
-
-FORCEINLINE const float* CMeshBuilder::TangentT() const
-{
- return m_VertexBuilder.TangentT();
-}
-
-FORCEINLINE float CMeshBuilder::Wrinkle() const
-{
- return m_VertexBuilder.Wrinkle();
-}
-
-FORCEINLINE const float* CMeshBuilder::BoneWeight() const
-{
- return m_VertexBuilder.BoneWeight();
-}
-
-FORCEINLINE int CMeshBuilder::NumBoneWeights() const
-{
- return m_VertexBuilder.NumBoneWeights();
-}
-
-FORCEINLINE unsigned short const* CMeshBuilder::Index() const
-{
- return m_IndexBuilder.Index();
-}
-
-
-//-----------------------------------------------------------------------------
-// Index
-//-----------------------------------------------------------------------------
-FORCEINLINE void CMeshBuilder::Index( unsigned short idx )
-{
- m_IndexBuilder.Index( idx );
-}
-
-
-//-----------------------------------------------------------------------------
-// Fast Index! No need to call advance index
-//-----------------------------------------------------------------------------
-FORCEINLINE void CMeshBuilder::FastIndex( unsigned short idx )
-{
- m_IndexBuilder.FastIndex( idx );
-}
-
-// NOTE: Use this one to get write combining! Much faster than the other version of FastIndex
-// Fast Index! No need to call advance index, and no random access allowed
-FORCEINLINE void CMeshBuilder::FastIndex2( unsigned short nIndex1, unsigned short nIndex2 )
-{
- m_IndexBuilder.FastIndex2( nIndex1, nIndex2 );
-}
-
-//-----------------------------------------------------------------------------
-// For use with the FastVertex methods, advances the current vertex by N
-//-----------------------------------------------------------------------------
-FORCEINLINE void CMeshBuilder::FastAdvanceNVertices( int nVertexCount )
-{
- m_VertexBuilder.FastAdvanceNVertices( nVertexCount );
-}
-
-
-//-----------------------------------------------------------------------------
-// Fast Vertex! No need to call advance vertex, and no random access allowed
-//-----------------------------------------------------------------------------
-FORCEINLINE void CMeshBuilder::FastVertex( const ModelVertexDX7_t &vertex )
-{
- m_VertexBuilder.FastVertex( vertex );
-}
-
-FORCEINLINE void CMeshBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex )
-{
- m_VertexBuilder.FastVertexSSE( vertex );
-}
-
-FORCEINLINE void CMeshBuilder::Fast4VerticesSSE(
- const ModelVertexDX7_t *vtx_a, const ModelVertexDX7_t *vtx_b,
- const ModelVertexDX7_t *vtx_c, const ModelVertexDX7_t *vtx_d )
-{
- m_VertexBuilder.Fast4VerticesSSE( vtx_a, vtx_b, vtx_c, vtx_d );
-}
-
-FORCEINLINE void CMeshBuilder::FastVertex( const ModelVertexDX8_t &vertex )
-{
- m_VertexBuilder.FastVertex( vertex );
-}
-
-FORCEINLINE void CMeshBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex )
-{
- m_VertexBuilder.FastVertexSSE( vertex );
-}
-
-//-----------------------------------------------------------------------------
-// Copies a vertex into the x360 format
-//-----------------------------------------------------------------------------
-#if defined( _X360 )
-inline void CMeshBuilder::VertexDX8ToX360( const ModelVertexDX8_t &vertex )
-{
- m_VertexBuilder.VertexDX8ToX360( vertex );
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// Vertex field setting methods
-//-----------------------------------------------------------------------------
-FORCEINLINE void CMeshBuilder::Position3f( float x, float y, float z )
-{
- m_VertexBuilder.Position3f( x, y, z );
-}
-
-FORCEINLINE void CMeshBuilder::Position3fv( const float *v )
-{
- m_VertexBuilder.Position3fv( v );
-}
-
-FORCEINLINE void CMeshBuilder::Normal3f( float nx, float ny, float nz )
-{
- m_VertexBuilder.Normal3f( nx, ny, nz );
-}
-
-FORCEINLINE void CMeshBuilder::Normal3fv( const float *n )
-{
- m_VertexBuilder.Normal3fv( n );
-}
-
-FORCEINLINE void CMeshBuilder::NormalDelta3f( float nx, float ny, float nz )
-{
- m_VertexBuilder.NormalDelta3f( nx, ny, nz );
-}
-
-FORCEINLINE void CMeshBuilder::NormalDelta3fv( const float *n )
-{
- m_VertexBuilder.NormalDelta3fv( n );
-}
-
-FORCEINLINE void CMeshBuilder::Color3f( float r, float g, float b )
-{
- m_VertexBuilder.Color3f( r, g, b );
-}
-
-FORCEINLINE void CMeshBuilder::Color3fv( const float *rgb )
-{
- m_VertexBuilder.Color3fv( rgb );
-}
-
-FORCEINLINE void CMeshBuilder::Color4f( float r, float g, float b, float a )
-{
- m_VertexBuilder.Color4f( r, g ,b, a );
-}
-
-FORCEINLINE void CMeshBuilder::Color4fv( const float *rgba )
-{
- m_VertexBuilder.Color4fv( rgba );
-}
-
-FORCEINLINE void CMeshBuilder::Color3ub( unsigned char r, unsigned char g, unsigned char b )
-{
- m_VertexBuilder.Color3ub( r, g, b );
-}
-
-FORCEINLINE void CMeshBuilder::Color3ubv( unsigned char const* rgb )
-{
- m_VertexBuilder.Color3ubv( rgb );
-}
-
-FORCEINLINE void CMeshBuilder::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
-{
- m_VertexBuilder.Color4ub( r, g, b, a );
-}
-
-FORCEINLINE void CMeshBuilder::Color4ubv( unsigned char const* rgba )
-{
- m_VertexBuilder.Color4ubv( rgba );
-}
-
-FORCEINLINE void CMeshBuilder::Specular3f( float r, float g, float b )
-{
- m_VertexBuilder.Specular3f( r, g, b );
-}
-
-FORCEINLINE void CMeshBuilder::Specular3fv( const float *rgb )
-{
- m_VertexBuilder.Specular3fv( rgb );
-}
-
-FORCEINLINE void CMeshBuilder::Specular4f( float r, float g, float b, float a )
-{
- m_VertexBuilder.Specular4f( r, g, b, a );
-}
-
-FORCEINLINE void CMeshBuilder::Specular4fv( const float *rgba )
-{
- m_VertexBuilder.Specular4fv( rgba );
-}
-
-FORCEINLINE void CMeshBuilder::Specular3ub( unsigned char r, unsigned char g, unsigned char b )
-{
- m_VertexBuilder.Specular3ub( r, g, b );
-}
-
-FORCEINLINE void CMeshBuilder::Specular3ubv( unsigned char const *c )
-{
- m_VertexBuilder.Specular3ubv( c );
-}
-
-FORCEINLINE void CMeshBuilder::Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
-{
- m_VertexBuilder.Specular4ub( r, g, b, a );
-}
-
-FORCEINLINE void CMeshBuilder::Specular4ubv( unsigned char const *c )
-{
- m_VertexBuilder.Specular4ubv( c );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoord1f( int nStage, float s )
-{
- m_VertexBuilder.TexCoord1f( nStage, s );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoord2f( int nStage, float s, float t )
-{
- m_VertexBuilder.TexCoord2f( nStage, s, t );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoord2fv( int nStage, const float *st )
-{
- m_VertexBuilder.TexCoord2fv( nStage, st );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoord3f( int nStage, float s, float t, float u )
-{
- m_VertexBuilder.TexCoord3f( nStage, s, t, u );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoord3fv( int nStage, const float *stu )
-{
- m_VertexBuilder.TexCoord3fv( nStage, stu );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoord4f( int nStage, float s, float t, float u, float v )
-{
- m_VertexBuilder.TexCoord4f( nStage, s, t, u, v );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoord4fv( int nStage, const float *stuv )
-{
- m_VertexBuilder.TexCoord4fv( nStage, stuv );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoordSubRect2f( int nStage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT )
-{
- m_VertexBuilder.TexCoordSubRect2f( nStage, s, t, offsetS, offsetT, scaleS, scaleT );
-}
-
-FORCEINLINE void CMeshBuilder::TexCoordSubRect2fv( int nStage, const float *st, const float *offset, const float *scale )
-{
- m_VertexBuilder.TexCoordSubRect2fv( nStage, st, offset, scale );
-}
-
-FORCEINLINE void CMeshBuilder::TangentS3f( float sx, float sy, float sz )
-{
- m_VertexBuilder.TangentS3f( sx, sy, sz );
-}
-
-FORCEINLINE void CMeshBuilder::TangentS3fv( const float* s )
-{
- m_VertexBuilder.TangentS3fv( s );
-}
-
-FORCEINLINE void CMeshBuilder::TangentT3f( float tx, float ty, float tz )
-{
- m_VertexBuilder.TangentT3f( tx, ty, tz );
-}
-
-FORCEINLINE void CMeshBuilder::TangentT3fv( const float* t )
-{
- m_VertexBuilder.TangentT3fv( t );
-}
-
-FORCEINLINE void CMeshBuilder::Wrinkle1f( float flWrinkle )
-{
- m_VertexBuilder.Wrinkle1f( flWrinkle );
-}
-
-FORCEINLINE void CMeshBuilder::BoneWeight( int nIndex, float flWeight )
-{
- m_VertexBuilder.BoneWeight( nIndex, flWeight );
-}
-
-template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedBoneWeight3fv( const float * pWeights )
-{
- m_VertexBuilder.CompressedBoneWeight3fv<T>( pWeights );
-}
-
-FORCEINLINE void CMeshBuilder::BoneMatrix( int nIndex, int nMatrixIdx )
-{
- m_VertexBuilder.BoneMatrix( nIndex, nMatrixIdx );
-}
-
-FORCEINLINE void CMeshBuilder::UserData( const float* pData )
-{
- m_VertexBuilder.UserData( pData );
-}
-
-template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedUserData( const float* pData )
-{
- m_VertexBuilder.CompressedUserData<T>( pData );
-}
-
-//-----------------------------------------------------------------------------
-// Templatized vertex field setting methods which support compression
-//-----------------------------------------------------------------------------
-
-template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedNormal3f( float nx, float ny, float nz )
-{
- m_VertexBuilder.CompressedNormal3f<T>( nx, ny, nz );
-}
-
-template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedNormal3fv( const float *n )
-{
- m_VertexBuilder.CompressedNormal3fv<T>( n );
-}
-
-#endif // IMESH_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef IMESH_H +#define IMESH_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "materialsystem/imaterial.h" +#include <float.h> +#include <string.h> +#include "tier0/dbg.h" +#include "tier2/meshutils.h" +#include "mathlib/mathlib.h" + +#if defined( DX_TO_GL_ABSTRACTION ) +// Swap these so that we do color swapping on 10.6.2, which doesn't have EXT_vertex_array_bgra +#define OPENGL_SWAP_COLORS +#endif + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterial; +class CMeshBuilder; +class IMaterialVar; +typedef uint64 VertexFormat_t; + + +//----------------------------------------------------------------------------- +// Define this to find write-combine problems +//----------------------------------------------------------------------------- +#ifdef _DEBUG +//#ifndef DEBUG_WRITE_COMBINE +//#define DEBUG_WRITE_COMBINE 1 +//#endif +#endif + + +//----------------------------------------------------------------------------- +// The Vertex Buffer interface +//----------------------------------------------------------------------------- +enum +{ + VERTEX_MAX_TEXTURE_COORDINATES = 8, + BONE_MATRIX_INDEX_INVALID = 255 +}; + +// Internal maximums for sizes. Don't use directly, use IMaterialSystem::GetMaxToRender() +enum +{ + INDEX_BUFFER_SIZE = 32768, + DYNAMIC_VERTEX_BUFFER_MEMORY = ( 1024 + 512 ) * 1024, + DYNAMIC_VERTEX_BUFFER_MEMORY_SMALL = 384 * 1024, // Only allocate this much during map transitions +}; + +// Vertex fields must be written in well-defined order to achieve write combining, +// which is a perf booster +enum WriteCombineOrdering_t +{ + MB_FIELD_NONE = -1, + MB_FIELD_POSITION = 0, + MB_FIELD_BONE_WEIGHTS, + MB_FIELD_BONE_INDEX, + MB_FIELD_NORMAL, + MB_FIELD_COLOR, + MB_FIELD_SPECULAR, + MB_FIELD_TEXCOORD_FIRST, + MB_FIELD_TEXCOORD_LAST = MB_FIELD_TEXCOORD_FIRST + VERTEX_MAX_TEXTURE_COORDINATES - 1, + MB_FIELD_TANGENT_S, + MB_FIELD_TANGENT_T, + MB_FIELD_USERDATA, +}; + +#define MB_FIELD_TEXCOORD( nStage ) ( MB_FIELD_TEXCOORD_FIRST + ( nStage ) ) + +struct VertexDesc_t +{ + // These can be set to zero if there are pointers to dummy buffers, when the + // actual buffer format doesn't contain the data but it needs to be safe to + // use all the CMeshBuilder functions. + int m_VertexSize_Position; + int m_VertexSize_BoneWeight; + int m_VertexSize_BoneMatrixIndex; + int m_VertexSize_Normal; + int m_VertexSize_Color; + int m_VertexSize_Specular; + int m_VertexSize_TexCoord[VERTEX_MAX_TEXTURE_COORDINATES]; + int m_VertexSize_TangentS; + int m_VertexSize_TangentT; + int m_VertexSize_Wrinkle; + + int m_VertexSize_UserData; + + int m_ActualVertexSize; // Size of the vertices.. Some of the m_VertexSize_ elements above + // are set to this value and some are set to zero depending on which + // fields exist in a buffer's vertex format. + + // The type of compression applied to this vertex data + VertexCompressionType_t m_CompressionType; + + // Number of bone weights per vertex... + int m_NumBoneWeights; + + // Pointers to our current vertex data + float *m_pPosition; + + float *m_pBoneWeight; + +#ifndef NEW_SKINNING + unsigned char *m_pBoneMatrixIndex; +#else + float *m_pBoneMatrixIndex; +#endif + + float *m_pNormal; + + unsigned char *m_pColor; + unsigned char *m_pSpecular; + float *m_pTexCoord[VERTEX_MAX_TEXTURE_COORDINATES]; + + // Tangent space *associated with one particular set of texcoords* + float *m_pTangentS; + float *m_pTangentT; + + float *m_pWrinkle; + + // user data + float *m_pUserData; + + // The first vertex index (used for buffered vertex buffers, or cards that don't support stream offset) + int m_nFirstVertex; + + // The offset in bytes of the memory we're writing into + // from the start of the D3D buffer (will be 0 for static meshes) + unsigned int m_nOffset; + +#ifdef DEBUG_WRITE_COMBINE + int m_nLastWrittenField; + unsigned char* m_pLastWrittenAddress; +#endif +}; + +struct IndexDesc_t +{ + // Pointers to the index data + unsigned short *m_pIndices; + + // The offset in bytes of the memory we're writing into + // from the start of the D3D buffer (will be 0 for static meshes) + unsigned int m_nOffset; + + // The first index (used for buffered index buffers, or cards that don't support stream offset) + unsigned int m_nFirstIndex; + + // 1 if the device is active, 0 if the device isn't active. + // Faster than doing if checks for null m_pIndices if someone is + // trying to write the m_pIndices while the device is inactive. + unsigned char m_nIndexSize; +}; + + +//----------------------------------------------------------------------------- +// The Mesh memory descriptor +//----------------------------------------------------------------------------- +struct MeshDesc_t : public VertexDesc_t, public IndexDesc_t +{ +}; + + +//----------------------------------------------------------------------------- +// Standard vertex formats for models +//----------------------------------------------------------------------------- +struct ModelVertexDX7_t +{ + Vector m_vecPosition; + Vector2D m_flBoneWeights; + unsigned int m_nBoneIndices; + Vector m_vecNormal; + unsigned int m_nColor; // ARGB + Vector2D m_vecTexCoord; +}; + +struct ModelVertexDX8_t : public ModelVertexDX7_t +{ + Vector4D m_vecUserData; +}; + + +//----------------------------------------------------------------------------- +// Utility methods for buffer builders +//----------------------------------------------------------------------------- +inline float *OffsetFloatPointer( float *pBufferPointer, int nVertexCount, int vertexSize ) +{ + return reinterpret_cast<float *>( + reinterpret_cast<unsigned char *>(pBufferPointer) + + nVertexCount * vertexSize); +} + +inline const float *OffsetFloatPointer( const float *pBufferPointer, int nVertexCount, int vertexSize ) +{ + return reinterpret_cast<const float*>( + reinterpret_cast<unsigned char const*>(pBufferPointer) + + nVertexCount * vertexSize); +} + +inline void IncrementFloatPointer( float* &pBufferPointer, int vertexSize ) +{ + pBufferPointer = reinterpret_cast<float*>( reinterpret_cast<unsigned char*>( pBufferPointer ) + vertexSize ); +} + + +//----------------------------------------------------------------------------- +// Used in lists of indexed primitives. +//----------------------------------------------------------------------------- +class CPrimList +{ +public: + CPrimList(); + CPrimList( int nFirstIndex, int nIndexCount ); + + int m_FirstIndex; + int m_NumIndices; +}; + +inline CPrimList::CPrimList() +{ +} + +inline CPrimList::CPrimList( int nFirstIndex, int nIndexCount ) +{ + m_FirstIndex = nFirstIndex; + m_NumIndices = nIndexCount; +} + +abstract_class IVertexBuffer +{ +public: + // Add a virtual destructor to silence the clang warning. + // This is harmless but not important since the only derived class + // doesn't have a destructor. + virtual ~IVertexBuffer() {} + + // NOTE: The following two methods are only valid for static vertex buffers + // Returns the number of vertices and the format of the vertex buffer + virtual int VertexCount() const = 0; + virtual VertexFormat_t GetVertexFormat() const = 0; + + // Is this vertex buffer dynamic? + virtual bool IsDynamic() const = 0; + + // NOTE: For dynamic vertex buffers only! + // Casts the memory of the dynamic vertex buffer to the appropriate type + virtual void BeginCastBuffer( VertexFormat_t format ) = 0; + virtual void EndCastBuffer() = 0; + + // Returns the number of vertices that can still be written into the buffer + virtual int GetRoomRemaining() const = 0; + + virtual bool Lock( int nVertexCount, bool bAppend, VertexDesc_t &desc ) = 0; + virtual void Unlock( int nVertexCount, VertexDesc_t &desc ) = 0; + + // Spews the mesh data + virtual void Spew( int nVertexCount, const VertexDesc_t &desc ) = 0; + + // Call this in debug mode to make sure our data is good. + virtual void ValidateData( int nVertexCount, const VertexDesc_t & desc ) = 0; +}; + +abstract_class IIndexBuffer +{ +public: + // Add a virtual destructor to silence the clang warning. + // This is harmless but not important since the only derived class + // doesn't have a destructor. + virtual ~IIndexBuffer() {} + + // NOTE: The following two methods are only valid for static index buffers + // Returns the number of indices and the format of the index buffer + virtual int IndexCount() const = 0; + virtual MaterialIndexFormat_t IndexFormat() const = 0; + + // Is this index buffer dynamic? + virtual bool IsDynamic() const = 0; + + // NOTE: For dynamic index buffers only! + // Casts the memory of the dynamic index buffer to the appropriate type + virtual void BeginCastBuffer( MaterialIndexFormat_t format ) = 0; + virtual void EndCastBuffer() = 0; + + // Returns the number of indices that can still be written into the buffer + virtual int GetRoomRemaining() const = 0; + + // Locks, unlocks the index buffer + virtual bool Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t &desc ) = 0; + virtual void Unlock( int nWrittenIndexCount, IndexDesc_t &desc ) = 0; + + // FIXME: Remove this!! + // Locks, unlocks the index buffer for modify + virtual void ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t& desc ) = 0; + virtual void ModifyEnd( IndexDesc_t& desc ) = 0; + + // Spews the mesh data + virtual void Spew( int nIndexCount, const IndexDesc_t &desc ) = 0; + + // Ensures the data in the index buffer is valid + virtual void ValidateData( int nIndexCount, const IndexDesc_t &desc ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Interface to the mesh - needs to contain an IVertexBuffer and an IIndexBuffer to emulate old mesh behavior +//----------------------------------------------------------------------------- +abstract_class IMesh : public IVertexBuffer, public IIndexBuffer +{ +public: + // ----------------------------------- + + // Sets/gets the primitive type + virtual void SetPrimitiveType( MaterialPrimitiveType_t type ) = 0; + + // Draws the mesh + virtual void Draw( int nFirstIndex = -1, int nIndexCount = 0 ) = 0; + + virtual void SetColorMesh( IMesh *pColorMesh, int nVertexOffset ) = 0; + + // 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 ) = 0; + + // 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 ) = 0; + + // Spews the mesh data + virtual void Spew( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ) = 0; + + // Call this in debug mode to make sure our data is good. + virtual void ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ) = 0; + + // New version + // 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 ) = 0; + virtual void ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t& desc ) = 0; + virtual void ModifyEnd( MeshDesc_t& desc ) = 0; + virtual void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) = 0; + + virtual void ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ) = 0; + + virtual void SetFlexMesh( IMesh *pMesh, int nVertexOffset ) = 0; + + virtual void DisableFlexMesh() = 0; + + virtual void MarkAsDrawn() = 0; + + virtual unsigned ComputeMemoryUsed() = 0; +}; + + +#include "meshreader.h" + +#define INVALID_BUFFER_OFFSET 0xFFFFFFFFUL + +// flags for advancevertex optimization +#define VTX_HAVEPOS 1 +#define VTX_HAVENORMAL 2 +#define VTX_HAVECOLOR 4 +#define VTX_HAVEALL ( VTX_HAVEPOS | VTX_HAVENORMAL | VTX_HAVECOLOR ) + + +//----------------------------------------------------------------------------- +// +// Helper class used to define vertex buffers +// +//----------------------------------------------------------------------------- +class CVertexBuilder : private VertexDesc_t +{ +public: + CVertexBuilder(); + CVertexBuilder( IVertexBuffer *pVertexBuffer, VertexFormat_t fmt = 0 ); + ~CVertexBuilder(); + + // Begins, ends modification of the index buffer (returns true if the lock succeeded) + // A lock may not succeed if append is set to true and there isn't enough room + // NOTE: Append is only used with dynamic index buffers; it's ignored for static buffers + bool Lock( int nMaxIndexCount, bool bAppend = false ); + void Unlock(); + + // Spews the current data + // NOTE: Can only be called during a lock/unlock block + void SpewData(); + + // Returns the number of indices we can fit into the buffer without needing to discard + int GetRoomRemaining() const; + + // Binds this vertex buffer + void Bind( IMatRenderContext *pContext, int nStreamID, VertexFormat_t usage = 0 ); + + // Returns the byte offset + int Offset() const; + + // This must be called before Begin, if a vertex buffer with a compressed format is to be used + void SetCompressionType( VertexCompressionType_t compressionType ); + void ValidateCompressionType(); + + void Begin( IVertexBuffer *pVertexBuffer, int nVertexCount, int *nFirstVertex ); + void Begin( IVertexBuffer *pVertexBuffer, int nVertexCount ); + + // Use this when you're done writing + // Set bDraw to true to call m_pMesh->Draw automatically. + void End( bool bSpewData = false ); + + // Locks the vertex buffer to modify existing data + // Passing nVertexCount == -1 says to lock all the vertices for modification. + void BeginModify( IVertexBuffer *pVertexBuffer, int nFirstVertex = 0, int nVertexCount = -1 ); + void EndModify( bool bSpewData = false ); + + // returns the number of vertices + int VertexCount() const; + + // Returns the total number of vertices across all Locks() + int TotalVertexCount() const; + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + // Returns the size of the vertex + int VertexSize() { return m_ActualVertexSize; } + + // returns the data size of a given texture coordinate + int TextureCoordinateSize( int nTexCoordNumber ) { return m_VertexSize_TexCoord[ nTexCoordNumber ]; } + + // Returns the base vertex memory pointer + void* BaseVertexData(); + + // Selects the nth Vertex and Index + void SelectVertex( int idx ); + + // Advances the current vertex and index by one + void AdvanceVertex( void ); + template<int nFlags, int nNumTexCoords> void AdvanceVertexF( void ); + void AdvanceVertices( int nVerts ); + + int GetCurrentVertex() const; + int GetFirstVertex() const; + + // Data retrieval... + const float *Position() const; + + const float *Normal() const; + + unsigned int Color() const; + + unsigned char *Specular() const; + + const float *TexCoord( int stage ) const; + + const float *TangentS() const; + const float *TangentT() const; + + const float *BoneWeight() const; + float Wrinkle() const; + + int NumBoneWeights() const; +#ifndef NEW_SKINNING + unsigned char *BoneMatrix() const; +#else + float *BoneMatrix() const; +#endif + + // position setting + void Position3f( float x, float y, float z ); + void Position3fv( const float *v ); + + // normal setting + void Normal3f( float nx, float ny, float nz ); + void Normal3fv( const float *n ); + void NormalDelta3fv( const float *n ); + void NormalDelta3f( float nx, float ny, float nz ); + // normal setting (templatized for code which needs to support compressed vertices) + template <VertexCompressionType_t T> void CompressedNormal3f( float nx, float ny, float nz ); + template <VertexCompressionType_t T> void CompressedNormal3fv( const float *n ); + + // color setting + void Color3f( float r, float g, float b ); + void Color3fv( const float *rgb ); + void Color4f( float r, float g, float b, float a ); + void Color4fv( const float *rgba ); + + // Faster versions of color + void Color3ub( unsigned char r, unsigned char g, unsigned char b ); + void Color3ubv( unsigned char const* rgb ); + void Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Color4ubv( unsigned char const* rgba ); + + // specular color setting + void Specular3f( float r, float g, float b ); + void Specular3fv( const float *rgb ); + void Specular4f( float r, float g, float b, float a ); + void Specular4fv( const float *rgba ); + + // Faster version of specular + void Specular3ub( unsigned char r, unsigned char g, unsigned char b ); + void Specular3ubv( unsigned char const *c ); + void Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Specular4ubv( unsigned char const *c ); + + // texture coordinate setting + void TexCoord1f( int stage, float s ); + void TexCoord2f( int stage, float s, float t ); + void TexCoord2fv( int stage, const float *st ); + void TexCoord3f( int stage, float s, float t, float u ); + void TexCoord3fv( int stage, const float *stu ); + void TexCoord4f( int stage, float s, float t, float u, float w ); + void TexCoord4fv( int stage, const float *stuv ); + + void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ); + void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ); + + // tangent space + void TangentS3f( float sx, float sy, float sz ); + void TangentS3fv( const float* s ); + + void TangentT3f( float tx, float ty, float tz ); + void TangentT3fv( const float* t ); + + // Wrinkle + void Wrinkle1f( float flWrinkle ); + + // bone weights + void BoneWeight( int idx, float weight ); + // bone weights (templatized for code which needs to support compressed vertices) + template <VertexCompressionType_t T> void CompressedBoneWeight3fv( const float * pWeights ); + + // bone matrix index + void BoneMatrix( int idx, int matrixIndex ); + + // Generic per-vertex data + void UserData( const float* pData ); + // Generic per-vertex data (templatized for code which needs to support compressed vertices) + template <VertexCompressionType_t T> void CompressedUserData( const float* pData ); + + // Fast Vertex! No need to call advance vertex, and no random access allowed. + // WARNING - these are low level functions that are intended only for use + // in the software vertex skinner. + void FastVertex( const ModelVertexDX7_t &vertex ); + void FastVertexSSE( const ModelVertexDX7_t &vertex ); + + // store 4 dx7 vertices fast. for special sse dx7 pipeline + void Fast4VerticesSSE( + ModelVertexDX7_t const *vtx_a, + ModelVertexDX7_t const *vtx_b, + ModelVertexDX7_t const *vtx_c, + ModelVertexDX7_t const *vtx_d); + + void FastVertex( const ModelVertexDX8_t &vertex ); + void FastVertexSSE( const ModelVertexDX8_t &vertex ); + + // Add number of verts and current vert since FastVertex routines do not update. + void FastAdvanceNVertices( int n ); + +#if defined( _X360 ) + void VertexDX8ToX360( const ModelVertexDX8_t &vertex ); +#endif + + // FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. + void AttachBegin( IMesh* pMesh, int nMaxVertexCount, const MeshDesc_t &desc ); + void AttachEnd(); + void AttachBeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, const MeshDesc_t &desc ); + void AttachEndModify(); + +private: + // The vertex buffer we're modifying + IVertexBuffer *m_pVertexBuffer; + + // Used to make sure Begin/End calls and BeginModify/EndModify calls match. + bool m_bModify; + + // Max number of indices and vertices + int m_nMaxVertexCount; + + // Number of indices and vertices + int m_nVertexCount; + + // The current vertex and index + mutable int m_nCurrentVertex; + + // Optimization: Pointer to the current pos, norm, texcoord, and color + mutable float *m_pCurrPosition; + mutable float *m_pCurrNormal; + mutable float *m_pCurrTexCoord[VERTEX_MAX_TEXTURE_COORDINATES]; + mutable unsigned char *m_pCurrColor; + + // Total number of vertices appended + int m_nTotalVertexCount; + + // First vertex buffer offset + index + unsigned int m_nBufferOffset; + unsigned int m_nBufferFirstVertex; + +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // Debug checks to make sure we write userdata4/tangents AFTER normals + bool m_bWrittenNormal : 1; + bool m_bWrittenUserData : 1; +#endif + + friend class CMeshBuilder; +}; + + +//----------------------------------------------------------------------------- +// +// Inline methods of CVertexBuilder +// +//----------------------------------------------------------------------------- +inline CVertexBuilder::CVertexBuilder() +{ + m_pVertexBuffer = NULL; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstVertex = 0; + m_nVertexCount = 0; + m_nCurrentVertex = 0; + m_nMaxVertexCount = 0; + m_nTotalVertexCount = 0; + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + m_bModify = false; +#endif +} + +inline CVertexBuilder::CVertexBuilder( IVertexBuffer *pVertexBuffer, VertexFormat_t fmt ) +{ + m_pVertexBuffer = pVertexBuffer; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstVertex = 0; + m_nVertexCount = 0; + m_nCurrentVertex = 0; + m_nMaxVertexCount = 0; + m_nTotalVertexCount = 0; + m_CompressionType = VERTEX_COMPRESSION_INVALID; + + if ( m_pVertexBuffer->IsDynamic() ) + { + m_pVertexBuffer->BeginCastBuffer( fmt ); + } + else + { + Assert( m_pVertexBuffer->GetVertexFormat() == fmt ); + } + +#ifdef _DEBUG + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + m_bModify = false; +#endif +} + +inline CVertexBuilder::~CVertexBuilder() +{ + if ( m_pVertexBuffer && m_pVertexBuffer->IsDynamic() ) + { + m_pVertexBuffer->EndCastBuffer(); + } +} + +//----------------------------------------------------------------------------- +// Begins, ends modification of the index buffer +//----------------------------------------------------------------------------- +inline bool CVertexBuilder::Lock( int nMaxVertexCount, bool bAppend ) +{ + Assert( m_pVertexBuffer ); + m_bModify = false; + m_nMaxVertexCount = nMaxVertexCount; + bool bFirstLock = ( m_nBufferOffset == INVALID_BUFFER_OFFSET ); + if ( bFirstLock ) + { + bAppend = false; + } + if ( !bAppend ) + { + m_nTotalVertexCount = 0; + } + + // Lock the vertex buffer + if ( !m_pVertexBuffer->Lock( m_nMaxVertexCount, bAppend, *this ) ) + { + m_nMaxVertexCount = 0; + return false; + } + + Reset(); + + if ( bFirstLock ) + { + m_nBufferOffset = m_nOffset; + m_nBufferFirstVertex = m_nFirstVertex; + } + + return true; +} + +inline void CVertexBuilder::Unlock() +{ + Assert( !m_bModify && m_pVertexBuffer ); + +#ifdef _DEBUG + m_pVertexBuffer->ValidateData( m_nVertexCount, *this ); +#endif + + m_pVertexBuffer->Unlock( m_nVertexCount, *this ); + m_nTotalVertexCount += m_nVertexCount; + + m_nMaxVertexCount = 0; + +#ifdef _DEBUG + // Null out our data... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast<VertexDesc_t*>( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + +inline void CVertexBuilder::SpewData() +{ + m_pVertexBuffer->Spew( m_nVertexCount, *this ); +} + + +//----------------------------------------------------------------------------- +// Binds this vertex buffer +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Bind( IMatRenderContext *pContext, int nStreamID, VertexFormat_t usage ) +{ + if ( m_pVertexBuffer && ( m_nBufferOffset != INVALID_BUFFER_OFFSET ) ) + { + pContext->BindVertexBuffer( nStreamID, m_pVertexBuffer, m_nBufferOffset, + m_nFirstVertex, m_nTotalVertexCount, usage ? usage : m_pVertexBuffer->GetVertexFormat() ); + } + else + { + pContext->BindVertexBuffer( nStreamID, NULL, 0, 0, 0, 0 ); + } +} + + +//----------------------------------------------------------------------------- +// Returns the byte offset +//----------------------------------------------------------------------------- +inline int CVertexBuilder::Offset() const +{ + return m_nBufferOffset; +} + +inline int CVertexBuilder::GetFirstVertex() const +{ + return m_nBufferFirstVertex; +} + +//----------------------------------------------------------------------------- +// Specify the type of vertex compression that this CMeshBuilder will perform +//----------------------------------------------------------------------------- +inline void CVertexBuilder::SetCompressionType( VertexCompressionType_t compressionType ) +{ + // The real purpose of this method is to allow us to emit a Warning in Begin() + m_CompressionType = compressionType; +} + +inline void CVertexBuilder::ValidateCompressionType() +{ +#ifdef _DEBUG + VertexCompressionType_t vbCompressionType = CompressionType( m_pVertexBuffer->GetVertexFormat() ); + if ( vbCompressionType != VERTEX_COMPRESSION_NONE ) + { + Assert( m_CompressionType == vbCompressionType ); + if ( m_CompressionType != vbCompressionType ) + { + Warning( "ERROR: CVertexBuilder::SetCompressionType() must be called to specify the same vertex compression type (%s) as the vertex buffer being modified." + "Junk vertices will be rendered, or there will be a crash in CVertexBuilder!\n", + vbCompressionType == VERTEX_COMPRESSION_ON ? "VERTEX_COMPRESSION_ON" : "VERTEX_COMPRESSION_NONE" ); + } + // Never use vertex compression for dynamic VBs (the conversions can really hurt perf) + Assert( !m_pVertexBuffer->IsDynamic() ); + } +#endif +} + +inline void CVertexBuilder::Begin( IVertexBuffer *pVertexBuffer, int nVertexCount ) +{ + Assert( pVertexBuffer && (!m_pVertexBuffer) ); + + m_pVertexBuffer = pVertexBuffer; + m_bModify = false; + + m_nMaxVertexCount = nVertexCount; + m_nVertexCount = 0; + + // Make sure SetCompressionType was called correctly, if this VB is compressed + ValidateCompressionType(); + + // Lock the vertex and index buffer + m_pVertexBuffer->Lock( m_nMaxVertexCount, false, *this ); + + // Point to the start of the buffers.. + Reset(); +} + + +//----------------------------------------------------------------------------- +// Use this when you're done modifying the mesh +//----------------------------------------------------------------------------- +inline void CVertexBuilder::End( bool bSpewData ) +{ + // Make sure they called Begin() + Assert( !m_bModify ); + + if ( bSpewData ) + { + m_pVertexBuffer->Spew( m_nVertexCount, *this ); + } + +#ifdef _DEBUG + m_pVertexBuffer->ValidateData( m_nVertexCount, *this ); +#endif + + // Unlock our buffers + m_pVertexBuffer->Unlock( m_nVertexCount, *this ); + + m_pVertexBuffer = 0; + m_nMaxVertexCount = 0; + + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + // Null out our pointers... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast< VertexDesc_t* >( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. +//----------------------------------------------------------------------------- +inline void CVertexBuilder::AttachBegin( IMesh* pMesh, int nMaxVertexCount, const MeshDesc_t &desc ) +{ + VertexCompressionType_t compressionType = m_CompressionType; + + m_pVertexBuffer = pMesh; + memcpy( static_cast<VertexDesc_t*>( this ), static_cast<const VertexDesc_t*>( &desc ), sizeof(VertexDesc_t) ); + m_nMaxVertexCount = nMaxVertexCount; + m_NumBoneWeights = m_NumBoneWeights == 0 ? 0 : 2; // Two weights if any + m_nVertexCount = 0; + m_bModify = false; + + if ( compressionType != VERTEX_COMPRESSION_INVALID ) + m_CompressionType = compressionType; + + // Make sure SetCompressionType was called correctly, if this VB is compressed + ValidateCompressionType(); + + if ( m_nBufferOffset == INVALID_BUFFER_OFFSET ) + { + m_nTotalVertexCount = 0; + m_nBufferOffset = static_cast< const VertexDesc_t* >( &desc )->m_nOffset; + m_nBufferFirstVertex = desc.m_nFirstVertex; + } +} + +inline void CVertexBuilder::AttachEnd() +{ + // Make sure they called Begin() + Assert( !m_bModify ); + + m_nMaxVertexCount = 0; + m_pVertexBuffer = NULL; + + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + // Null out our pointers... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast<VertexDesc_t*>( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + +inline void CVertexBuilder::AttachBeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, const MeshDesc_t &desc ) +{ + Assert( pMesh && (!m_pVertexBuffer) ); + + m_pVertexBuffer = pMesh; + memcpy( static_cast<VertexDesc_t*>( this ), static_cast<const VertexDesc_t*>( &desc ), sizeof(VertexDesc_t) ); + m_nMaxVertexCount = m_nVertexCount = nVertexCount; + m_NumBoneWeights = m_NumBoneWeights == 0 ? 0 : 2; // Two weights if any + m_bModify = true; + + // Make sure SetCompressionType was called correctly, if this VB is compressed + ValidateCompressionType(); +} + +inline void CVertexBuilder::AttachEndModify() +{ + Assert( m_pVertexBuffer ); + Assert( m_bModify ); // Make sure they called BeginModify. + + m_pVertexBuffer = 0; + m_nMaxVertexCount = 0; + + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + // Null out our pointers... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast<VertexDesc_t*>( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Computes the first min non-null address +//----------------------------------------------------------------------------- +inline unsigned char* FindMinAddress( void *pAddress1, void *pAddress2, int nAddress2Size ) +{ + if ( nAddress2Size == 0 ) + return (unsigned char*)pAddress1; + if ( !pAddress1 ) + return (unsigned char*)pAddress2; + return ( pAddress1 < pAddress2 ) ? (unsigned char*)pAddress1 : (unsigned char*)pAddress2; +} + +//----------------------------------------------------------------------------- +// Resets the vertex buffer builder so it points to the start of everything again +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Reset() +{ + m_nCurrentVertex = 0; + + m_pCurrPosition = m_pPosition; + m_pCurrNormal = m_pNormal; + for ( int i = 0; i < NELEMS( m_pCurrTexCoord ); i++ ) + { + m_pCurrTexCoord[i] = m_pTexCoord[i]; + } + m_pCurrColor = m_pColor; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif + +#ifdef DEBUG_WRITE_COMBINE + // Logic for m_pLastWrittenAddress is tricky. It really wants the min of the + // non-null address pointers. + m_nLastWrittenField = MB_FIELD_NONE; + m_pLastWrittenAddress = NULL; + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pPosition, m_VertexSize_Position ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pBoneWeight, m_VertexSize_BoneWeight ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pBoneMatrixIndex, m_VertexSize_BoneMatrixIndex ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pNormal, m_VertexSize_Normal ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pColor, m_VertexSize_Color ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pSpecular, m_VertexSize_Specular ); + for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i ) + { + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTexCoord[i], m_VertexSize_TexCoord[i] ); + } + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTangentS, m_VertexSize_TangentS ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTangentT, m_VertexSize_TangentT ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pUserData, m_VertexSize_UserData ); +#endif +} + + +//----------------------------------------------------------------------------- +// returns the number of vertices +//----------------------------------------------------------------------------- +inline int CVertexBuilder::VertexCount() const +{ + return m_nVertexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the total number of vertices across all Locks() +//----------------------------------------------------------------------------- +inline int CVertexBuilder::TotalVertexCount() const +{ + return m_nTotalVertexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the base vertex memory pointer +//----------------------------------------------------------------------------- +inline void* CVertexBuilder::BaseVertexData() +{ + // FIXME: If there's no position specified, we need to find + // the base address + Assert( m_pPosition ); + return m_pPosition; +} + + +//----------------------------------------------------------------------------- +// Selects the current vertex +//----------------------------------------------------------------------------- +inline void CVertexBuilder::SelectVertex( int nIndex ) +{ + // NOTE: This index is expected to be relative + Assert( (nIndex >= 0) && (nIndex < m_nMaxVertexCount) ); + m_nCurrentVertex = nIndex; + + m_pCurrPosition = OffsetFloatPointer( m_pPosition, m_nCurrentVertex, m_VertexSize_Position ); + m_pCurrNormal = OffsetFloatPointer( m_pNormal, m_nCurrentVertex, m_VertexSize_Normal ); + + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + m_pCurrTexCoord[0] = OffsetFloatPointer( m_pTexCoord[0], m_nCurrentVertex, m_VertexSize_TexCoord[0] ); + m_pCurrTexCoord[1] = OffsetFloatPointer( m_pTexCoord[1], m_nCurrentVertex, m_VertexSize_TexCoord[1] ); + m_pCurrTexCoord[2] = OffsetFloatPointer( m_pTexCoord[2], m_nCurrentVertex, m_VertexSize_TexCoord[2] ); + m_pCurrTexCoord[3] = OffsetFloatPointer( m_pTexCoord[3], m_nCurrentVertex, m_VertexSize_TexCoord[3] ); + m_pCurrTexCoord[4] = OffsetFloatPointer( m_pTexCoord[4], m_nCurrentVertex, m_VertexSize_TexCoord[4] ); + m_pCurrTexCoord[5] = OffsetFloatPointer( m_pTexCoord[5], m_nCurrentVertex, m_VertexSize_TexCoord[5] ); + m_pCurrTexCoord[6] = OffsetFloatPointer( m_pTexCoord[6], m_nCurrentVertex, m_VertexSize_TexCoord[6] ); + m_pCurrTexCoord[7] = OffsetFloatPointer( m_pTexCoord[7], m_nCurrentVertex, m_VertexSize_TexCoord[7] ); + m_pCurrColor = m_pColor + m_nCurrentVertex * m_VertexSize_Color; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + + +//----------------------------------------------------------------------------- +// Advances vertex after you're done writing to it. +//----------------------------------------------------------------------------- + +template<int nFlags, int nNumTexCoords> FORCEINLINE void CVertexBuilder::AdvanceVertexF() +{ + if ( ++m_nCurrentVertex > m_nVertexCount ) + { + m_nVertexCount = m_nCurrentVertex; + } + + if ( nFlags & VTX_HAVEPOS ) + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + if ( nFlags & VTX_HAVENORMAL ) + IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal ); + if ( nFlags & VTX_HAVECOLOR ) + m_pCurrColor += m_VertexSize_Color; + + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + if ( nNumTexCoords > 0 ) + IncrementFloatPointer( m_pCurrTexCoord[0], m_VertexSize_TexCoord[0] ); + if ( nNumTexCoords > 1 ) + IncrementFloatPointer( m_pCurrTexCoord[1], m_VertexSize_TexCoord[1] ); + if ( nNumTexCoords > 2 ) + IncrementFloatPointer( m_pCurrTexCoord[2], m_VertexSize_TexCoord[2] ); + if ( nNumTexCoords > 3 ) + IncrementFloatPointer( m_pCurrTexCoord[3], m_VertexSize_TexCoord[3] ); + if ( nNumTexCoords > 4 ) + IncrementFloatPointer( m_pCurrTexCoord[4], m_VertexSize_TexCoord[4] ); + if ( nNumTexCoords > 5 ) + IncrementFloatPointer( m_pCurrTexCoord[5], m_VertexSize_TexCoord[5] ); + if ( nNumTexCoords > 6 ) + IncrementFloatPointer( m_pCurrTexCoord[6], m_VertexSize_TexCoord[6] ); + if ( nNumTexCoords > 7 ) + IncrementFloatPointer( m_pCurrTexCoord[7], m_VertexSize_TexCoord[7] ); + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::AdvanceVertex() +{ + AdvanceVertexF<VTX_HAVEALL, 8>(); +} + + +inline void CVertexBuilder::AdvanceVertices( int nVerts ) +{ + m_nCurrentVertex += nVerts; + if ( m_nCurrentVertex > m_nVertexCount ) + { + m_nVertexCount = m_nCurrentVertex; + } + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position*nVerts ); + IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal*nVerts ); + + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + IncrementFloatPointer( m_pCurrTexCoord[0], m_VertexSize_TexCoord[0]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[1], m_VertexSize_TexCoord[1]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[2], m_VertexSize_TexCoord[2]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[3], m_VertexSize_TexCoord[3]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[4], m_VertexSize_TexCoord[4]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[5], m_VertexSize_TexCoord[5]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[6], m_VertexSize_TexCoord[6]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[7], m_VertexSize_TexCoord[7]*nVerts ); + m_pCurrColor += m_VertexSize_Color*nVerts; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + + +//----------------------------------------------------------------------------- +// For use with the FastVertex methods, advances the current vertex by N +//----------------------------------------------------------------------------- +inline void CVertexBuilder::FastAdvanceNVertices( int n ) +{ + m_nCurrentVertex += n; + m_nVertexCount = m_nCurrentVertex; +} + + + +#ifndef COMPILER_MSVC64 +// Implement for 64-bit Windows if needed. +//----------------------------------------------------------------------------- +// Fast Vertex! No need to call advance vertex, and no random access allowed +//----------------------------------------------------------------------------- +inline void CVertexBuilder::FastVertex( const ModelVertexDX7_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movq mm0, [esi + 0] + movq mm1, [esi + 8] + movq mm2, [esi + 16] + movq mm3, [esi + 24] + movq mm4, [esi + 32] + movq mm5, [esi + 40] + + movntq [edi + 0], mm0 + movntq [edi + 8], mm1 + movntq [edi + 16], mm2 + movntq [edi + 24], mm3 + movntq [edi + 32], mm4 + movntq [edi + 40], mm5 + + emms + } +#elif defined(GNUC) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movntq %%mm0, (%1)\n" + "movntq %%mm1, 8(%1)\n" + "movntq %%mm2, 16(%1)\n" + "movntq %%mm3, 24(%1)\n" + "movntq %%mm4, 32(%1)\n" + "movntq %%mm5, 40(%1)\n" + "emms\n" + :: "r" (pRead), "r" (pCurrPos) : "memory"); +#else + Error( "Implement CMeshBuilder::FastVertex(dx7) "); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + //m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + + movntps [edi + 0], xmm0 + movntps [edi + 16], xmm1 + movntps [edi + 32], xmm2 + } +#elif defined(GNUC) + const char *pRead = (char *)&vertex; + char *pCurrPos = (char *)m_pCurrPosition; + __m128 m1 = _mm_load_ps( (float *)pRead ); + __m128 m2 = _mm_load_ps( (float *)(pRead + 16) ); + __m128 m3 = _mm_load_ps( (float *)(pRead + 32) ); + _mm_stream_ps( (float *)pCurrPos, m1 ); + _mm_stream_ps( (float *)(pCurrPos + 16), m2 ); + _mm_stream_ps( (float *)(pCurrPos + 32), m3 ); +#else + Error( "Implement CMeshBuilder::FastVertexSSE(dx7)" ); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + //m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::Fast4VerticesSSE( + ModelVertexDX7_t const *vtx_a, + ModelVertexDX7_t const *vtx_b, + ModelVertexDX7_t const *vtx_c, + ModelVertexDX7_t const *vtx_d) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount-3 ); + +#if defined( _WIN32 ) && !defined( _X360 ) + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, vtx_a + mov ecx, vtx_b + + mov edi, pCurrPos + nop + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + movaps xmm3, [ecx + 0] + movaps xmm4, [ecx + 16] + movaps xmm5, [ecx + 32] + + mov esi, vtx_c + mov ecx, vtx_d + + movntps [edi + 0], xmm0 + movntps [edi + 16], xmm1 + movntps [edi + 32], xmm2 + movntps [edi + 48], xmm3 + movntps [edi + 64], xmm4 + movntps [edi + 80], xmm5 + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + movaps xmm3, [ecx + 0] + movaps xmm4, [ecx + 16] + movaps xmm5, [ecx + 32] + + movntps [edi + 0+96], xmm0 + movntps [edi + 16+96], xmm1 + movntps [edi + 32+96], xmm2 + movntps [edi + 48+96], xmm3 + movntps [edi + 64+96], xmm4 + movntps [edi + 80+96], xmm5 + + } +#else + Error( "Implement CMeshBuilder::Fast4VerticesSSE\n"); +#endif + IncrementFloatPointer( m_pCurrPosition, 4*m_VertexSize_Position ); + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::FastVertex( const ModelVertexDX8_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movq mm0, [esi + 0] + movq mm1, [esi + 8] + movq mm2, [esi + 16] + movq mm3, [esi + 24] + movq mm4, [esi + 32] + movq mm5, [esi + 40] + movq mm6, [esi + 48] + movq mm7, [esi + 56] + + movntq [edi + 0], mm0 + movntq [edi + 8], mm1 + movntq [edi + 16], mm2 + movntq [edi + 24], mm3 + movntq [edi + 32], mm4 + movntq [edi + 40], mm5 + movntq [edi + 48], mm6 + movntq [edi + 56], mm7 + + emms + } +#elif defined(GNUC) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movq 48(%0), %%mm6\n" + "movq 56(%0), %%mm7\n" + "movntq %%mm0, (%1)\n" + "movntq %%mm1, 8(%1)\n" + "movntq %%mm2, 16(%1)\n" + "movntq %%mm3, 24(%1)\n" + "movntq %%mm4, 32(%1)\n" + "movntq %%mm5, 40(%1)\n" + "movntq %%mm6, 48(%1)\n" + "movntq %%mm7, 56(%1)\n" + "emms\n" + :: "r" (pRead), "r" (pCurrPos) : "memory"); +#else + Error( "Implement CMeshBuilder::FastVertex(dx8)" ); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + // m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + movaps xmm3, [esi + 48] + + movntps [edi + 0], xmm0 + movntps [edi + 16], xmm1 + movntps [edi + 32], xmm2 + movntps [edi + 48], xmm3 + } +#elif defined(GNUC) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm__ __volatile__ ( + "movaps (%0), %%xmm0\n" + "movaps 16(%0), %%xmm1\n" + "movaps 32(%0), %%xmm2\n" + "movaps 48(%0), %%xmm3\n" + "movntps %%xmm0, (%1)\n" + "movntps %%xmm1, 16(%1)\n" + "movntps %%xmm2, 32(%1)\n" + "movntps %%xmm3, 48(%1)\n" + :: "r" (pRead), "r" (pCurrPos) : "memory"); +#else + Error( "Implement CMeshBuilder::FastVertexSSE((dx8)" ); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + // m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} +#endif // COMPILER_MSVC64 + + +//----------------------------------------------------------------------------- +// Returns the current vertex +//----------------------------------------------------------------------------- +inline int CVertexBuilder::GetCurrentVertex() const +{ + return m_nCurrentVertex; +} + + +//----------------------------------------------------------------------------- +// Copies a vertex into the x360 format +//----------------------------------------------------------------------------- +#if defined( _X360 ) +inline void CVertexBuilder::VertexDX8ToX360( const ModelVertexDX8_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + + // get the start of the data + unsigned char *pDst = (unsigned char*)m_pCurrPosition; + + Assert( m_VertexSize_Position > 0 ); // Assume position is always present + Assert( GetVertexElementSize( VERTEX_ELEMENT_POSITION, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecPosition ) ); + memcpy( pDst, vertex.m_vecPosition.Base(), sizeof( vertex.m_vecPosition ) ); + pDst += sizeof( vertex.m_vecPosition ); + + if ( m_VertexSize_BoneWeight ) + { + Assert( vertex.m_flBoneWeights[0] >= 0 && vertex.m_flBoneWeights[0] <= 1.0f ); + Assert( vertex.m_flBoneWeights[1] >= 0 && vertex.m_flBoneWeights[1] <= 1.0f ); + Assert( GetVertexElementSize( VERTEX_ELEMENT_BONEWEIGHTS2, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_flBoneWeights ) ); + memcpy( pDst, vertex.m_flBoneWeights.Base(), sizeof( vertex.m_flBoneWeights ) ); + pDst += sizeof( vertex.m_flBoneWeights ); + + if ( m_VertexSize_BoneMatrixIndex ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_BONEINDEX, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_nBoneIndices ) ); + *(unsigned int*)pDst = vertex.m_nBoneIndices; + pDst += sizeof( vertex.m_nBoneIndices ); + } + } + + if ( m_VertexSize_Normal ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_NORMAL, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecNormal ) ); + memcpy( pDst, vertex.m_vecNormal.Base(), sizeof( vertex.m_vecNormal ) ); + pDst += sizeof( vertex.m_vecNormal ); + } + + if ( m_VertexSize_Color ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_COLOR, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_nColor ) ); + *(unsigned int*)pDst = vertex.m_nColor; + pDst += sizeof( vertex.m_nColor ); + } + + if ( m_VertexSize_TexCoord[0] ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_TEXCOORD2D_0, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecTexCoord ) ); + memcpy( pDst, vertex.m_vecTexCoord.Base(), sizeof( vertex.m_vecTexCoord ) ); + pDst += sizeof( vertex.m_vecTexCoord ); + } + + if ( m_VertexSize_UserData ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_USERDATA4, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecUserData ) ); + memcpy( pDst, vertex.m_vecUserData.Base(), sizeof( vertex.m_vecUserData ) ); + pDst += sizeof( vertex.m_vecUserData ); + } + + // ensure code is synced with the mesh builder that established the offsets + Assert( pDst - (unsigned char*)m_pCurrPosition == m_VertexSize_Position ); + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} +#endif + + +//----------------------------------------------------------------------------- +// Data retrieval... +//----------------------------------------------------------------------------- +inline const float* CVertexBuilder::Position() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pCurrPosition; +} + +inline const float* CVertexBuilder::Normal() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pCurrNormal; +} + +inline unsigned int CVertexBuilder::Color() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + // Swizzle it so it returns the same format as accepted by Color4ubv - rgba + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + unsigned int color; + if ( IsPC() || !IsX360() ) + { + color = (m_pCurrColor[3] << 24) | (m_pCurrColor[0] << 16) | (m_pCurrColor[1] << 8) | (m_pCurrColor[2]); + } + else + { + // in memory as argb, back to rgba + color = (m_pCurrColor[1] << 24) | (m_pCurrColor[2] << 16) | (m_pCurrColor[3] << 8) | (m_pCurrColor[0]); + } + return color; +} + +inline unsigned char *CVertexBuilder::Specular() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pSpecular + m_nCurrentVertex * m_VertexSize_Specular; +} + +inline const float* CVertexBuilder::TexCoord( int stage ) const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pCurrTexCoord[stage]; +} + +inline const float* CVertexBuilder::TangentS() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS ); +} + +inline const float* CVertexBuilder::TangentT() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT ); +} + +inline float CVertexBuilder::Wrinkle() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return *OffsetFloatPointer( m_pWrinkle, m_nCurrentVertex, m_VertexSize_Wrinkle ); +} + +inline const float* CVertexBuilder::BoneWeight() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight ); +} + +inline int CVertexBuilder::NumBoneWeights() const +{ + return m_NumBoneWeights; +} + +#ifndef NEW_SKINNING +inline unsigned char* CVertexBuilder::BoneMatrix() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pBoneMatrixIndex + m_nCurrentVertex * m_VertexSize_BoneMatrixIndex; +} +#else +inline float* CVertexBuilder::BoneMatrix() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pBoneMatrixIndex + m_nCurrentVertex * m_VertexSize_BoneMatrixIndex; +} +#endif + + +//----------------------------------------------------------------------------- +// Position setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Position3f( float x, float y, float z ) +{ + Assert( m_pPosition && m_pCurrPosition ); + Assert( IsFinite(x) && IsFinite(y) && IsFinite(z) ); + float *pDst = m_pCurrPosition; + *pDst++ = x; + *pDst++ = y; + *pDst = z; +} + +inline void CVertexBuilder::Position3fv( const float *v ) +{ + Assert(v); + Assert( m_pPosition && m_pCurrPosition ); + + float *pDst = m_pCurrPosition; + *pDst++ = *v++; + *pDst++ = *v++; + *pDst = *v; +} + + +//----------------------------------------------------------------------------- +// Normal setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Normal3f( float nx, float ny, float nz ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( m_pNormal ); + Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) ); + Assert( nx >= -1.05f && nx <= 1.05f ); + Assert( ny >= -1.05f && ny <= 1.05f ); + Assert( nz >= -1.05f && nz <= 1.05f ); + + float *pDst = m_pCurrNormal; + *pDst++ = nx; + *pDst++ = ny; + *pDst = nz; +} + +inline void CVertexBuilder::Normal3fv( const float *n ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( n ); + Assert( m_pNormal && m_pCurrNormal ); + Assert( IsFinite(n[0]) && IsFinite(n[1]) && IsFinite(n[2]) ); + Assert( n[0] >= -1.05f && n[0] <= 1.05f ); + Assert( n[1] >= -1.05f && n[1] <= 1.05f ); + Assert( n[2] >= -1.05f && n[2] <= 1.05f ); + + float *pDst = m_pCurrNormal; + *pDst++ = *n++; + *pDst++ = *n++; + *pDst = *n; +} + +inline void CVertexBuilder::NormalDelta3f( float nx, float ny, float nz ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( m_pNormal ); + Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) ); + + float *pDst = m_pCurrNormal; + *pDst++ = nx; + *pDst++ = ny; + *pDst = nz; +} + +inline void CVertexBuilder::NormalDelta3fv( const float *n ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( n ); + Assert( m_pNormal && m_pCurrNormal ); + Assert( IsFinite(n[0]) && IsFinite(n[1]) && IsFinite(n[2]) ); + + float *pDst = m_pCurrNormal; + *pDst++ = *n++; + *pDst++ = *n++; + *pDst = *n; +} + +//----------------------------------------------------------------------------- +// Templatized normal setting methods which support compressed vertices +//----------------------------------------------------------------------------- +template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedNormal3f( float nx, float ny, float nz ) +{ + Assert( T == m_CompressionType ); + Assert( m_pNormal && m_pCurrNormal ); + Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) ); + Assert( nx >= -1.05f && nx <= 1.05f ); + Assert( ny >= -1.05f && ny <= 1.05f ); + Assert( nz >= -1.05f && nz <= 1.05f ); + // FIXME: studiorender is passing in non-unit normals + //float lengthSqd = nx*nx + ny*ny + nz*nz; + //Assert( lengthSqd >= 0.95f && lengthSqd <= 1.05f ); + + if ( T == VERTEX_COMPRESSION_ON ) + { +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + PackNormal_SHORT2( nx, ny, nz, (unsigned int *)m_pCurrNormal ); + +#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // NOTE: write the normal into the lower 16 bits of a word, clearing the top 16 bits - a userdata4 + // tangent must be written into the upper 16 bits by CompressedUserData() *AFTER* this. +#ifdef _DEBUG + Assert( m_bWrittenUserData == false ); + m_bWrittenNormal = true; +#endif + PackNormal_UBYTE4( nx, ny, nz, (unsigned int *)m_pCurrNormal ); +#endif + } + else + { + float *pDst = m_pCurrNormal; + *pDst++ = nx; + *pDst++ = ny; + *pDst = nz; + } +} + +template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedNormal3fv( const float *n ) +{ + Assert( n ); + CompressedNormal3f<T>( n[0], n[1], n[2] ); +} + + +//----------------------------------------------------------------------------- +// Color setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Color3f( float r, float g, float b ) +{ + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; +#endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color3fv( const float *rgb ) +{ + Assert(rgb); + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) ); + Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) ); + Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; +#else + int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; +#endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4f( float r, float g, float b, float a ) +{ + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) && IsFinite(a) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) && (a >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); +#endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4fv( const float *rgba ) +{ + Assert(rgba); + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(rgba[0]) && IsFinite(rgba[1]) && IsFinite(rgba[2]) && IsFinite(rgba[3]) ); + Assert( (rgba[0] >= 0.0) && (rgba[1] >= 0.0) && (rgba[2] >= 0.0) && (rgba[3] >= 0.0) ); + Assert( (rgba[0] <= 1.0) && (rgba[1] <= 1.0) && (rgba[2] <= 1.0) && (rgba[3] <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgba[0])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[2]) << 16) | (FastFToC(rgba[3]) << 24); +#else + int col = (FastFToC(rgba[2])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[0]) << 16) | (FastFToC(rgba[3]) << 24); +#endif + *(int*)m_pCurrColor = col; +} + + +//----------------------------------------------------------------------------- +// Faster versions of color +//----------------------------------------------------------------------------- + +// note that on the OSX target (OpenGL) whenever there is vertex data being written as bytes - they need to be written in R,G,B,A memory order + +inline void CVertexBuilder::Color3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | 0xFF000000; + #endif + + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color3ubv( unsigned char const* rgb ) +{ + Assert(rgb); + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = rgb[0] | (rgb[1] << 8) | (rgb[2] << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = rgb[2] | (rgb[1] << 8) | (rgb[0] << 16) | 0xFF000000; + #endif + + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | (a << 24); + #endif + + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4ubv( unsigned char const* rgba ) +{ + Assert( rgba ); + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = rgba[0] | (rgba[1] << 8) | (rgba[2] << 16) | (rgba[3] << 24); // r, g, b, a in memory + #else + int col = rgba[2] | (rgba[1] << 8) | (rgba[0] << 16) | (rgba[3] << 24); + #endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Specular3f( float r, float g, float b ) +{ + Assert( m_pSpecular ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular3fv( const float *rgb ) +{ + Assert(rgb); + Assert( m_pSpecular ); + Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) ); + Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) ); + Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; +#else + int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4f( float r, float g, float b, float a ) +{ + Assert( m_pSpecular ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) && IsFinite(a) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) && (a >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0f) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4fv( const float *rgb ) +{ + Assert(rgb); + Assert( m_pSpecular ); + Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) && IsFinite(rgb[3]) ); + Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) && (rgb[3] >= 0.0) ); + Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) && (rgb[3] <= 1.0) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | (FastFToC(rgb[3]) << 24); +#else + int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | (FastFToC(rgb[3]) << 24); +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | 0xFF000000; + #endif + + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular3ubv( unsigned char const *c ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = c[0] | (c[1] << 8) | (c[2] << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = c[2] | (c[1] << 8) | (c[0] << 16) | 0xFF000000; + #endif + + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | (a << 24); + #endif + + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4ubv( unsigned char const *c ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + #else + int col = c[2] | (c[1] << 8) | (c[0] << 16) | (c[3] << 24); + #endif + + *(int*)pSpecular = col; +} + + +//----------------------------------------------------------------------------- +// Texture coordinate setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::TexCoord1f( int nStage, float s ) +{ + Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] ); + Assert( IsFinite(s) ); + + float *pDst = m_pCurrTexCoord[nStage]; + *pDst = s; +} + +inline void CVertexBuilder::TexCoord2f( int nStage, float s, float t ) +{ + Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] ); + Assert( IsFinite(s) && IsFinite(t) ); + + float *pDst = m_pCurrTexCoord[nStage]; + *pDst++ = s; + *pDst = t; +} + +inline void CVertexBuilder::TexCoord2fv( int nStage, const float *st ) +{ + Assert(st); + Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] ); + Assert( IsFinite(st[0]) && IsFinite(st[1]) ); + + float *pDst = m_pCurrTexCoord[nStage]; + *pDst++ = *st++; + *pDst = *st; +} + +inline void CVertexBuilder::TexCoord3f( int stage, float s, float t, float u ) +{ + // Tried to add too much! + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(s) && IsFinite(t) && IsFinite(u) ); + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = s; + *pDst++ = t; + *pDst = u; +} + +inline void CVertexBuilder::TexCoord3fv( int stage, const float *stu ) +{ + Assert(stu); + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(stu[0]) && IsFinite(stu[1]) && IsFinite(stu[2]) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = *stu++; + *pDst++ = *stu++; + *pDst = *stu; +} + +inline void CVertexBuilder::TexCoord4f( int stage, float s, float t, float u, float v ) +{ + // Tried to add too much! + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(s) && IsFinite(t) && IsFinite(u) ); + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = s; + *pDst++ = t; + *pDst++ = u; + *pDst = v; +} + +inline void CVertexBuilder::TexCoord4fv( int stage, const float *stuv ) +{ + Assert(stuv); + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(stuv[0]) && IsFinite(stuv[1]) && IsFinite(stuv[2]) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = *stuv++; + *pDst++ = *stuv++; + *pDst++ = *stuv++; + *pDst = *stuv; +} + + +inline void CVertexBuilder::TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ) +{ + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(s) && IsFinite(t) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = ( s * scaleS ) + offsetS; + *pDst = ( t * scaleT ) + offsetT; +} + +inline void CVertexBuilder::TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ) +{ + Assert(st); + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(st[0]) && IsFinite(st[1]) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = ( *st++ * *scale++ ) + *offset++; + *pDst = ( *st * *scale ) + *offset; +} + + +//----------------------------------------------------------------------------- +// Tangent space setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::TangentS3f( float sx, float sy, float sz ) +{ + Assert( m_pTangentS ); + Assert( IsFinite(sx) && IsFinite(sy) && IsFinite(sz) ); + + float* pTangentS = OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS ); + *pTangentS++ = sx; + *pTangentS++ = sy; + *pTangentS = sz; +} + +inline void CVertexBuilder::TangentS3fv( const float* s ) +{ + Assert( s ); + Assert( m_pTangentS ); + Assert( IsFinite(s[0]) && IsFinite(s[1]) && IsFinite(s[2]) ); + + float* pTangentS = OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS ); + *pTangentS++ = *s++; + *pTangentS++ = *s++; + *pTangentS = *s; +} + +inline void CVertexBuilder::TangentT3f( float tx, float ty, float tz ) +{ + Assert( m_pTangentT ); + Assert( IsFinite(tx) && IsFinite(ty) && IsFinite(tz) ); + + float* pTangentT = OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT ); + *pTangentT++ = tx; + *pTangentT++ = ty; + *pTangentT = tz; +} + +inline void CVertexBuilder::TangentT3fv( const float* t ) +{ + Assert( t ); + Assert( m_pTangentT ); + Assert( IsFinite(t[0]) && IsFinite(t[1]) && IsFinite(t[2]) ); + + float* pTangentT = OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT ); + *pTangentT++ = *t++; + *pTangentT++ = *t++; + *pTangentT = *t; +} + + +//----------------------------------------------------------------------------- +// Wrinkle setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Wrinkle1f( float flWrinkle ) +{ + Assert( m_pWrinkle ); + Assert( IsFinite(flWrinkle) ); + + float *pWrinkle = OffsetFloatPointer( m_pWrinkle, m_nCurrentVertex, m_VertexSize_Wrinkle ); + *pWrinkle = flWrinkle; +} + + +//----------------------------------------------------------------------------- +// Bone weight setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::BoneWeight( int idx, float weight ) +{ + Assert( m_pBoneWeight ); + Assert( IsFinite( weight ) ); + Assert( idx >= 0 ); + AssertOnce( m_NumBoneWeights == 2 ); + + // This test is here because we store N-1 bone weights (the Nth is computed in + // the vertex shader as "1 - C", where C is the sum of the (N-1) other weights) + if ( idx < m_NumBoneWeights ) + { + float* pBoneWeight = OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight ); + pBoneWeight[idx] = weight; + } +} + +static int sg_IndexSwap[4] = { 2, 1, 0, 3 }; + +inline void CVertexBuilder::BoneMatrix( int idx, int matrixIdx ) +{ + Assert( m_pBoneMatrixIndex ); + Assert( idx >= 0 ); + Assert( idx < 4 ); + + // garymcthack + if ( matrixIdx == BONE_MATRIX_INDEX_INVALID ) + { + matrixIdx = 0; + } + Assert( (matrixIdx >= 0) && (matrixIdx < 53) ); + +#ifdef OPENGL_SWAP_COLORS + idx = sg_IndexSwap[idx]; +#endif + +#ifndef NEW_SKINNING + unsigned char* pBoneMatrix = &m_pBoneMatrixIndex[m_nCurrentVertex * m_VertexSize_BoneMatrixIndex]; + if ( IsX360() ) + { + // store sequentially as wzyx order, gpu delivers as xyzw + idx = 3-idx; + } + pBoneMatrix[idx] = (unsigned char)matrixIdx; +#else + float* pBoneMatrix = &m_pBoneMatrixIndex[m_nCurrentVertex * m_VertexSize_BoneMatrixIndex]; + pBoneMatrix[idx] = matrixIdx; +#endif +} + +//----------------------------------------------------------------------------- +// Templatized bone weight setting methods which support compressed vertices +//----------------------------------------------------------------------------- +template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedBoneWeight3fv( const float * pWeights ) +{ + Assert( T == m_CompressionType ); + Assert( m_pBoneWeight ); + Assert( pWeights ); + + float *pDestWeights = OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight ); + + if ( T == VERTEX_COMPRESSION_ON ) + { + // Quantize to 15 bits per weight (we use D3DDECLTYPE_SHORT2) + // NOTE: we perform careful normalization (weights sum to 1.0f in the vertex shader), so + // as to avoid cracking at boundaries between meshes with different numbers of weights + // per vertex. For example, (1) needs to yield the same normalized weights as (1,0), + // and (0.5,0.49) needs to normalize the same normalized weights as (0.5,0.49,0). + // The key is that values which are *computed* in the shader (e.g. the second weight + // in a 2-weight mesh) must exactly equal values which are *read* from the vertex + // stream (e.g. the second weight in a 3-weight mesh). + + // Only 1 or 2 weights (SHORT2N) supported for compressed verts so far + Assert( m_NumBoneWeights <= 2 ); + + const int WEIGHT0_SHIFT = IsX360() ? 16 : 0; + const int WEIGHT1_SHIFT = IsX360() ? 0 : 16; + unsigned int *weights = (unsigned int *)pDestWeights; + + // We scale our weights so that they sum to 32768, then subtract 1 (which gets added + // back in the shader), because dividing by 32767 introduces nasty rounding issues. + Assert( IsFinite( pWeights[0] ) && ( pWeights[0] >= 0.0f ) && ( pWeights[0] <= 1.0f ) ); + unsigned int weight0 = Float2Int( pWeights[0] * 32768.0f ); + *weights = ( 0x0000FFFF & (weight0 - 1) ) << WEIGHT0_SHIFT; + +#ifdef DEBUG + if ( m_NumBoneWeights == 1 ) + { + // Double-check the validity of the values that were passed in + Assert( IsFinite( pWeights[1] ) && ( pWeights[1] >= 0.0f ) && ( pWeights[1] <= 1.0f ) ); + unsigned int weight1 = Float2Int( pWeights[1] * 32768.0f ); + Assert( ( weight0 + weight1 ) <= 32768 ); + } +#endif + + if ( m_NumBoneWeights > 1 ) + { + // This path for 3 weights per vert (2 are stored and the 3rd is computed + // in the shader - we do post-quantization normalization here in such a + // way as to avoid mesh-boundary cracking) + Assert( m_NumBoneWeights == 2 ); + Assert( IsFinite( pWeights[1] ) && ( pWeights[1] >= 0.0f ) && ( pWeights[1] <= 1.0f ) ); + Assert( IsFinite( pWeights[2] ) && ( pWeights[2] >= 0.0f ) && ( pWeights[2] <= 1.0f ) ); + unsigned int weight1 = Float2Int( pWeights[1] * 32768.0f ); + unsigned int weight2 = Float2Int( pWeights[2] * 32768.0f ); + Assert( ( weight0 + weight1 + weight2 ) <= 32768 ); + unsigned int residual = 32768 - ( weight0 + weight1 + weight2 ); + weight1 += residual; // Normalize + *weights |= ( 0x0000FFFF & ( weight1 - 1 ) ) << WEIGHT1_SHIFT; + } + } + else // Uncompressed path + { + pDestWeights[0] = pWeights[0]; + pDestWeights[1] = pWeights[1]; + } +} + +//----------------------------------------------------------------------------- +// Generic per-vertex data setting method +//----------------------------------------------------------------------------- +inline void CVertexBuilder::UserData( const float* pData ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( pData ); + + int userDataSize = 4; // garymcthack + float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData ); + memcpy( pUserData, pData, sizeof( float ) * userDataSize ); +} + +//----------------------------------------------------------------------------- +// Templatized generic per-vertex data setting method which supports compressed vertices +//----------------------------------------------------------------------------- +template <VertexCompressionType_t T> inline void CVertexBuilder::CompressedUserData( const float* pData ) +{ + Assert( T == m_CompressionType ); + Assert( pData ); + // This is always in fact a tangent vector, not generic 'userdata' + Assert( IsFinite(pData[0]) && IsFinite(pData[1]) && IsFinite(pData[2]) ); + Assert( pData[0] >= -1.05f && pData[0] <= 1.05f ); + Assert( pData[1] >= -1.05f && pData[1] <= 1.05f ); + Assert( pData[2] >= -1.05f && pData[2] <= 1.05f ); + Assert( pData[3] == +1.0f || pData[3] == -1.0f ); + // FIXME: studiorender is passing in non-unit normals + //float lengthSqd = pData[0]*pData[0] + pData[1]*pData[1] + pData[2]*pData[2]; + //Assert( lengthSqd >= 0.95f && lengthSqd <= 1.05f ); + + if ( T == VERTEX_COMPRESSION_ON ) + { + float binormalSign = pData[3]; + +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData ); + PackNormal_SHORT2( pData, (unsigned int *)pUserData, binormalSign ); +#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // FIXME: add a combined CompressedNormalAndTangent() accessor, to avoid reading back from write-combined memory here + // The normal should have already been written into the lower 16 + // bits - here, we OR in the tangent into the upper 16 bits + unsigned int existingNormalData = *(unsigned int *)m_pCurrNormal; + Assert( ( existingNormalData & 0xFFFF0000 ) == 0 ); +#ifdef _DEBUG + Assert( m_bWrittenNormal == true ); + m_bWrittenUserData = true; +#endif + bool bIsTangent = true; + unsigned int tangentData = 0; + PackNormal_UBYTE4( pData, &tangentData, bIsTangent, binormalSign ); + *(unsigned int *)m_pCurrNormal = existingNormalData | tangentData; +#endif + } + else + { + int userDataSize = 4; // garymcthack + float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData ); + memcpy( pUserData, pData, sizeof( float ) * userDataSize ); + } +} + + +//----------------------------------------------------------------------------- +// +// Helper class used to define index buffers +// +//----------------------------------------------------------------------------- +class CIndexBuilder : private IndexDesc_t +{ +public: + CIndexBuilder(); + CIndexBuilder( IIndexBuffer *pIndexBuffer, MaterialIndexFormat_t fmt = MATERIAL_INDEX_FORMAT_UNKNOWN ); + ~CIndexBuilder(); + + // Begins, ends modification of the index buffer (returns true if the lock succeeded) + // A lock may not succeed if append is set to true and there isn't enough room + // NOTE: Append is only used with dynamic index buffers; it's ignored for static buffers + bool Lock( int nMaxIndexCount, int nIndexOffset, bool bAppend = false ); + void Unlock(); + + // Spews the current data + // NOTE: Can only be called during a lock/unlock block + void SpewData(); + + // Returns the number of indices we can fit into the buffer without needing to discard + int GetRoomRemaining() const; + + // Binds this index buffer + void Bind( IMatRenderContext *pContext ); + + // Returns the byte offset + int Offset() const; + + // Begins, ends modification of the index buffer + // NOTE: IndexOffset is the number to add to all indices written into the buffer; + // useful when using dynamic vertex buffers. + void Begin( IIndexBuffer *pIndexBuffer, int nMaxIndexCount, int nIndexOffset = 0 ); + void End( bool bSpewData = false ); + + // Locks the index buffer to modify existing data + // Passing nVertexCount == -1 says to lock all the vertices for modification. + // Pass 0 for nIndexCount to not lock the index buffer. + void BeginModify( IIndexBuffer *pIndexBuffer, int nFirstIndex = 0, int nIndexCount = 0, int nIndexOffset = 0 ); + void EndModify( bool bSpewData = false ); + + // returns the number of indices + int IndexCount() const; + + // Returns the total number of indices across all Locks() + int TotalIndexCount() const; + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + // Selects the nth Index + void SelectIndex( int nBufferIndex ); + + // Advances the current index by one + void AdvanceIndex(); + void AdvanceIndices( int nIndexCount ); + + int GetCurrentIndex(); + int GetFirstIndex() const; + + unsigned short const* Index() const; + + // Used to define the indices (only used if you aren't using primitives) + void Index( unsigned short nIndex ); + + // Fast Index! No need to call advance index, and no random access allowed + void FastIndex( unsigned short nIndex ); + + // NOTE: This version is the one you really want to achieve write-combining; + // Write combining only works if you write in 4 bytes chunks. + void FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ); + + // Generates indices for a particular primitive type + void GenerateIndices( MaterialPrimitiveType_t primitiveType, int nIndexCount ); + + // FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. + void AttachBegin( IMesh* pMesh, int nMaxIndexCount, const MeshDesc_t &desc ); + void AttachEnd(); + void AttachBeginModify( IMesh* pMesh, int nFirstIndex, int nIndexCount, const MeshDesc_t &desc ); + void AttachEndModify(); + + void FastTriangle( int startVert ); + void FastQuad( int startVert ); + void FastPolygon( int startVert, int numTriangles ); + void FastPolygonList( int startVert, int *pVertexCount, int polygonCount ); + void FastIndexList( const unsigned short *pIndexList, int startVert, int indexCount ); + +private: + // The mesh we're modifying + IIndexBuffer *m_pIndexBuffer; + + // Max number of indices + int m_nMaxIndexCount; + + // Number of indices + int m_nIndexCount; + + // Offset to add to each index as it's written into the buffer + int m_nIndexOffset; + + // The current index + mutable int m_nCurrentIndex; + + // Total number of indices appended + int m_nTotalIndexCount; + + // First index buffer offset + first index + unsigned int m_nBufferOffset; + unsigned int m_nBufferFirstIndex; + + // Used to make sure Begin/End calls and BeginModify/EndModify calls match. + bool m_bModify; +}; + + +//----------------------------------------------------------------------------- +// +// Inline methods related to CIndexBuilder +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +inline CIndexBuilder::CIndexBuilder() : m_pIndexBuffer(0), m_nIndexCount(0), + m_nCurrentIndex(0), m_nMaxIndexCount(0) +{ + m_nTotalIndexCount = 0; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstIndex = 0; +#ifdef _DEBUG + m_bModify = false; +#endif +} + +inline CIndexBuilder::CIndexBuilder( IIndexBuffer *pIndexBuffer, MaterialIndexFormat_t fmt ) +{ + m_pIndexBuffer = pIndexBuffer; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstIndex = 0; + m_nIndexCount = 0; + m_nCurrentIndex = 0; + m_nMaxIndexCount = 0; + m_nTotalIndexCount = 0; + if ( m_pIndexBuffer->IsDynamic() ) + { + m_pIndexBuffer->BeginCastBuffer( fmt ); + } + else + { + Assert( m_pIndexBuffer->IndexFormat() == fmt ); + } +#ifdef _DEBUG + m_bModify = false; +#endif +} + +inline CIndexBuilder::~CIndexBuilder() +{ + if ( m_pIndexBuffer && m_pIndexBuffer->IsDynamic() ) + { + m_pIndexBuffer->EndCastBuffer(); + } +} + + +//----------------------------------------------------------------------------- +// Begins, ends modification of the index buffer +//----------------------------------------------------------------------------- +inline bool CIndexBuilder::Lock( int nMaxIndexCount, int nIndexOffset, bool bAppend ) +{ + Assert( m_pIndexBuffer ); + m_bModify = false; + m_nIndexOffset = nIndexOffset; + m_nMaxIndexCount = nMaxIndexCount; + bool bFirstLock = ( m_nBufferOffset == INVALID_BUFFER_OFFSET ); + if ( bFirstLock ) + { + bAppend = false; + } + if ( !bAppend ) + { + m_nTotalIndexCount = 0; + } + Reset(); + + // Lock the index buffer + if ( !m_pIndexBuffer->Lock( m_nMaxIndexCount, bAppend, *this ) ) + { + m_nMaxIndexCount = 0; + return false; + } + + if ( bFirstLock ) + { + m_nBufferOffset = m_nOffset; + m_nBufferFirstIndex = m_nFirstIndex; + } + + return true; +} + +inline void CIndexBuilder::Unlock() +{ + Assert( !m_bModify && m_pIndexBuffer ); + + m_pIndexBuffer->Unlock( m_nIndexCount, *this ); + m_nTotalIndexCount += m_nIndexCount; + + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + +inline void CIndexBuilder::SpewData() +{ + m_pIndexBuffer->Spew( m_nIndexCount, *this ); +} + + +//----------------------------------------------------------------------------- +// Binds this index buffer +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Bind( IMatRenderContext *pContext ) +{ + if ( m_pIndexBuffer && ( m_nBufferOffset != INVALID_BUFFER_OFFSET ) ) + { + pContext->BindIndexBuffer( m_pIndexBuffer, m_nBufferOffset ); + } + else + { + pContext->BindIndexBuffer( NULL, 0 ); + } +} + + +//----------------------------------------------------------------------------- +// Returns the byte offset +//----------------------------------------------------------------------------- +inline int CIndexBuilder::Offset() const +{ + return m_nBufferOffset; +} + +inline int CIndexBuilder::GetFirstIndex() const +{ + return m_nBufferFirstIndex; +} + + +//----------------------------------------------------------------------------- +// Begins, ends modification of the index buffer +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Begin( IIndexBuffer *pIndexBuffer, int nMaxIndexCount, int nIndexOffset ) +{ + Assert( pIndexBuffer && (!m_pIndexBuffer) ); + + m_pIndexBuffer = pIndexBuffer; + m_nIndexCount = 0; + m_nMaxIndexCount = nMaxIndexCount; + m_nIndexOffset = nIndexOffset; + + m_bModify = false; + + // Lock the index buffer + m_pIndexBuffer->Lock( m_nMaxIndexCount, false, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::End( bool bSpewData ) +{ + // Make sure they called Begin() + Assert( !m_bModify ); + + if ( bSpewData ) + { + m_pIndexBuffer->Spew( m_nIndexCount, *this ); + } + + // Unlock our buffers + m_pIndexBuffer->Unlock( m_nIndexCount, *this ); + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Begins, ends modification of an existing index buffer which has already been filled out +//----------------------------------------------------------------------------- +inline void CIndexBuilder::BeginModify( IIndexBuffer* pIndexBuffer, int nFirstIndex, int nIndexCount, int nIndexOffset ) +{ + m_pIndexBuffer = pIndexBuffer; + m_nIndexCount = nIndexCount; + m_nMaxIndexCount = nIndexCount; + m_nIndexOffset = nIndexOffset; + m_bModify = true; + + // Lock the vertex and index buffer + m_pIndexBuffer->ModifyBegin( false, nFirstIndex, nIndexCount, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::EndModify( bool bSpewData ) +{ + Assert( m_pIndexBuffer ); + Assert( m_bModify ); // Make sure they called BeginModify. + + if ( bSpewData ) + { + m_pIndexBuffer->Spew( m_nIndexCount, *this ); + } + + // Unlock our buffers + m_pIndexBuffer->ModifyEnd( *this ); + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. +//----------------------------------------------------------------------------- +inline void CIndexBuilder::AttachBegin( IMesh* pMesh, int nMaxIndexCount, const MeshDesc_t &desc ) +{ + m_pIndexBuffer = pMesh; + m_nIndexCount = 0; + m_nMaxIndexCount = nMaxIndexCount; + + m_bModify = false; + + // Copy relevant data from the mesh desc + m_nIndexOffset = desc.m_nFirstVertex; + m_pIndices = desc.m_pIndices; + m_nIndexSize = desc.m_nIndexSize; + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::AttachEnd() +{ + Assert( m_pIndexBuffer ); + Assert( !m_bModify ); // Make sure they called AttachBegin. + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + +inline void CIndexBuilder::AttachBeginModify( IMesh* pMesh, int nFirstIndex, int nIndexCount, const MeshDesc_t &desc ) +{ + m_pIndexBuffer = pMesh; + m_nIndexCount = nIndexCount; + m_nMaxIndexCount = nIndexCount; + m_bModify = true; + + // Copy relevant data from the mesh desc + m_nIndexOffset = desc.m_nFirstVertex; + m_pIndices = desc.m_pIndices; + m_nIndexSize = desc.m_nIndexSize; + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::AttachEndModify() +{ + Assert( m_pIndexBuffer ); + Assert( m_bModify ); // Make sure they called AttachBeginModify. + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Resets the index buffer builder so it points to the start of everything again +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Reset() +{ + m_nCurrentIndex = 0; +} + + +//----------------------------------------------------------------------------- +// returns the number of indices +//----------------------------------------------------------------------------- +inline int CIndexBuilder::IndexCount() const +{ + return m_nIndexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the total number of indices across all Locks() +//----------------------------------------------------------------------------- +inline int CIndexBuilder::TotalIndexCount() const +{ + return m_nTotalIndexCount; +} + + +//----------------------------------------------------------------------------- +// Advances the current index +//----------------------------------------------------------------------------- +inline void CIndexBuilder::AdvanceIndex() +{ + m_nCurrentIndex += m_nIndexSize; + if ( m_nCurrentIndex > m_nIndexCount ) + { + m_nIndexCount = m_nCurrentIndex; + } +} + +inline void CIndexBuilder::AdvanceIndices( int nIndices ) +{ + m_nCurrentIndex += nIndices * m_nIndexSize; + if ( m_nCurrentIndex > m_nIndexCount ) + { + m_nIndexCount = m_nCurrentIndex; + } +} + + +//----------------------------------------------------------------------------- +// Returns the current index +//----------------------------------------------------------------------------- +inline int CIndexBuilder::GetCurrentIndex() +{ + return m_nCurrentIndex; +} + +inline unsigned short const* CIndexBuilder::Index() const +{ + Assert( m_nCurrentIndex < m_nMaxIndexCount ); + return &m_pIndices[m_nCurrentIndex]; +} + +inline void CIndexBuilder::SelectIndex( int nIndex ) +{ + Assert( ( nIndex >= 0 ) && ( nIndex < m_nIndexCount ) ); + m_nCurrentIndex = nIndex * m_nIndexSize; +} + + +//----------------------------------------------------------------------------- +// Used to write data into the index buffer +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Index( unsigned short nIndex ) +{ + Assert( m_pIndices ); + Assert( m_nCurrentIndex < m_nMaxIndexCount ); + m_pIndices[ m_nCurrentIndex ] = (unsigned short)( m_nIndexOffset + nIndex ); +} + +// Fast Index! No need to call advance index +inline void CIndexBuilder::FastIndex( unsigned short nIndex ) +{ + Assert( m_pIndices ); + Assert( m_nCurrentIndex < m_nMaxIndexCount ); + m_pIndices[m_nCurrentIndex] = (unsigned short)( m_nIndexOffset + nIndex ); + m_nCurrentIndex += m_nIndexSize; + m_nIndexCount = m_nCurrentIndex; +} + +inline void CIndexBuilder::FastTriangle( int startVert ) +{ + startVert += m_nIndexOffset; + m_pIndices[m_nCurrentIndex+0] = startVert; + m_pIndices[m_nCurrentIndex+1] = startVert + 1; + m_pIndices[m_nCurrentIndex+2] = startVert + 2; + + AdvanceIndices(3); +} + +inline void CIndexBuilder::FastQuad( int startVert ) +{ + startVert += m_nIndexOffset; + m_pIndices[m_nCurrentIndex+0] = startVert; + m_pIndices[m_nCurrentIndex+1] = startVert + 1; + m_pIndices[m_nCurrentIndex+2] = startVert + 2; + m_pIndices[m_nCurrentIndex+3] = startVert; + m_pIndices[m_nCurrentIndex+4] = startVert + 2; + m_pIndices[m_nCurrentIndex+5] = startVert + 3; + AdvanceIndices(6); +} + +inline void CIndexBuilder::FastPolygon( int startVert, int triangleCount ) +{ + unsigned short *pIndex = &m_pIndices[m_nCurrentIndex]; + startVert += m_nIndexOffset; + if ( !IsX360() ) + { + // NOTE: IndexSize is 1 or 0 (0 for alt-tab) + // This prevents us from writing into bogus memory + Assert( m_nIndexSize == 0 || m_nIndexSize == 1 ); + triangleCount *= m_nIndexSize; + } + for ( int v = 0; v < triangleCount; ++v ) + { + *pIndex++ = startVert; + *pIndex++ = startVert + v + 1; + *pIndex++ = startVert + v + 2; + } + AdvanceIndices(triangleCount*3); +} + +inline void CIndexBuilder::FastPolygonList( int startVert, int *pVertexCount, int polygonCount ) +{ + unsigned short *pIndex = &m_pIndices[m_nCurrentIndex]; + startVert += m_nIndexOffset; + int indexOut = 0; + + if ( !IsX360() ) + { + // NOTE: IndexSize is 1 or 0 (0 for alt-tab) + // This prevents us from writing into bogus memory + Assert( m_nIndexSize == 0 || m_nIndexSize == 1 ); + polygonCount *= m_nIndexSize; + } + + for ( int i = 0; i < polygonCount; i++ ) + { + int vertexCount = pVertexCount[i]; + int triangleCount = vertexCount-2; + for ( int v = 0; v < triangleCount; ++v ) + { + *pIndex++ = startVert; + *pIndex++ = startVert + v + 1; + *pIndex++ = startVert + v + 2; + } + startVert += vertexCount; + indexOut += triangleCount * 3; + } + AdvanceIndices(indexOut); +} + +inline void CIndexBuilder::FastIndexList( const unsigned short *pIndexList, int startVert, int indexCount ) +{ + unsigned short *pIndexOut = &m_pIndices[m_nCurrentIndex]; + startVert += m_nIndexOffset; + if ( !IsX360() ) + { + // NOTE: IndexSize is 1 or 0 (0 for alt-tab) + // This prevents us from writing into bogus memory + Assert( m_nIndexSize == 0 || m_nIndexSize == 1 ); + indexCount *= m_nIndexSize; + } + for ( int i = 0; i < indexCount; ++i ) + { + pIndexOut[i] = startVert + pIndexList[i]; + } + AdvanceIndices(indexCount); +} + + +//----------------------------------------------------------------------------- +// NOTE: This version is the one you really want to achieve write-combining; +// Write combining only works if you write in 4 bytes chunks. +//----------------------------------------------------------------------------- +inline void CIndexBuilder::FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ) +{ + Assert( m_pIndices ); + Assert( m_nCurrentIndex < m_nMaxIndexCount - 1 ); +// Assert( ( (int)( &m_pIndices[m_nCurrentIndex] ) & 0x3 ) == 0 ); + +#ifndef _X360 + unsigned int nIndices = ( (unsigned int)nIndex1 + m_nIndexOffset ) | ( ( (unsigned int)nIndex2 + m_nIndexOffset ) << 16 ); +#else + unsigned int nIndices = ( (unsigned int)nIndex2 + m_nIndexOffset ) | ( ( (unsigned int)nIndex1 + m_nIndexOffset ) << 16 ); +#endif + + *(int*)( &m_pIndices[m_nCurrentIndex] ) = nIndices; + m_nCurrentIndex += m_nIndexSize + m_nIndexSize; + m_nIndexCount = m_nCurrentIndex; +} + + +//----------------------------------------------------------------------------- +// Generates indices for a particular primitive type +//----------------------------------------------------------------------------- +inline void CIndexBuilder::GenerateIndices( MaterialPrimitiveType_t primitiveType, int nIndexCount ) +{ + // FIXME: How to make this work with short vs int sized indices? + // Don't generate indices if we've got an empty buffer + if ( m_nIndexSize == 0 ) + return; + + int nMaxIndices = m_nMaxIndexCount - m_nCurrentIndex; + nIndexCount = Min( nMaxIndices, nIndexCount ); + if ( nIndexCount == 0 ) + return; + + unsigned short *pIndices = &m_pIndices[m_nCurrentIndex]; + + switch( primitiveType ) + { + case MATERIAL_INSTANCED_QUADS: + Assert(0); // Shouldn't get here (this primtype is unindexed) + break; + case MATERIAL_QUADS: + GenerateQuadIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_POLYGON: + GeneratePolygonIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_LINE_STRIP: + GenerateLineStripIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_LINE_LOOP: + GenerateLineLoopIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_POINTS: + Assert(0); // Shouldn't get here (this primtype is unindexed) + break; + default: + GenerateSequentialIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + } + + AdvanceIndices( nIndexCount ); +} + + +//----------------------------------------------------------------------------- +// +// Helper class used to define meshes +// +//----------------------------------------------------------------------------- +//class CMeshBuilder : private MeshDesc_t +// hack fixme +class CMeshBuilder : public MeshDesc_t +{ +public: + CMeshBuilder(); + ~CMeshBuilder() { Assert(!m_pMesh); } // if this fires you did a Begin() without an End() + + operator CIndexBuilder&() { return m_IndexBuilder; } + + // This must be called before Begin, if a vertex buffer with a compressed format is to be used + void SetCompressionType( VertexCompressionType_t compressionType ); + + // Locks the vertex buffer + // (*cannot* use the Index() call below) + void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int numPrimitives ); + + // Locks the vertex buffer, can specify arbitrary index lists + // (must use the Index() call below) + void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ); + void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ); + + // forward compat + void Begin( IVertexBuffer *pVertexBuffer, MaterialPrimitiveType_t type, int numPrimitives ); + void Begin( IVertexBuffer *pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ); + void Begin( IVertexBuffer *pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ); + + // Use this when you're done writing + // Set bDraw to true to call m_pMesh->Draw automatically. + void End( bool bSpewData = false, bool bDraw = false ); + + // Locks the vertex buffer to modify existing data + // Passing nVertexCount == -1 says to lock all the vertices for modification. + // Pass 0 for nIndexCount to not lock the index buffer. + void BeginModify( IMesh *pMesh, int nFirstVertex = 0, int nVertexCount = -1, int nFirstIndex = 0, int nIndexCount = 0 ); + void EndModify( bool bSpewData = false ); + + // A helper method since this seems to be done a whole bunch. + void DrawQuad( IMesh* pMesh, const float *v1, const float *v2, + const float *v3, const float *v4, unsigned char const *pColor, bool wireframe = false ); + + // returns the number of indices and vertices + int VertexCount() const; + int IndexCount() const; + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + // Returns the size of the vertex + int VertexSize() { return m_ActualVertexSize; } + + // returns the data size of a given texture coordinate + int TextureCoordinateSize( int nTexCoordNumber ) { return m_VertexSize_TexCoord[ nTexCoordNumber ]; } + + // Returns the base vertex memory pointer + void* BaseVertexData(); + + // Selects the nth Vertex and Index + void SelectVertex( int idx ); + void SelectIndex( int idx ); + + // Given an index, point to the associated vertex + void SelectVertexFromIndex( int idx ); + + // Advances the current vertex and index by one + void AdvanceVertex(); + template<int nFlags, int nNumTexCoords> void AdvanceVertexF(); + void AdvanceVertices( int nVerts ); + void AdvanceIndex(); + void AdvanceIndices( int nIndices ); + + int GetCurrentVertex(); + int GetCurrentIndex(); + + // Data retrieval... + const float *Position() const; + + const float *Normal() const; + + unsigned int Color() const; + + unsigned char *Specular() const; + + const float *TexCoord( int stage ) const; + + const float *TangentS() const; + const float *TangentT() const; + + const float *BoneWeight() const; + float Wrinkle() const; + + int NumBoneWeights() const; +#ifndef NEW_SKINNING + unsigned char *BoneMatrix() const; +#else + float *BoneMatrix() const; +#endif + unsigned short const *Index() const; + + // position setting + void Position3f( float x, float y, float z ); + void Position3fv( const float *v ); + + // normal setting + void Normal3f( float nx, float ny, float nz ); + void Normal3fv( const float *n ); + void NormalDelta3fv( const float *n ); + void NormalDelta3f( float nx, float ny, float nz ); + + // normal setting (templatized for code which needs to support compressed vertices) + template <VertexCompressionType_t T> void CompressedNormal3f( float nx, float ny, float nz ); + template <VertexCompressionType_t T> void CompressedNormal3fv( const float *n ); + + // color setting + void Color3f( float r, float g, float b ); + void Color3fv( const float *rgb ); + void Color4f( float r, float g, float b, float a ); + void Color4fv( const float *rgba ); + + // Faster versions of color + void Color3ub( unsigned char r, unsigned char g, unsigned char b ); + void Color3ubv( unsigned char const* rgb ); + void Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Color4ubv( unsigned char const* rgba ); + + // specular color setting + void Specular3f( float r, float g, float b ); + void Specular3fv( const float *rgb ); + void Specular4f( float r, float g, float b, float a ); + void Specular4fv( const float *rgba ); + + // Faster version of specular + void Specular3ub( unsigned char r, unsigned char g, unsigned char b ); + void Specular3ubv( unsigned char const *c ); + void Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Specular4ubv( unsigned char const *c ); + + // texture coordinate setting + void TexCoord1f( int stage, float s ); + void TexCoord2f( int stage, float s, float t ); + void TexCoord2fv( int stage, const float *st ); + void TexCoord3f( int stage, float s, float t, float u ); + void TexCoord3fv( int stage, const float *stu ); + void TexCoord4f( int stage, float s, float t, float u, float w ); + void TexCoord4fv( int stage, const float *stuv ); + + void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ); + void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ); + + // tangent space + void TangentS3f( float sx, float sy, float sz ); + void TangentS3fv( const float *s ); + + void TangentT3f( float tx, float ty, float tz ); + void TangentT3fv( const float *t ); + + // Wrinkle + void Wrinkle1f( float flWrinkle ); + + // bone weights + void BoneWeight( int idx, float weight ); + // bone weights (templatized for code which needs to support compressed vertices) + template <VertexCompressionType_t T> void CompressedBoneWeight3fv( const float * pWeights ); + + // bone matrix index + void BoneMatrix( int idx, int matrixIndex ); + + // Generic per-vertex data + void UserData( const float *pData ); + // Generic per-vertex data (templatized for code which needs to support compressed vertices) + template <VertexCompressionType_t T> void CompressedUserData( const float* pData ); + + // Used to define the indices (only used if you aren't using primitives) + void Index( unsigned short index ); + + // NOTE: Use this one to get write combining! Much faster than the other version of FastIndex + // Fast Index! No need to call advance index, and no random access allowed + void FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ); + + // Fast Index! No need to call advance index, and no random access allowed + void FastIndex( unsigned short index ); + + // Fast Vertex! No need to call advance vertex, and no random access allowed. + // WARNING - these are low level functions that are intended only for use + // in the software vertex skinner. + void FastVertex( const ModelVertexDX7_t &vertex ); + void FastVertexSSE( const ModelVertexDX7_t &vertex ); + + // store 4 dx7 vertices fast. for special sse dx7 pipeline + void Fast4VerticesSSE( + ModelVertexDX7_t const *vtx_a, + ModelVertexDX7_t const *vtx_b, + ModelVertexDX7_t const *vtx_c, + ModelVertexDX7_t const *vtx_d); + + void FastVertex( const ModelVertexDX8_t &vertex ); + void FastVertexSSE( const ModelVertexDX8_t &vertex ); + + // Add number of verts and current vert since FastVertexxx routines do not update. + void FastAdvanceNVertices(int n); + +#if defined( _X360 ) + void VertexDX8ToX360( const ModelVertexDX8_t &vertex ); +#endif + +private: + // Computes number of verts and indices + void ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, + MaterialPrimitiveType_t type, int nPrimitiveCount ); + int IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount ); + + // The mesh we're modifying + IMesh *m_pMesh; + + MaterialPrimitiveType_t m_Type; + + // Generate indices? + bool m_bGenerateIndices; + + CIndexBuilder m_IndexBuilder; + CVertexBuilder m_VertexBuilder; +}; + + +//----------------------------------------------------------------------------- +// Forward compat +//----------------------------------------------------------------------------- +inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, MaterialPrimitiveType_t type, int numPrimitives ) +{ + Assert( 0 ); + // Begin( pVertexBuffer->GetMesh(), type, numPrimitives ); +} + +inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ) +{ + Assert( 0 ); + // Begin( pVertexBuffer->GetMesh(), type, nVertexCount, nIndexCount, nFirstVertex ); +} + +inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ) +{ + Assert( 0 ); + // Begin( pVertexBuffer->GetMesh(), type, nVertexCount, nIndexCount ); +} + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +inline CMeshBuilder::CMeshBuilder() : m_pMesh(0), m_bGenerateIndices(false) +{ +} + + +//----------------------------------------------------------------------------- +// Computes the number of verts and indices based on primitive type and count +//----------------------------------------------------------------------------- +inline void CMeshBuilder::ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, + MaterialPrimitiveType_t type, int nPrimitiveCount ) +{ + switch(type) + { + case MATERIAL_POINTS: + *pMaxVertices = *pMaxIndices = nPrimitiveCount; + break; + + case MATERIAL_LINES: + *pMaxVertices = *pMaxIndices = nPrimitiveCount * 2; + break; + + case MATERIAL_LINE_STRIP: + *pMaxVertices = nPrimitiveCount + 1; + *pMaxIndices = nPrimitiveCount * 2; + break; + + case MATERIAL_LINE_LOOP: + *pMaxVertices = nPrimitiveCount; + *pMaxIndices = nPrimitiveCount * 2; + break; + + case MATERIAL_TRIANGLES: + *pMaxVertices = *pMaxIndices = nPrimitiveCount * 3; + break; + + case MATERIAL_TRIANGLE_STRIP: + *pMaxVertices = *pMaxIndices = nPrimitiveCount + 2; + break; + + case MATERIAL_QUADS: + *pMaxVertices = nPrimitiveCount * 4; + *pMaxIndices = nPrimitiveCount * 6; + break; + + case MATERIAL_INSTANCED_QUADS: + *pMaxVertices = nPrimitiveCount; + *pMaxIndices = 0; // This primtype is unindexed + break; + + case MATERIAL_POLYGON: + *pMaxVertices = nPrimitiveCount; + *pMaxIndices = (nPrimitiveCount - 2) * 3; + break; + + default: + Assert(0); + } + + // FIXME: need to get this from meshdx8.cpp, or move it to somewhere common + Assert( *pMaxVertices <= 32768 ); + Assert( *pMaxIndices <= 32768 ); +} + + +inline int CMeshBuilder::IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount ) +{ + switch( type ) + { + case MATERIAL_QUADS: + Assert( (nVertexCount & 0x3) == 0 ); + return (nVertexCount * 6) / 4; + + case MATERIAL_INSTANCED_QUADS: + // This primtype is unindexed + return 0; + + case MATERIAL_POLYGON: + Assert( nVertexCount >= 3 ); + return (nVertexCount - 2) * 3; + + case MATERIAL_LINE_STRIP: + Assert( nVertexCount >= 2 ); + return (nVertexCount - 1) * 2; + + case MATERIAL_LINE_LOOP: + Assert( nVertexCount >= 3 ); + return nVertexCount * 2; + + default: + return nVertexCount; + } +} + +//----------------------------------------------------------------------------- +// Specify the type of vertex compression that this CMeshBuilder will perform +//----------------------------------------------------------------------------- +inline void CMeshBuilder::SetCompressionType( VertexCompressionType_t vertexCompressionType ) +{ + m_VertexBuilder.SetCompressionType( vertexCompressionType ); +} + +//----------------------------------------------------------------------------- +// Begins modifying the mesh +//----------------------------------------------------------------------------- +inline void CMeshBuilder::Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int numPrimitives ) +{ + Assert( pMesh && (!m_pMesh) ); + Assert( type != MATERIAL_HETEROGENOUS ); + + m_pMesh = pMesh; + m_bGenerateIndices = true; + m_Type = type; + + int nMaxVertexCount, nMaxIndexCount; + ComputeNumVertsAndIndices( &nMaxVertexCount, &nMaxIndexCount, type, numPrimitives ); + + switch( type ) + { + case MATERIAL_INSTANCED_QUADS: + m_pMesh->SetPrimitiveType( MATERIAL_INSTANCED_QUADS ); + break; + + case MATERIAL_QUADS: + case MATERIAL_POLYGON: + m_pMesh->SetPrimitiveType( MATERIAL_TRIANGLES ); + break; + + case MATERIAL_LINE_STRIP: + case MATERIAL_LINE_LOOP: + m_pMesh->SetPrimitiveType( MATERIAL_LINES ); + break; + + default: + m_pMesh->SetPrimitiveType( type ); + } + + // Lock the mesh + m_pMesh->LockMesh( nMaxVertexCount, nMaxIndexCount, *this ); + + m_IndexBuilder.AttachBegin( pMesh, nMaxIndexCount, *this ); + m_VertexBuilder.AttachBegin( pMesh, nMaxVertexCount, *this ); + + // Point to the start of the index and vertex buffers + Reset(); +} + +inline void CMeshBuilder::Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ) +{ + Begin( pMesh, type, nVertexCount, nIndexCount ); + + *nFirstVertex = m_VertexBuilder.m_nFirstVertex * m_VertexBuilder.VertexSize(); +} + +inline void CMeshBuilder::Begin( IMesh* pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ) +{ + Assert( pMesh && (!m_pMesh) ); + + // NOTE: We can't specify the indices when we use quads, polygons, or + // linestrips; they aren't actually directly supported by + // the material system + Assert( (type != MATERIAL_QUADS) && (type != MATERIAL_INSTANCED_QUADS) && (type != MATERIAL_POLYGON) && + (type != MATERIAL_LINE_STRIP) && (type != MATERIAL_LINE_LOOP)); + + // Dx8 doesn't support indexed points... + Assert( type != MATERIAL_POINTS ); + + m_pMesh = pMesh; + m_bGenerateIndices = false; + m_Type = type; + + // Set the primitive type + m_pMesh->SetPrimitiveType( type ); + + // Lock the vertex and index buffer + m_pMesh->LockMesh( nVertexCount, nIndexCount, *this ); + + m_IndexBuilder.AttachBegin( pMesh, nIndexCount, *this ); + m_VertexBuilder.AttachBegin( pMesh, nVertexCount, *this ); + + // Point to the start of the buffers.. + Reset(); +} + + +//----------------------------------------------------------------------------- +// Use this when you're done modifying the mesh +//----------------------------------------------------------------------------- +inline void CMeshBuilder::End( bool bSpewData, bool bDraw ) +{ + if ( m_bGenerateIndices ) + { + int nIndexCount = IndicesFromVertices( m_Type, m_VertexBuilder.VertexCount() ); + m_IndexBuilder.GenerateIndices( m_Type, nIndexCount ); + } + + if ( bSpewData ) + { + m_pMesh->Spew( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); + } + +#ifdef _DEBUG + m_pMesh->ValidateData( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); +#endif + + // Unlock our buffers + m_pMesh->UnlockMesh( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); + + m_IndexBuilder.AttachEnd(); + m_VertexBuilder.AttachEnd(); + + if ( bDraw ) + { + m_pMesh->Draw(); + } + + m_pMesh = 0; + +#ifdef _DEBUG + memset( (MeshDesc_t*)this, 0, sizeof(MeshDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Locks the vertex buffer to modify existing data +//----------------------------------------------------------------------------- +inline void CMeshBuilder::BeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount ) +{ + Assert( pMesh && (!m_pMesh) ); + + if (nVertexCount < 0) + { + nVertexCount = pMesh->VertexCount(); + } + + m_pMesh = pMesh; + m_bGenerateIndices = false; + + // Locks mesh for modifying + pMesh->ModifyBeginEx( false, nFirstVertex, nVertexCount, nFirstIndex, nIndexCount, *this ); + + m_IndexBuilder.AttachBeginModify( pMesh, nFirstIndex, nIndexCount, *this ); + m_VertexBuilder.AttachBeginModify( pMesh, nFirstVertex, nVertexCount, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CMeshBuilder::EndModify( bool bSpewData ) +{ + Assert( m_pMesh ); + + if (bSpewData) + { + m_pMesh->Spew( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); + } +#ifdef _DEBUG + m_pMesh->ValidateData( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); +#endif + + // Unlocks mesh + m_pMesh->ModifyEnd( *this ); + m_pMesh = 0; + + m_IndexBuilder.AttachEndModify(); + m_VertexBuilder.AttachEndModify(); + +#ifdef _DEBUG + // Null out our pointers... + memset( (MeshDesc_t*)this, 0, sizeof(MeshDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Resets the mesh builder so it points to the start of everything again +//----------------------------------------------------------------------------- +inline void CMeshBuilder::Reset() +{ + m_IndexBuilder.Reset(); + m_VertexBuilder.Reset(); +} + + +//----------------------------------------------------------------------------- +// Selects the current Vertex and Index +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::SelectVertex( int nIndex ) +{ + m_VertexBuilder.SelectVertex( nIndex ); +} + +inline void CMeshBuilder::SelectVertexFromIndex( int idx ) +{ + // NOTE: This index is expected to be relative + int vertIdx = idx - m_nFirstVertex; + SelectVertex( vertIdx ); +} + +FORCEINLINE void CMeshBuilder::SelectIndex( int idx ) +{ + m_IndexBuilder.SelectIndex( idx ); +} + + +//----------------------------------------------------------------------------- +// Advances the current vertex and index by one +//----------------------------------------------------------------------------- +template<int nFlags, int nNumTexCoords> FORCEINLINE void CMeshBuilder::AdvanceVertexF() +{ + m_VertexBuilder.AdvanceVertexF<nFlags, nNumTexCoords>(); +} +FORCEINLINE void CMeshBuilder::AdvanceVertex() +{ + m_VertexBuilder.AdvanceVertex(); +} + +FORCEINLINE void CMeshBuilder::AdvanceVertices( int nVertexCount ) +{ + m_VertexBuilder.AdvanceVertices( nVertexCount ); +} + +FORCEINLINE void CMeshBuilder::AdvanceIndex() +{ + m_IndexBuilder.AdvanceIndex(); +} + +FORCEINLINE void CMeshBuilder::AdvanceIndices( int nIndices ) +{ + m_IndexBuilder.AdvanceIndices( nIndices ); +} + +FORCEINLINE int CMeshBuilder::GetCurrentVertex() +{ + return m_VertexBuilder.GetCurrentVertex(); +} + +FORCEINLINE int CMeshBuilder::GetCurrentIndex() +{ + return m_IndexBuilder.GetCurrentIndex(); +} + + +//----------------------------------------------------------------------------- +// A helper method since this seems to be done a whole bunch. +//----------------------------------------------------------------------------- +inline void CMeshBuilder::DrawQuad( IMesh* pMesh, const float* v1, const float* v2, + const float* v3, const float* v4, unsigned char const* pColor, bool wireframe ) +{ + if (!wireframe) + { + Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 ); + + Position3fv (v1); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + + Position3fv (v2); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + + Position3fv (v4); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + + Position3fv (v3); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + } + else + { + Begin( pMesh, MATERIAL_LINE_LOOP, 4 ); + Position3fv (v1); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + + Position3fv (v2); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + + Position3fv (v3); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + + Position3fv (v4); + Color4ubv( pColor ); + AdvanceVertexF<VTX_HAVEPOS | VTX_HAVECOLOR, 0>(); + } + + End(); + pMesh->Draw(); +} + + +//----------------------------------------------------------------------------- +// returns the number of indices and vertices +//----------------------------------------------------------------------------- +FORCEINLINE int CMeshBuilder::VertexCount() const +{ + return m_VertexBuilder.VertexCount(); +} + +FORCEINLINE int CMeshBuilder::IndexCount() const +{ + return m_IndexBuilder.IndexCount(); +} + + +//----------------------------------------------------------------------------- +// Returns the base vertex memory pointer +//----------------------------------------------------------------------------- +FORCEINLINE void* CMeshBuilder::BaseVertexData() +{ + return m_VertexBuilder.BaseVertexData(); +} + +//----------------------------------------------------------------------------- +// Data retrieval... +//----------------------------------------------------------------------------- +FORCEINLINE const float* CMeshBuilder::Position() const +{ + return m_VertexBuilder.Position(); +} + +FORCEINLINE const float* CMeshBuilder::Normal() const +{ + return m_VertexBuilder.Normal(); +} + +FORCEINLINE unsigned int CMeshBuilder::Color() const +{ + return m_VertexBuilder.Color(); +} + +FORCEINLINE unsigned char *CMeshBuilder::Specular() const +{ + return m_VertexBuilder.Specular(); +} + +FORCEINLINE const float* CMeshBuilder::TexCoord( int nStage ) const +{ + return m_VertexBuilder.TexCoord( nStage ); +} + +FORCEINLINE const float* CMeshBuilder::TangentS() const +{ + return m_VertexBuilder.TangentS(); +} + +FORCEINLINE const float* CMeshBuilder::TangentT() const +{ + return m_VertexBuilder.TangentT(); +} + +FORCEINLINE float CMeshBuilder::Wrinkle() const +{ + return m_VertexBuilder.Wrinkle(); +} + +FORCEINLINE const float* CMeshBuilder::BoneWeight() const +{ + return m_VertexBuilder.BoneWeight(); +} + +FORCEINLINE int CMeshBuilder::NumBoneWeights() const +{ + return m_VertexBuilder.NumBoneWeights(); +} + +FORCEINLINE unsigned short const* CMeshBuilder::Index() const +{ + return m_IndexBuilder.Index(); +} + + +//----------------------------------------------------------------------------- +// Index +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::Index( unsigned short idx ) +{ + m_IndexBuilder.Index( idx ); +} + + +//----------------------------------------------------------------------------- +// Fast Index! No need to call advance index +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::FastIndex( unsigned short idx ) +{ + m_IndexBuilder.FastIndex( idx ); +} + +// NOTE: Use this one to get write combining! Much faster than the other version of FastIndex +// Fast Index! No need to call advance index, and no random access allowed +FORCEINLINE void CMeshBuilder::FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ) +{ + m_IndexBuilder.FastIndex2( nIndex1, nIndex2 ); +} + +//----------------------------------------------------------------------------- +// For use with the FastVertex methods, advances the current vertex by N +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::FastAdvanceNVertices( int nVertexCount ) +{ + m_VertexBuilder.FastAdvanceNVertices( nVertexCount ); +} + + +//----------------------------------------------------------------------------- +// Fast Vertex! No need to call advance vertex, and no random access allowed +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::FastVertex( const ModelVertexDX7_t &vertex ) +{ + m_VertexBuilder.FastVertex( vertex ); +} + +FORCEINLINE void CMeshBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex ) +{ + m_VertexBuilder.FastVertexSSE( vertex ); +} + +FORCEINLINE void CMeshBuilder::Fast4VerticesSSE( + const ModelVertexDX7_t *vtx_a, const ModelVertexDX7_t *vtx_b, + const ModelVertexDX7_t *vtx_c, const ModelVertexDX7_t *vtx_d ) +{ + m_VertexBuilder.Fast4VerticesSSE( vtx_a, vtx_b, vtx_c, vtx_d ); +} + +FORCEINLINE void CMeshBuilder::FastVertex( const ModelVertexDX8_t &vertex ) +{ + m_VertexBuilder.FastVertex( vertex ); +} + +FORCEINLINE void CMeshBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex ) +{ + m_VertexBuilder.FastVertexSSE( vertex ); +} + +//----------------------------------------------------------------------------- +// Copies a vertex into the x360 format +//----------------------------------------------------------------------------- +#if defined( _X360 ) +inline void CMeshBuilder::VertexDX8ToX360( const ModelVertexDX8_t &vertex ) +{ + m_VertexBuilder.VertexDX8ToX360( vertex ); +} +#endif + +//----------------------------------------------------------------------------- +// Vertex field setting methods +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::Position3f( float x, float y, float z ) +{ + m_VertexBuilder.Position3f( x, y, z ); +} + +FORCEINLINE void CMeshBuilder::Position3fv( const float *v ) +{ + m_VertexBuilder.Position3fv( v ); +} + +FORCEINLINE void CMeshBuilder::Normal3f( float nx, float ny, float nz ) +{ + m_VertexBuilder.Normal3f( nx, ny, nz ); +} + +FORCEINLINE void CMeshBuilder::Normal3fv( const float *n ) +{ + m_VertexBuilder.Normal3fv( n ); +} + +FORCEINLINE void CMeshBuilder::NormalDelta3f( float nx, float ny, float nz ) +{ + m_VertexBuilder.NormalDelta3f( nx, ny, nz ); +} + +FORCEINLINE void CMeshBuilder::NormalDelta3fv( const float *n ) +{ + m_VertexBuilder.NormalDelta3fv( n ); +} + +FORCEINLINE void CMeshBuilder::Color3f( float r, float g, float b ) +{ + m_VertexBuilder.Color3f( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Color3fv( const float *rgb ) +{ + m_VertexBuilder.Color3fv( rgb ); +} + +FORCEINLINE void CMeshBuilder::Color4f( float r, float g, float b, float a ) +{ + m_VertexBuilder.Color4f( r, g ,b, a ); +} + +FORCEINLINE void CMeshBuilder::Color4fv( const float *rgba ) +{ + m_VertexBuilder.Color4fv( rgba ); +} + +FORCEINLINE void CMeshBuilder::Color3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + m_VertexBuilder.Color3ub( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Color3ubv( unsigned char const* rgb ) +{ + m_VertexBuilder.Color3ubv( rgb ); +} + +FORCEINLINE void CMeshBuilder::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + m_VertexBuilder.Color4ub( r, g, b, a ); +} + +FORCEINLINE void CMeshBuilder::Color4ubv( unsigned char const* rgba ) +{ + m_VertexBuilder.Color4ubv( rgba ); +} + +FORCEINLINE void CMeshBuilder::Specular3f( float r, float g, float b ) +{ + m_VertexBuilder.Specular3f( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Specular3fv( const float *rgb ) +{ + m_VertexBuilder.Specular3fv( rgb ); +} + +FORCEINLINE void CMeshBuilder::Specular4f( float r, float g, float b, float a ) +{ + m_VertexBuilder.Specular4f( r, g, b, a ); +} + +FORCEINLINE void CMeshBuilder::Specular4fv( const float *rgba ) +{ + m_VertexBuilder.Specular4fv( rgba ); +} + +FORCEINLINE void CMeshBuilder::Specular3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + m_VertexBuilder.Specular3ub( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Specular3ubv( unsigned char const *c ) +{ + m_VertexBuilder.Specular3ubv( c ); +} + +FORCEINLINE void CMeshBuilder::Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + m_VertexBuilder.Specular4ub( r, g, b, a ); +} + +FORCEINLINE void CMeshBuilder::Specular4ubv( unsigned char const *c ) +{ + m_VertexBuilder.Specular4ubv( c ); +} + +FORCEINLINE void CMeshBuilder::TexCoord1f( int nStage, float s ) +{ + m_VertexBuilder.TexCoord1f( nStage, s ); +} + +FORCEINLINE void CMeshBuilder::TexCoord2f( int nStage, float s, float t ) +{ + m_VertexBuilder.TexCoord2f( nStage, s, t ); +} + +FORCEINLINE void CMeshBuilder::TexCoord2fv( int nStage, const float *st ) +{ + m_VertexBuilder.TexCoord2fv( nStage, st ); +} + +FORCEINLINE void CMeshBuilder::TexCoord3f( int nStage, float s, float t, float u ) +{ + m_VertexBuilder.TexCoord3f( nStage, s, t, u ); +} + +FORCEINLINE void CMeshBuilder::TexCoord3fv( int nStage, const float *stu ) +{ + m_VertexBuilder.TexCoord3fv( nStage, stu ); +} + +FORCEINLINE void CMeshBuilder::TexCoord4f( int nStage, float s, float t, float u, float v ) +{ + m_VertexBuilder.TexCoord4f( nStage, s, t, u, v ); +} + +FORCEINLINE void CMeshBuilder::TexCoord4fv( int nStage, const float *stuv ) +{ + m_VertexBuilder.TexCoord4fv( nStage, stuv ); +} + +FORCEINLINE void CMeshBuilder::TexCoordSubRect2f( int nStage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ) +{ + m_VertexBuilder.TexCoordSubRect2f( nStage, s, t, offsetS, offsetT, scaleS, scaleT ); +} + +FORCEINLINE void CMeshBuilder::TexCoordSubRect2fv( int nStage, const float *st, const float *offset, const float *scale ) +{ + m_VertexBuilder.TexCoordSubRect2fv( nStage, st, offset, scale ); +} + +FORCEINLINE void CMeshBuilder::TangentS3f( float sx, float sy, float sz ) +{ + m_VertexBuilder.TangentS3f( sx, sy, sz ); +} + +FORCEINLINE void CMeshBuilder::TangentS3fv( const float* s ) +{ + m_VertexBuilder.TangentS3fv( s ); +} + +FORCEINLINE void CMeshBuilder::TangentT3f( float tx, float ty, float tz ) +{ + m_VertexBuilder.TangentT3f( tx, ty, tz ); +} + +FORCEINLINE void CMeshBuilder::TangentT3fv( const float* t ) +{ + m_VertexBuilder.TangentT3fv( t ); +} + +FORCEINLINE void CMeshBuilder::Wrinkle1f( float flWrinkle ) +{ + m_VertexBuilder.Wrinkle1f( flWrinkle ); +} + +FORCEINLINE void CMeshBuilder::BoneWeight( int nIndex, float flWeight ) +{ + m_VertexBuilder.BoneWeight( nIndex, flWeight ); +} + +template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedBoneWeight3fv( const float * pWeights ) +{ + m_VertexBuilder.CompressedBoneWeight3fv<T>( pWeights ); +} + +FORCEINLINE void CMeshBuilder::BoneMatrix( int nIndex, int nMatrixIdx ) +{ + m_VertexBuilder.BoneMatrix( nIndex, nMatrixIdx ); +} + +FORCEINLINE void CMeshBuilder::UserData( const float* pData ) +{ + m_VertexBuilder.UserData( pData ); +} + +template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedUserData( const float* pData ) +{ + m_VertexBuilder.CompressedUserData<T>( pData ); +} + +//----------------------------------------------------------------------------- +// Templatized vertex field setting methods which support compression +//----------------------------------------------------------------------------- + +template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedNormal3f( float nx, float ny, float nz ) +{ + m_VertexBuilder.CompressedNormal3f<T>( nx, ny, nz ); +} + +template <VertexCompressionType_t T> FORCEINLINE void CMeshBuilder::CompressedNormal3fv( const float *n ) +{ + m_VertexBuilder.CompressedNormal3fv<T>( n ); +} + +#endif // IMESH_H diff --git a/mp/src/public/materialsystem/imorph.h b/mp/src/public/materialsystem/imorph.h index 45af7ee7..c3bff78b 100644 --- a/mp/src/public/materialsystem/imorph.h +++ b/mp/src/public/materialsystem/imorph.h @@ -1,251 +1,251 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// The copyright to the contents herein is the property of Valve, L.L.C.
-// The contents may be used and/or copied only with the written permission of
-// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
-// the agreement/contract under which the contents have been supplied.
-//
-// $Header: $
-// $NoKeywords: $
-//
-// Interface used to construct morph buffers
-//=============================================================================
-
-#ifndef IMORPH_H
-#define IMORPH_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "mathlib/vector.h"
-#include <float.h>
-#include "tier0/dbg.h"
-#include "materialsystem/imaterial.h"
-
-
-//-----------------------------------------------------------------------------
-// Single morph data
-//-----------------------------------------------------------------------------
-struct MorphVertexInfo_t
-{
- int m_nVertexId; // What vertex is this going to affect?
- int m_nMorphTargetId; // What morph did it come from?
- Vector m_PositionDelta; // Positional morph delta
- Vector m_NormalDelta; // Normal morph delta
- float m_flWrinkleDelta; // Wrinkle morph delta
- float m_flSpeed;
- float m_flSide;
-};
-
-
-//-----------------------------------------------------------------------------
-// Morph weight data
-//-----------------------------------------------------------------------------
-enum MorphWeightType_t
-{
- MORPH_WEIGHT = 0,
- MORPH_WEIGHT_LAGGED,
- MORPH_WEIGHT_STEREO,
- MORPH_WEIGHT_STEREO_LAGGED,
-
- MORPH_WEIGHT_COUNT,
-};
-
-struct MorphWeight_t
-{
- float m_pWeight[MORPH_WEIGHT_COUNT];
-};
-
-
-//-----------------------------------------------------------------------------
-// Interface to the morph
-//-----------------------------------------------------------------------------
-abstract_class IMorph
-{
-public:
- // Locks the morph, destroys any existing contents
- virtual void Lock( float flFloatToFixedScale = 1.0f ) = 0;
-
- // Adds a morph
- virtual void AddMorph( const MorphVertexInfo_t &info ) = 0;
-
- // Unlocks the morph
- virtual void Unlock( ) = 0;
-};
-
-
-//-----------------------------------------------------------------------------
-// Morph builders
-//-----------------------------------------------------------------------------
-class CMorphBuilder
-{
-public:
- CMorphBuilder();
- ~CMorphBuilder();
-
- // Start building the morph
- void Begin( IMorph *pMorph, float flFloatToFixedScale = 1.0f );
-
- // End building the morph
- void End();
-
- void PositionDelta3fv( const float *pDelta );
- void PositionDelta3f( float dx, float dy, float dz );
- void PositionDelta3( const Vector &vec );
-
- void NormalDelta3fv( const float *pDelta );
- void NormalDelta3f( float dx, float dy, float dz );
- void NormalDelta3( const Vector &vec );
-
- void WrinkleDelta1f( float flWrinkle );
-
- // Both are 0-1 values indicating which morph target to use (for stereo morph targets)
- // and how much to blend between using lagged weights vs actual weights
- // Speed: 0 - use lagged, 1 - use actual
- void Speed1f( float flSpeed );
- void Side1f( float flSide );
-
- void AdvanceMorph( int nSourceVertex, int nMorphTargetId );
-
-private:
- MorphVertexInfo_t m_Info;
- IMorph *m_pMorph;
-};
-
-
-//-----------------------------------------------------------------------------
-// Constructor, destructor
-//-----------------------------------------------------------------------------
-inline CMorphBuilder::CMorphBuilder()
-{
- m_pMorph = NULL;
-}
-
-inline CMorphBuilder::~CMorphBuilder()
-{
- // You forgot to call End()!
- Assert( !m_pMorph );
-}
-
-
-//-----------------------------------------------------------------------------
-// Start building the morph
-//-----------------------------------------------------------------------------
-inline void CMorphBuilder::Begin( IMorph *pMorph, float flFloatToFixedScale )
-{
- Assert( pMorph && !m_pMorph );
- m_pMorph = pMorph;
- m_pMorph->Lock( flFloatToFixedScale );
-
-#ifdef _DEBUG
- m_Info.m_PositionDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN );
- m_Info.m_NormalDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN );
- m_Info.m_flWrinkleDelta = VEC_T_NAN;
- m_Info.m_flSpeed = VEC_T_NAN;
- m_Info.m_flSide = VEC_T_NAN;
-#endif
-}
-
-// End building the morph
-inline void CMorphBuilder::End()
-{
- Assert( m_pMorph );
- m_pMorph->Unlock();
- m_pMorph = NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// Set position delta
-//-----------------------------------------------------------------------------
-inline void CMorphBuilder::PositionDelta3fv( const float *pDelta )
-{
- Assert( m_pMorph );
- m_Info.m_PositionDelta.Init( pDelta[0], pDelta[1], pDelta[2] );
-}
-
-inline void CMorphBuilder::PositionDelta3f( float dx, float dy, float dz )
-{
- Assert( m_pMorph );
- m_Info.m_PositionDelta.Init( dx, dy, dz );
-}
-
-inline void CMorphBuilder::PositionDelta3( const Vector &vec )
-{
- Assert( m_pMorph );
- m_Info.m_PositionDelta = vec;
-}
-
-
-//-----------------------------------------------------------------------------
-// Set normal delta
-//-----------------------------------------------------------------------------
-inline void CMorphBuilder::NormalDelta3fv( const float *pDelta )
-{
- Assert( m_pMorph );
- m_Info.m_NormalDelta.Init( pDelta[0], pDelta[1], pDelta[2] );
-}
-
-inline void CMorphBuilder::NormalDelta3f( float dx, float dy, float dz )
-{
- Assert( m_pMorph );
- m_Info.m_NormalDelta.Init( dx, dy, dz );
-}
-
-inline void CMorphBuilder::NormalDelta3( const Vector &vec )
-{
- Assert( m_pMorph );
- m_Info.m_NormalDelta = vec;
-}
-
-
-//-----------------------------------------------------------------------------
-// Set wrinkle delta
-//-----------------------------------------------------------------------------
-inline void CMorphBuilder::WrinkleDelta1f( float flWrinkle )
-{
- Assert( m_pMorph );
- m_Info.m_flWrinkleDelta = flWrinkle;
-}
-
-
-//-----------------------------------------------------------------------------
-// Set speed,side data
-//-----------------------------------------------------------------------------
-inline void CMorphBuilder::Speed1f( float flSpeed )
-{
- Assert( m_pMorph );
- m_Info.m_flSpeed = flSpeed;
-}
-
-inline void CMorphBuilder::Side1f( float flSide )
-{
- Assert( m_pMorph );
- m_Info.m_flSide = flSide;
-}
-
-
-//-----------------------------------------------------------------------------
-// Advance morph
-//-----------------------------------------------------------------------------
-inline void CMorphBuilder::AdvanceMorph( int nSourceVertex, int nMorphTargetId )
-{
- Assert( m_pMorph );
-
- m_Info.m_nVertexId = nSourceVertex;
- m_Info.m_nMorphTargetId = nMorphTargetId;
-
- m_pMorph->AddMorph( m_Info );
-
-#ifdef _DEBUG
- m_Info.m_PositionDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN );
- m_Info.m_NormalDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN );
- m_Info.m_flWrinkleDelta = VEC_T_NAN;
- m_Info.m_flSpeed = VEC_T_NAN;
- m_Info.m_flSide = VEC_T_NAN;
-#endif
-}
-
-
-#endif // IMORPH_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +// Interface used to construct morph buffers +//============================================================================= + +#ifndef IMORPH_H +#define IMORPH_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" +#include <float.h> +#include "tier0/dbg.h" +#include "materialsystem/imaterial.h" + + +//----------------------------------------------------------------------------- +// Single morph data +//----------------------------------------------------------------------------- +struct MorphVertexInfo_t +{ + int m_nVertexId; // What vertex is this going to affect? + int m_nMorphTargetId; // What morph did it come from? + Vector m_PositionDelta; // Positional morph delta + Vector m_NormalDelta; // Normal morph delta + float m_flWrinkleDelta; // Wrinkle morph delta + float m_flSpeed; + float m_flSide; +}; + + +//----------------------------------------------------------------------------- +// Morph weight data +//----------------------------------------------------------------------------- +enum MorphWeightType_t +{ + MORPH_WEIGHT = 0, + MORPH_WEIGHT_LAGGED, + MORPH_WEIGHT_STEREO, + MORPH_WEIGHT_STEREO_LAGGED, + + MORPH_WEIGHT_COUNT, +}; + +struct MorphWeight_t +{ + float m_pWeight[MORPH_WEIGHT_COUNT]; +}; + + +//----------------------------------------------------------------------------- +// Interface to the morph +//----------------------------------------------------------------------------- +abstract_class IMorph +{ +public: + // Locks the morph, destroys any existing contents + virtual void Lock( float flFloatToFixedScale = 1.0f ) = 0; + + // Adds a morph + virtual void AddMorph( const MorphVertexInfo_t &info ) = 0; + + // Unlocks the morph + virtual void Unlock( ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Morph builders +//----------------------------------------------------------------------------- +class CMorphBuilder +{ +public: + CMorphBuilder(); + ~CMorphBuilder(); + + // Start building the morph + void Begin( IMorph *pMorph, float flFloatToFixedScale = 1.0f ); + + // End building the morph + void End(); + + void PositionDelta3fv( const float *pDelta ); + void PositionDelta3f( float dx, float dy, float dz ); + void PositionDelta3( const Vector &vec ); + + void NormalDelta3fv( const float *pDelta ); + void NormalDelta3f( float dx, float dy, float dz ); + void NormalDelta3( const Vector &vec ); + + void WrinkleDelta1f( float flWrinkle ); + + // Both are 0-1 values indicating which morph target to use (for stereo morph targets) + // and how much to blend between using lagged weights vs actual weights + // Speed: 0 - use lagged, 1 - use actual + void Speed1f( float flSpeed ); + void Side1f( float flSide ); + + void AdvanceMorph( int nSourceVertex, int nMorphTargetId ); + +private: + MorphVertexInfo_t m_Info; + IMorph *m_pMorph; +}; + + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +inline CMorphBuilder::CMorphBuilder() +{ + m_pMorph = NULL; +} + +inline CMorphBuilder::~CMorphBuilder() +{ + // You forgot to call End()! + Assert( !m_pMorph ); +} + + +//----------------------------------------------------------------------------- +// Start building the morph +//----------------------------------------------------------------------------- +inline void CMorphBuilder::Begin( IMorph *pMorph, float flFloatToFixedScale ) +{ + Assert( pMorph && !m_pMorph ); + m_pMorph = pMorph; + m_pMorph->Lock( flFloatToFixedScale ); + +#ifdef _DEBUG + m_Info.m_PositionDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_NormalDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_flWrinkleDelta = VEC_T_NAN; + m_Info.m_flSpeed = VEC_T_NAN; + m_Info.m_flSide = VEC_T_NAN; +#endif +} + +// End building the morph +inline void CMorphBuilder::End() +{ + Assert( m_pMorph ); + m_pMorph->Unlock(); + m_pMorph = NULL; +} + + +//----------------------------------------------------------------------------- +// Set position delta +//----------------------------------------------------------------------------- +inline void CMorphBuilder::PositionDelta3fv( const float *pDelta ) +{ + Assert( m_pMorph ); + m_Info.m_PositionDelta.Init( pDelta[0], pDelta[1], pDelta[2] ); +} + +inline void CMorphBuilder::PositionDelta3f( float dx, float dy, float dz ) +{ + Assert( m_pMorph ); + m_Info.m_PositionDelta.Init( dx, dy, dz ); +} + +inline void CMorphBuilder::PositionDelta3( const Vector &vec ) +{ + Assert( m_pMorph ); + m_Info.m_PositionDelta = vec; +} + + +//----------------------------------------------------------------------------- +// Set normal delta +//----------------------------------------------------------------------------- +inline void CMorphBuilder::NormalDelta3fv( const float *pDelta ) +{ + Assert( m_pMorph ); + m_Info.m_NormalDelta.Init( pDelta[0], pDelta[1], pDelta[2] ); +} + +inline void CMorphBuilder::NormalDelta3f( float dx, float dy, float dz ) +{ + Assert( m_pMorph ); + m_Info.m_NormalDelta.Init( dx, dy, dz ); +} + +inline void CMorphBuilder::NormalDelta3( const Vector &vec ) +{ + Assert( m_pMorph ); + m_Info.m_NormalDelta = vec; +} + + +//----------------------------------------------------------------------------- +// Set wrinkle delta +//----------------------------------------------------------------------------- +inline void CMorphBuilder::WrinkleDelta1f( float flWrinkle ) +{ + Assert( m_pMorph ); + m_Info.m_flWrinkleDelta = flWrinkle; +} + + +//----------------------------------------------------------------------------- +// Set speed,side data +//----------------------------------------------------------------------------- +inline void CMorphBuilder::Speed1f( float flSpeed ) +{ + Assert( m_pMorph ); + m_Info.m_flSpeed = flSpeed; +} + +inline void CMorphBuilder::Side1f( float flSide ) +{ + Assert( m_pMorph ); + m_Info.m_flSide = flSide; +} + + +//----------------------------------------------------------------------------- +// Advance morph +//----------------------------------------------------------------------------- +inline void CMorphBuilder::AdvanceMorph( int nSourceVertex, int nMorphTargetId ) +{ + Assert( m_pMorph ); + + m_Info.m_nVertexId = nSourceVertex; + m_Info.m_nMorphTargetId = nMorphTargetId; + + m_pMorph->AddMorph( m_Info ); + +#ifdef _DEBUG + m_Info.m_PositionDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_NormalDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_flWrinkleDelta = VEC_T_NAN; + m_Info.m_flSpeed = VEC_T_NAN; + m_Info.m_flSide = VEC_T_NAN; +#endif +} + + +#endif // IMORPH_H diff --git a/mp/src/public/materialsystem/ishaderapi.h b/mp/src/public/materialsystem/ishaderapi.h index 5db40666..e16ad8c7 100644 --- a/mp/src/public/materialsystem/ishaderapi.h +++ b/mp/src/public/materialsystem/ishaderapi.h @@ -1,43 +1,43 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: NOTE: This file is for backward compat!
-// We'll get rid of it soon. Most of the contents of this file were moved
-// into shaderpi/ishadershadow.h, shaderapi/ishaderdynamic.h, or
-// shaderapi/shareddefs.h
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-
-#ifndef ISHADERAPI_MS_H
-#define ISHADERAPI_MS_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <shaderapi/shareddefs.h>
-#include <shaderapi/ishadershadow.h>
-#include <shaderapi/ishaderdynamic.h>
-
-
-//-----------------------------------------------------------------------------
-// forward declarations
-//-----------------------------------------------------------------------------
-class IMaterialVar;
-
-
-//-----------------------------------------------------------------------------
-// Methods that can be called from the SHADER_INIT blocks of shaders
-//-----------------------------------------------------------------------------
-abstract_class IShaderInit
-{
-public:
- // Loads up a texture
- virtual void LoadTexture( IMaterialVar *pTextureVar, const char *pTextureGroupName, int nAdditionalCreationFlags = 0 ) = 0;
- virtual void LoadBumpMap( IMaterialVar *pTextureVar, const char *pTextureGroupName ) = 0;
- virtual void LoadCubeMap( IMaterialVar **ppParams, IMaterialVar *pTextureVar, int nAdditionalCreationFlags = 0 ) = 0;
-};
-
-
-#endif // ISHADERAPI_MS_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: NOTE: This file is for backward compat! +// We'll get rid of it soon. Most of the contents of this file were moved +// into shaderpi/ishadershadow.h, shaderapi/ishaderdynamic.h, or +// shaderapi/shareddefs.h +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef ISHADERAPI_MS_H +#define ISHADERAPI_MS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include <shaderapi/shareddefs.h> +#include <shaderapi/ishadershadow.h> +#include <shaderapi/ishaderdynamic.h> + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterialVar; + + +//----------------------------------------------------------------------------- +// Methods that can be called from the SHADER_INIT blocks of shaders +//----------------------------------------------------------------------------- +abstract_class IShaderInit +{ +public: + // Loads up a texture + virtual void LoadTexture( IMaterialVar *pTextureVar, const char *pTextureGroupName, int nAdditionalCreationFlags = 0 ) = 0; + virtual void LoadBumpMap( IMaterialVar *pTextureVar, const char *pTextureGroupName ) = 0; + virtual void LoadCubeMap( IMaterialVar **ppParams, IMaterialVar *pTextureVar, int nAdditionalCreationFlags = 0 ) = 0; +}; + + +#endif // ISHADERAPI_MS_H diff --git a/mp/src/public/materialsystem/itexture.h b/mp/src/public/materialsystem/itexture.h index 35da645b..a5aa20fd 100644 --- a/mp/src/public/materialsystem/itexture.h +++ b/mp/src/public/materialsystem/itexture.h @@ -1,132 +1,132 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-
-#ifndef ITEXTURE_H
-#define ITEXTURE_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-#include "bitmap/imageformat.h" // ImageFormat defn.
-
-class IVTFTexture;
-class ITexture;
-struct Rect_t;
-
-//-----------------------------------------------------------------------------
-// This will get called on procedural textures to re-fill the textures
-// with the appropriate bit pattern. Calling Download() will also
-// cause this interface to be called. It will also be called upon
-// mode switch, or on other occasions where the bits are discarded.
-//-----------------------------------------------------------------------------
-abstract_class ITextureRegenerator
-{
-public:
- // This will be called when the texture bits need to be regenerated.
- // Use the VTFTexture interface, which has been set up with the
- // appropriate texture size + format
- // The rect specifies which part of the texture needs to be updated
- // You can choose to update all of the bits if you prefer
- virtual void RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pRect ) = 0;
-
- // This will be called when the regenerator needs to be deleted
- // which will happen when the texture is destroyed
- virtual void Release() = 0;
-};
-
-abstract_class ITexture
-{
-public:
- // Various texture polling methods
- virtual const char *GetName( void ) const = 0;
- virtual int GetMappingWidth() const = 0;
- virtual int GetMappingHeight() const = 0;
- virtual int GetActualWidth() const = 0;
- virtual int GetActualHeight() const = 0;
- virtual int GetNumAnimationFrames() const = 0;
- virtual bool IsTranslucent() const = 0;
- virtual bool IsMipmapped() const = 0;
-
- virtual void GetLowResColorSample( float s, float t, float *color ) const = 0;
-
- // Gets texture resource data of the specified type.
- // Params:
- // eDataType type of resource to retrieve.
- // pnumBytes on return is the number of bytes available in the read-only data buffer or is undefined
- // Returns:
- // pointer to the resource data, or NULL
- virtual void *GetResourceData( uint32 eDataType, size_t *pNumBytes ) const = 0;
-
- // Methods associated with reference count
- virtual void IncrementReferenceCount( void ) = 0;
- virtual void DecrementReferenceCount( void ) = 0;
-
- inline void AddRef() { IncrementReferenceCount(); }
- inline void Release() { DecrementReferenceCount(); }
-
- // Used to modify the texture bits (procedural textures only)
- virtual void SetTextureRegenerator( ITextureRegenerator *pTextureRegen ) = 0;
-
- // Reconstruct the texture bits in HW memory
-
- // If rect is not specified, reconstruct all bits, otherwise just
- // reconstruct a subrect.
- virtual void Download( Rect_t *pRect = 0, int nAdditionalCreationFlags = 0 ) = 0;
-
- // Uses for stats. . .get the approximate size of the texture in it's current format.
- virtual int GetApproximateVidMemBytes( void ) const = 0;
-
- // Returns true if the texture data couldn't be loaded.
- virtual bool IsError() const = 0;
-
- // NOTE: Stuff after this is added after shipping HL2.
-
- // For volume textures
- virtual bool IsVolumeTexture() const = 0;
- virtual int GetMappingDepth() const = 0;
- virtual int GetActualDepth() const = 0;
-
- virtual ImageFormat GetImageFormat() const = 0;
- virtual NormalDecodeMode_t GetNormalDecodeMode() const = 0;
-
- // Various information about the texture
- virtual bool IsRenderTarget() const = 0;
- virtual bool IsCubeMap() const = 0;
- virtual bool IsNormalMap() const = 0;
- virtual bool IsProcedural() const = 0;
-
- virtual void DeleteIfUnreferenced() = 0;
-
-#if defined( _X360 )
- virtual bool ClearTexture( int r, int g, int b, int a ) = 0;
- virtual bool CreateRenderTargetSurface( int width, int height, ImageFormat format, bool bSameAsTexture ) = 0;
-#endif
-
- // swap everything except the name with another texture
- virtual void SwapContents( ITexture *pOther ) = 0;
-
- // Retrieve the vtf flags mask
- virtual unsigned int GetFlags( void ) const = 0;
-
- // Force LOD override (automatically downloads the texture)
- virtual void ForceLODOverride( int iNumLodsOverrideUpOrDown ) = 0;
-
- // Save texture to a file.
- virtual bool SaveToFile( const char *fileName ) = 0;
-};
-
-
-inline bool IsErrorTexture( ITexture *pTex )
-{
- return !pTex || pTex->IsError();
-}
-
-
-#endif // ITEXTURE_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef ITEXTURE_H +#define ITEXTURE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "bitmap/imageformat.h" // ImageFormat defn. + +class IVTFTexture; +class ITexture; +struct Rect_t; + +//----------------------------------------------------------------------------- +// This will get called on procedural textures to re-fill the textures +// with the appropriate bit pattern. Calling Download() will also +// cause this interface to be called. It will also be called upon +// mode switch, or on other occasions where the bits are discarded. +//----------------------------------------------------------------------------- +abstract_class ITextureRegenerator +{ +public: + // This will be called when the texture bits need to be regenerated. + // Use the VTFTexture interface, which has been set up with the + // appropriate texture size + format + // The rect specifies which part of the texture needs to be updated + // You can choose to update all of the bits if you prefer + virtual void RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pRect ) = 0; + + // This will be called when the regenerator needs to be deleted + // which will happen when the texture is destroyed + virtual void Release() = 0; +}; + +abstract_class ITexture +{ +public: + // Various texture polling methods + virtual const char *GetName( void ) const = 0; + virtual int GetMappingWidth() const = 0; + virtual int GetMappingHeight() const = 0; + virtual int GetActualWidth() const = 0; + virtual int GetActualHeight() const = 0; + virtual int GetNumAnimationFrames() const = 0; + virtual bool IsTranslucent() const = 0; + virtual bool IsMipmapped() const = 0; + + virtual void GetLowResColorSample( float s, float t, float *color ) const = 0; + + // Gets texture resource data of the specified type. + // Params: + // eDataType type of resource to retrieve. + // pnumBytes on return is the number of bytes available in the read-only data buffer or is undefined + // Returns: + // pointer to the resource data, or NULL + virtual void *GetResourceData( uint32 eDataType, size_t *pNumBytes ) const = 0; + + // Methods associated with reference count + virtual void IncrementReferenceCount( void ) = 0; + virtual void DecrementReferenceCount( void ) = 0; + + inline void AddRef() { IncrementReferenceCount(); } + inline void Release() { DecrementReferenceCount(); } + + // Used to modify the texture bits (procedural textures only) + virtual void SetTextureRegenerator( ITextureRegenerator *pTextureRegen ) = 0; + + // Reconstruct the texture bits in HW memory + + // If rect is not specified, reconstruct all bits, otherwise just + // reconstruct a subrect. + virtual void Download( Rect_t *pRect = 0, int nAdditionalCreationFlags = 0 ) = 0; + + // Uses for stats. . .get the approximate size of the texture in it's current format. + virtual int GetApproximateVidMemBytes( void ) const = 0; + + // Returns true if the texture data couldn't be loaded. + virtual bool IsError() const = 0; + + // NOTE: Stuff after this is added after shipping HL2. + + // For volume textures + virtual bool IsVolumeTexture() const = 0; + virtual int GetMappingDepth() const = 0; + virtual int GetActualDepth() const = 0; + + virtual ImageFormat GetImageFormat() const = 0; + virtual NormalDecodeMode_t GetNormalDecodeMode() const = 0; + + // Various information about the texture + virtual bool IsRenderTarget() const = 0; + virtual bool IsCubeMap() const = 0; + virtual bool IsNormalMap() const = 0; + virtual bool IsProcedural() const = 0; + + virtual void DeleteIfUnreferenced() = 0; + +#if defined( _X360 ) + virtual bool ClearTexture( int r, int g, int b, int a ) = 0; + virtual bool CreateRenderTargetSurface( int width, int height, ImageFormat format, bool bSameAsTexture ) = 0; +#endif + + // swap everything except the name with another texture + virtual void SwapContents( ITexture *pOther ) = 0; + + // Retrieve the vtf flags mask + virtual unsigned int GetFlags( void ) const = 0; + + // Force LOD override (automatically downloads the texture) + virtual void ForceLODOverride( int iNumLodsOverrideUpOrDown ) = 0; + + // Save texture to a file. + virtual bool SaveToFile( const char *fileName ) = 0; +}; + + +inline bool IsErrorTexture( ITexture *pTex ) +{ + return !pTex || pTex->IsError(); +} + + +#endif // ITEXTURE_H diff --git a/mp/src/public/materialsystem/ivballoctracker.h b/mp/src/public/materialsystem/ivballoctracker.h index dfd723c9..7d07e25d 100644 --- a/mp/src/public/materialsystem/ivballoctracker.h +++ b/mp/src/public/materialsystem/ivballoctracker.h @@ -1,35 +1,35 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: tracks VB allocations (and compressed/uncompressed vertex memory usage)
-//
-//===========================================================================//
-
-#ifndef IVBALLOCTRACKER_H
-#define IVBALLOCTRACKER_H
-
-#include "materialsystem/imaterialsystem.h"
-
-// By default, only enable this alloc tracking for a debug shaderapidx*.dll
-// (it uses about 0.25MB to track ~7000 allocations)
-#if defined(_DEBUG)
-#define ENABLE_VB_ALLOC_TRACKER 1
-#else
-#define ENABLE_VB_ALLOC_TRACKER 0
-#endif
-
-// This interface is actually exported by the shader API DLL.
-#define VB_ALLOC_TRACKER_INTERFACE_VERSION "VBAllocTracker001"
-
-// Interface to the VB mem alloc tracker
-abstract_class IVBAllocTracker
-{
-public:
- // This should be called wherever VertexBuffers are allocated
- virtual void CountVB( void * buffer, bool isDynamic, int bufferSize, int vertexSize, VertexFormat_t fmt ) = 0;
- // This should be called wherever VertexBuffers are freed
- virtual void UnCountVB( void * buffer ) = 0;
- // Track mesh allocations (set this before an allocation, clear it after)
- virtual bool TrackMeshAllocations( const char * allocatorName ) = 0;
-};
-
-#endif // IVBALLOCTRACKER_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: tracks VB allocations (and compressed/uncompressed vertex memory usage) +// +//===========================================================================// + +#ifndef IVBALLOCTRACKER_H +#define IVBALLOCTRACKER_H + +#include "materialsystem/imaterialsystem.h" + +// By default, only enable this alloc tracking for a debug shaderapidx*.dll +// (it uses about 0.25MB to track ~7000 allocations) +#if defined(_DEBUG) +#define ENABLE_VB_ALLOC_TRACKER 1 +#else +#define ENABLE_VB_ALLOC_TRACKER 0 +#endif + +// This interface is actually exported by the shader API DLL. +#define VB_ALLOC_TRACKER_INTERFACE_VERSION "VBAllocTracker001" + +// Interface to the VB mem alloc tracker +abstract_class IVBAllocTracker +{ +public: + // This should be called wherever VertexBuffers are allocated + virtual void CountVB( void * buffer, bool isDynamic, int bufferSize, int vertexSize, VertexFormat_t fmt ) = 0; + // This should be called wherever VertexBuffers are freed + virtual void UnCountVB( void * buffer ) = 0; + // Track mesh allocations (set this before an allocation, clear it after) + virtual bool TrackMeshAllocations( const char * allocatorName ) = 0; +}; + +#endif // IVBALLOCTRACKER_H diff --git a/mp/src/public/materialsystem/materialsystem_config.h b/mp/src/public/materialsystem/materialsystem_config.h index 1a8d1d1d..b0fe3a27 100644 --- a/mp/src/public/materialsystem/materialsystem_config.h +++ b/mp/src/public/materialsystem/materialsystem_config.h @@ -1,222 +1,222 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//===========================================================================//
-
-#ifndef MATERIALSYSTEM_CONFIG_H
-#define MATERIALSYSTEM_CONFIG_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "materialsystem/imaterialsystem.h"
-
-#define MATERIALSYSTEM_CONFIG_VERSION "VMaterialSystemConfig002"
-
-enum MaterialSystem_Config_Flags_t
-{
- MATSYS_VIDCFG_FLAGS_WINDOWED = ( 1 << 0 ),
- MATSYS_VIDCFG_FLAGS_RESIZING = ( 1 << 1 ),
- MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC = ( 1 << 3 ),
- MATSYS_VIDCFG_FLAGS_STENCIL = ( 1 << 4 ),
- MATSYS_VIDCFG_FLAGS_FORCE_TRILINEAR = ( 1 << 5 ),
- MATSYS_VIDCFG_FLAGS_FORCE_HWSYNC = ( 1 << 6 ),
- MATSYS_VIDCFG_FLAGS_DISABLE_SPECULAR = ( 1 << 7 ),
- MATSYS_VIDCFG_FLAGS_DISABLE_BUMPMAP = ( 1 << 8 ),
- MATSYS_VIDCFG_FLAGS_ENABLE_PARALLAX_MAPPING = ( 1 << 9 ),
- MATSYS_VIDCFG_FLAGS_USE_Z_PREFILL = ( 1 << 10 ),
- MATSYS_VIDCFG_FLAGS_REDUCE_FILLRATE = ( 1 << 11 ),
- MATSYS_VIDCFG_FLAGS_ENABLE_HDR = ( 1 << 12 ),
- MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE = ( 1 << 13 ),
- MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION = ( 1 << 14 ),
- MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS = ( 1 << 15 ),
- MATSYS_VIDCFG_FLAGS_DISABLE_PHONG = ( 1 << 16 ),
-};
-
-struct MaterialSystemHardwareIdentifier_t
-{
- char *m_pCardName;
- unsigned int m_nVendorID;
- unsigned int m_nDeviceID;
-};
-
-struct MaterialSystem_Config_t
-{
- bool Windowed() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_WINDOWED ) != 0; }
- bool Resizing() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_RESIZING ) != 0; }
-#ifdef CSS_PERF_TEST
- bool WaitForVSync() const { return false; }//( m_Flags & MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC ) == 0; }
-#else
- bool WaitForVSync() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC ) == 0; }
-#endif
- bool Stencil() const { return (m_Flags & MATSYS_VIDCFG_FLAGS_STENCIL ) != 0; }
- bool ForceTrilinear() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_FORCE_TRILINEAR ) != 0; }
- bool ForceHWSync() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_FORCE_HWSYNC ) != 0; }
- bool UseSpecular() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_DISABLE_SPECULAR ) == 0; }
- bool UseBumpmapping() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_DISABLE_BUMPMAP ) == 0; }
- bool UseParallaxMapping() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_ENABLE_PARALLAX_MAPPING ) != 0; }
- bool UseZPrefill() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_USE_Z_PREFILL ) != 0; }
- bool ReduceFillrate() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_REDUCE_FILLRATE ) != 0; }
- bool HDREnabled() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_ENABLE_HDR ) != 0; }
- bool LimitWindowedSize() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE ) != 0; }
- bool ScaleToOutputResolution() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION ) != 0; }
- bool UsingMultipleWindows() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS ) != 0; }
- bool UsePhong() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_DISABLE_PHONG ) == 0; }
- bool ShadowDepthTexture() const { return m_bShadowDepthTexture; }
- bool MotionBlur() const { return m_bMotionBlur; }
- bool SupportFlashlight() const { return m_bSupportFlashlight; }
-
- void SetFlag( unsigned int flag, bool val )
- {
- if( val )
- {
- m_Flags |= flag;
- }
- else
- {
- m_Flags &= ~flag;
- }
- }
-
- // control panel stuff
- MaterialVideoMode_t m_VideoMode;
- float m_fMonitorGamma;
- float m_fGammaTVRangeMin;
- float m_fGammaTVRangeMax;
- float m_fGammaTVExponent;
- bool m_bGammaTVEnabled;
-
- int m_nAASamples;
- int m_nForceAnisotropicLevel;
- int skipMipLevels;
- int dxSupportLevel;
- unsigned int m_Flags;
- bool bEditMode; // true if in Hammer.
- unsigned char proxiesTestMode; // 0 = normal, 1 = no proxies, 2 = alpha test all, 3 = color mod all
- bool bCompressedTextures;
- bool bFilterLightmaps;
- bool bFilterTextures;
- bool bReverseDepth;
- bool bBufferPrimitives;
- bool bDrawFlat;
- bool bMeasureFillRate;
- bool bVisualizeFillRate;
- bool bNoTransparency;
- bool bSoftwareLighting;
- bool bAllowCheats;
- char nShowMipLevels;
- bool bShowLowResImage;
- bool bShowNormalMap;
- bool bMipMapTextures;
- unsigned char nFullbright;
- bool m_bFastNoBump;
- bool m_bSuppressRendering;
-
- // debug modes
- bool bShowSpecular; // This is the fast version that doesn't require reloading materials
- bool bShowDiffuse; // This is the fast version that doesn't require reloading materials
-
- // misc
- int m_nReserved; // Currently unused
-
- // No depth bias
- float m_SlopeScaleDepthBias_Normal;
- float m_DepthBias_Normal;
-
- // Depth bias for rendering decals closer to the camera
- float m_SlopeScaleDepthBias_Decal;
- float m_DepthBias_Decal;
-
- // Depth bias for biasing shadow depth map rendering away from the camera
- float m_SlopeScaleDepthBias_ShadowMap;
- float m_DepthBias_ShadowMap;
-
- uint m_WindowedSizeLimitWidth;
- uint m_WindowedSizeLimitHeight;
- int m_nAAQuality;
- bool m_bShadowDepthTexture;
- bool m_bMotionBlur;
- bool m_bSupportFlashlight;
-
- MaterialSystem_Config_t()
- {
- memset( this, 0, sizeof( *this ) );
-
- // video config defaults
- SetFlag( MATSYS_VIDCFG_FLAGS_WINDOWED, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_RESIZING, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC, true );
- SetFlag( MATSYS_VIDCFG_FLAGS_STENCIL, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_FORCE_TRILINEAR, true );
- SetFlag( MATSYS_VIDCFG_FLAGS_FORCE_HWSYNC, true );
- SetFlag( MATSYS_VIDCFG_FLAGS_DISABLE_SPECULAR, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_DISABLE_BUMPMAP, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_ENABLE_PARALLAX_MAPPING, true );
- SetFlag( MATSYS_VIDCFG_FLAGS_USE_Z_PREFILL, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_REDUCE_FILLRATE, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS, false );
- SetFlag( MATSYS_VIDCFG_FLAGS_DISABLE_PHONG, false );
-
- m_VideoMode.m_Width = 640;
- m_VideoMode.m_Height = 480;
- m_VideoMode.m_RefreshRate = 60;
- dxSupportLevel = 0;
- bCompressedTextures = true;
- bFilterTextures = true;
- bFilterLightmaps = true;
- bMipMapTextures = true;
- bBufferPrimitives = true;
-
- m_fMonitorGamma = 2.2f;
- m_fGammaTVRangeMin = 16.0f;
- m_fGammaTVRangeMax = 255.0f;
- m_fGammaTVExponent = 2.5;
- m_bGammaTVEnabled = IsX360();
-
- m_nAASamples = 1;
- m_bShadowDepthTexture = false;
- m_bMotionBlur = false;
- m_bSupportFlashlight = true;
-
- // misc defaults
- bAllowCheats = false;
- bCompressedTextures = true;
- bEditMode = false;
-
- // debug modes
- bShowSpecular = true;
- bShowDiffuse = true;
- nFullbright = 0;
- bShowNormalMap = false;
- bFilterLightmaps = true;
- bFilterTextures = true;
- bMipMapTextures = true;
- nShowMipLevels = 0;
- bShowLowResImage = false;
- bReverseDepth = false;
- bBufferPrimitives = true;
- bDrawFlat = false;
- bMeasureFillRate = false;
- bVisualizeFillRate = false;
- bSoftwareLighting = false;
- bNoTransparency = false;
- proxiesTestMode = 0;
- m_bFastNoBump = false;
- m_bSuppressRendering = false;
- m_SlopeScaleDepthBias_Decal = -0.5f;
- m_SlopeScaleDepthBias_Normal = 0.0f;
- m_SlopeScaleDepthBias_ShadowMap = 0.5f;
- m_DepthBias_Decal = -262144;
- m_DepthBias_Normal = 0.0f;
- m_DepthBias_ShadowMap = 262144;
- m_WindowedSizeLimitWidth = 1280;
- m_WindowedSizeLimitHeight = 1024;
- }
-};
-
-
-#endif // MATERIALSYSTEM_CONFIG_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef MATERIALSYSTEM_CONFIG_H +#define MATERIALSYSTEM_CONFIG_H +#ifdef _WIN32 +#pragma once +#endif + +#include "materialsystem/imaterialsystem.h" + +#define MATERIALSYSTEM_CONFIG_VERSION "VMaterialSystemConfig002" + +enum MaterialSystem_Config_Flags_t +{ + MATSYS_VIDCFG_FLAGS_WINDOWED = ( 1 << 0 ), + MATSYS_VIDCFG_FLAGS_RESIZING = ( 1 << 1 ), + MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC = ( 1 << 3 ), + MATSYS_VIDCFG_FLAGS_STENCIL = ( 1 << 4 ), + MATSYS_VIDCFG_FLAGS_FORCE_TRILINEAR = ( 1 << 5 ), + MATSYS_VIDCFG_FLAGS_FORCE_HWSYNC = ( 1 << 6 ), + MATSYS_VIDCFG_FLAGS_DISABLE_SPECULAR = ( 1 << 7 ), + MATSYS_VIDCFG_FLAGS_DISABLE_BUMPMAP = ( 1 << 8 ), + MATSYS_VIDCFG_FLAGS_ENABLE_PARALLAX_MAPPING = ( 1 << 9 ), + MATSYS_VIDCFG_FLAGS_USE_Z_PREFILL = ( 1 << 10 ), + MATSYS_VIDCFG_FLAGS_REDUCE_FILLRATE = ( 1 << 11 ), + MATSYS_VIDCFG_FLAGS_ENABLE_HDR = ( 1 << 12 ), + MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE = ( 1 << 13 ), + MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION = ( 1 << 14 ), + MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS = ( 1 << 15 ), + MATSYS_VIDCFG_FLAGS_DISABLE_PHONG = ( 1 << 16 ), +}; + +struct MaterialSystemHardwareIdentifier_t +{ + char *m_pCardName; + unsigned int m_nVendorID; + unsigned int m_nDeviceID; +}; + +struct MaterialSystem_Config_t +{ + bool Windowed() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_WINDOWED ) != 0; } + bool Resizing() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_RESIZING ) != 0; } +#ifdef CSS_PERF_TEST + bool WaitForVSync() const { return false; }//( m_Flags & MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC ) == 0; } +#else + bool WaitForVSync() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC ) == 0; } +#endif + bool Stencil() const { return (m_Flags & MATSYS_VIDCFG_FLAGS_STENCIL ) != 0; } + bool ForceTrilinear() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_FORCE_TRILINEAR ) != 0; } + bool ForceHWSync() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_FORCE_HWSYNC ) != 0; } + bool UseSpecular() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_DISABLE_SPECULAR ) == 0; } + bool UseBumpmapping() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_DISABLE_BUMPMAP ) == 0; } + bool UseParallaxMapping() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_ENABLE_PARALLAX_MAPPING ) != 0; } + bool UseZPrefill() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_USE_Z_PREFILL ) != 0; } + bool ReduceFillrate() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_REDUCE_FILLRATE ) != 0; } + bool HDREnabled() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_ENABLE_HDR ) != 0; } + bool LimitWindowedSize() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE ) != 0; } + bool ScaleToOutputResolution() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION ) != 0; } + bool UsingMultipleWindows() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS ) != 0; } + bool UsePhong() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_DISABLE_PHONG ) == 0; } + bool ShadowDepthTexture() const { return m_bShadowDepthTexture; } + bool MotionBlur() const { return m_bMotionBlur; } + bool SupportFlashlight() const { return m_bSupportFlashlight; } + + void SetFlag( unsigned int flag, bool val ) + { + if( val ) + { + m_Flags |= flag; + } + else + { + m_Flags &= ~flag; + } + } + + // control panel stuff + MaterialVideoMode_t m_VideoMode; + float m_fMonitorGamma; + float m_fGammaTVRangeMin; + float m_fGammaTVRangeMax; + float m_fGammaTVExponent; + bool m_bGammaTVEnabled; + + int m_nAASamples; + int m_nForceAnisotropicLevel; + int skipMipLevels; + int dxSupportLevel; + unsigned int m_Flags; + bool bEditMode; // true if in Hammer. + unsigned char proxiesTestMode; // 0 = normal, 1 = no proxies, 2 = alpha test all, 3 = color mod all + bool bCompressedTextures; + bool bFilterLightmaps; + bool bFilterTextures; + bool bReverseDepth; + bool bBufferPrimitives; + bool bDrawFlat; + bool bMeasureFillRate; + bool bVisualizeFillRate; + bool bNoTransparency; + bool bSoftwareLighting; + bool bAllowCheats; + char nShowMipLevels; + bool bShowLowResImage; + bool bShowNormalMap; + bool bMipMapTextures; + unsigned char nFullbright; + bool m_bFastNoBump; + bool m_bSuppressRendering; + + // debug modes + bool bShowSpecular; // This is the fast version that doesn't require reloading materials + bool bShowDiffuse; // This is the fast version that doesn't require reloading materials + + // misc + int m_nReserved; // Currently unused + + // No depth bias + float m_SlopeScaleDepthBias_Normal; + float m_DepthBias_Normal; + + // Depth bias for rendering decals closer to the camera + float m_SlopeScaleDepthBias_Decal; + float m_DepthBias_Decal; + + // Depth bias for biasing shadow depth map rendering away from the camera + float m_SlopeScaleDepthBias_ShadowMap; + float m_DepthBias_ShadowMap; + + uint m_WindowedSizeLimitWidth; + uint m_WindowedSizeLimitHeight; + int m_nAAQuality; + bool m_bShadowDepthTexture; + bool m_bMotionBlur; + bool m_bSupportFlashlight; + + MaterialSystem_Config_t() + { + memset( this, 0, sizeof( *this ) ); + + // video config defaults + SetFlag( MATSYS_VIDCFG_FLAGS_WINDOWED, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_RESIZING, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC, true ); + SetFlag( MATSYS_VIDCFG_FLAGS_STENCIL, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_FORCE_TRILINEAR, true ); + SetFlag( MATSYS_VIDCFG_FLAGS_FORCE_HWSYNC, true ); + SetFlag( MATSYS_VIDCFG_FLAGS_DISABLE_SPECULAR, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_DISABLE_BUMPMAP, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_ENABLE_PARALLAX_MAPPING, true ); + SetFlag( MATSYS_VIDCFG_FLAGS_USE_Z_PREFILL, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_REDUCE_FILLRATE, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS, false ); + SetFlag( MATSYS_VIDCFG_FLAGS_DISABLE_PHONG, false ); + + m_VideoMode.m_Width = 640; + m_VideoMode.m_Height = 480; + m_VideoMode.m_RefreshRate = 60; + dxSupportLevel = 0; + bCompressedTextures = true; + bFilterTextures = true; + bFilterLightmaps = true; + bMipMapTextures = true; + bBufferPrimitives = true; + + m_fMonitorGamma = 2.2f; + m_fGammaTVRangeMin = 16.0f; + m_fGammaTVRangeMax = 255.0f; + m_fGammaTVExponent = 2.5; + m_bGammaTVEnabled = IsX360(); + + m_nAASamples = 1; + m_bShadowDepthTexture = false; + m_bMotionBlur = false; + m_bSupportFlashlight = true; + + // misc defaults + bAllowCheats = false; + bCompressedTextures = true; + bEditMode = false; + + // debug modes + bShowSpecular = true; + bShowDiffuse = true; + nFullbright = 0; + bShowNormalMap = false; + bFilterLightmaps = true; + bFilterTextures = true; + bMipMapTextures = true; + nShowMipLevels = 0; + bShowLowResImage = false; + bReverseDepth = false; + bBufferPrimitives = true; + bDrawFlat = false; + bMeasureFillRate = false; + bVisualizeFillRate = false; + bSoftwareLighting = false; + bNoTransparency = false; + proxiesTestMode = 0; + m_bFastNoBump = false; + m_bSuppressRendering = false; + m_SlopeScaleDepthBias_Decal = -0.5f; + m_SlopeScaleDepthBias_Normal = 0.0f; + m_SlopeScaleDepthBias_ShadowMap = 0.5f; + m_DepthBias_Decal = -262144; + m_DepthBias_Normal = 0.0f; + m_DepthBias_ShadowMap = 262144; + m_WindowedSizeLimitWidth = 1280; + m_WindowedSizeLimitHeight = 1024; + } +}; + + +#endif // MATERIALSYSTEM_CONFIG_H diff --git a/mp/src/public/materialsystem/meshreader.h b/mp/src/public/materialsystem/meshreader.h index 7bfd80e2..15b68738 100644 --- a/mp/src/public/materialsystem/meshreader.h +++ b/mp/src/public/materialsystem/meshreader.h @@ -1,268 +1,268 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=====================================================================================//
-
-#ifndef MESHREADER_H
-#define MESHREADER_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-//-----------------------------------------------------------------------------
-// This is used to read vertex and index data out of already-created meshes.
-// xbox uses this a lot so it doesn't have to store sysmem backups of the
-// vertex data.
-//-----------------------------------------------------------------------------
-class CBaseMeshReader : protected MeshDesc_t
-{
-// Initialization.
-public:
-
- CBaseMeshReader();
- ~CBaseMeshReader();
-
- // Use BeginRead/EndRead to initialize the mesh reader.
- void BeginRead(
- IMesh* pMesh,
- int firstVertex = 0,
- int numVertices = 0,
- int firstIndex = 0,
- int numIndices = 0 );
-
- void EndRead();
-
- // PC can use this if it stores its own copy of meshes around, in case
- // locking static buffers is too costly.
- void BeginRead_Direct( const MeshDesc_t &desc, int numVertices, int nIndices );
-
- // Resets the mesh builder so it points to the start of everything again
- void Reset();
-
-
-protected:
- IMesh *m_pMesh;
- int m_MaxVertices;
- int m_MaxIndices;
-};
-
-
-// A bunch of accessors for the data that CBaseMeshReader sets up.
-class CMeshReader : public CBaseMeshReader
-{
-public:
-// Access to vertex data.
-public:
- int NumIndices() const;
- unsigned short Index( int index ) const;
-
- const Vector& Position( int iVertex ) const;
-
- unsigned int Color( int iVertex ) const;
-
- const float *TexCoord( int iVertex, int stage ) const;
- void TexCoord2f( int iVertex, int stage, float &s, float &t ) const;
- const Vector2D& TexCoordVector2D( int iVertex, int stage ) const;
-
- int NumBoneWeights() const;
- float Wrinkle( int iVertex ) const;
-
- const Vector &Normal( int iVertex ) const;
- void Normal( int iVertex, Vector &vNormal ) const;
-
- const Vector &TangentS( int iVertex ) const;
- const Vector &TangentT( int iVertex ) const;
- float BoneWeight( int iVertex ) const;
-
-#ifdef NEW_SKINNING
- float* BoneMatrix( int iVertex ) const;
-#else
- unsigned char* BoneMatrix( int iVertex ) const;
-#endif
-};
-
-
-//-----------------------------------------------------------------------------
-// CBaseMeshReader implementation.
-//-----------------------------------------------------------------------------
-
-inline CBaseMeshReader::CBaseMeshReader()
-{
- m_pMesh = NULL;
-}
-
-inline CBaseMeshReader::~CBaseMeshReader()
-{
- Assert( !m_pMesh );
-}
-
-inline void CBaseMeshReader::BeginRead(
- IMesh* pMesh,
- int firstVertex,
- int numVertices,
- int firstIndex,
- int numIndices )
-{
- Assert( pMesh && (!m_pMesh) );
-
- if ( numVertices < 0 )
- {
- numVertices = pMesh->VertexCount();
- }
-
- if ( numIndices < 0 )
- {
- numIndices = pMesh->IndexCount();
- }
-
- m_pMesh = pMesh;
- m_MaxVertices = numVertices;
- m_MaxIndices = numIndices;
-
- // UNDONE: support reading from compressed VBs if needed
- VertexCompressionType_t compressionType = CompressionType( pMesh->GetVertexFormat() );
- Assert( compressionType == VERTEX_COMPRESSION_NONE );
- if ( compressionType != VERTEX_COMPRESSION_NONE )
- {
- Warning( "Cannot use CBaseMeshReader with compressed vertices! Will get junk data or a crash.\n" );
- }
-
- // Locks mesh for modifying
- pMesh->ModifyBeginEx( true, firstVertex, numVertices, firstIndex, numIndices, *this );
-
- // Point to the start of the buffers..
- Reset();
-}
-
-inline void CBaseMeshReader::EndRead()
-{
- Assert( m_pMesh );
- m_pMesh->ModifyEnd( *this );
- m_pMesh = NULL;
-}
-
-inline void CBaseMeshReader::BeginRead_Direct( const MeshDesc_t &desc, int nVertices, int nIndices )
-{
- MeshDesc_t *pThis = this;
- *pThis = desc;
- m_MaxVertices = nVertices;
- m_MaxIndices = nIndices;
-
- // UNDONE: support reading from compressed verts if necessary
- Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE );
- if ( desc.m_CompressionType != VERTEX_COMPRESSION_NONE )
- {
- Warning( "Cannot use CBaseMeshReader with compressed vertices!\n" );
- }
-}
-
-inline void CBaseMeshReader::Reset()
-{
-}
-
-
-
-
-// -------------------------------------------------------------------------------------- //
-// CMeshReader implementation.
-// -------------------------------------------------------------------------------------- //
-
-inline int CMeshReader::NumIndices() const
-{
- return m_MaxIndices;
-}
-
-inline unsigned short CMeshReader::Index( int index ) const
-{
- Assert( (index >= 0) && (index < m_MaxIndices) );
- return m_pIndices[index * m_nIndexSize];
-}
-
-inline const Vector& CMeshReader::Position( int iVertex ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- return *(Vector*)((char*)m_pPosition + iVertex * m_VertexSize_Position);
-}
-
-inline unsigned int CMeshReader::Color( int iVertex ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- unsigned char *pColor = m_pColor + iVertex * m_VertexSize_Color;
- return (pColor[0] << 16) | (pColor[1] << 8) | (pColor[2]) | (pColor[3] << 24);
-}
-
-inline const float *CMeshReader::TexCoord( int iVertex, int iStage ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- return (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] );
-}
-
-inline void CMeshReader::TexCoord2f( int iVertex, int iStage, float &s, float &t ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- float *p = (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] );
- s = p[0];
- t = p[1];
-}
-
-inline const Vector2D& CMeshReader::TexCoordVector2D( int iVertex, int iStage ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- Vector2D *p = (Vector2D*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] );
- return *p;
-}
-
-inline float CMeshReader::Wrinkle( int iVertex ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- return *(float*)( (char*)m_pWrinkle + iVertex * m_VertexSize_Wrinkle );
-}
-
-inline int CMeshReader::NumBoneWeights() const
-{
- return m_NumBoneWeights;
-}
-
-inline const Vector &CMeshReader::Normal( int iVertex ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- return *(const Vector *)(const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal );
-}
-
-inline void CMeshReader::Normal( int iVertex, Vector &vNormal ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- const float *p = (const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal );
- vNormal.Init( p[0], p[1], p[2] );
-}
-
-inline const Vector &CMeshReader::TangentS( int iVertex ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- return *(const Vector*)( (char*)m_pTangentS + iVertex * m_VertexSize_TangentS );
-}
-
-inline const Vector &CMeshReader::TangentT( int iVertex ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- return *(const Vector*)( (char*)m_pTangentT + iVertex * m_VertexSize_TangentT );
-}
-
-inline float CMeshReader::BoneWeight( int iVertex ) const
-{
- Assert( iVertex >= 0 && iVertex < m_MaxVertices );
- float *p = (float*)( (char*)m_pBoneWeight + iVertex * m_VertexSize_BoneWeight );
- return *p;
-}
-
-#endif // MESHREADER_H
-
-
-
-
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#ifndef MESHREADER_H +#define MESHREADER_H + +#ifdef _WIN32 +#pragma once +#endif + + +//----------------------------------------------------------------------------- +// This is used to read vertex and index data out of already-created meshes. +// xbox uses this a lot so it doesn't have to store sysmem backups of the +// vertex data. +//----------------------------------------------------------------------------- +class CBaseMeshReader : protected MeshDesc_t +{ +// Initialization. +public: + + CBaseMeshReader(); + ~CBaseMeshReader(); + + // Use BeginRead/EndRead to initialize the mesh reader. + void BeginRead( + IMesh* pMesh, + int firstVertex = 0, + int numVertices = 0, + int firstIndex = 0, + int numIndices = 0 ); + + void EndRead(); + + // PC can use this if it stores its own copy of meshes around, in case + // locking static buffers is too costly. + void BeginRead_Direct( const MeshDesc_t &desc, int numVertices, int nIndices ); + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + +protected: + IMesh *m_pMesh; + int m_MaxVertices; + int m_MaxIndices; +}; + + +// A bunch of accessors for the data that CBaseMeshReader sets up. +class CMeshReader : public CBaseMeshReader +{ +public: +// Access to vertex data. +public: + int NumIndices() const; + unsigned short Index( int index ) const; + + const Vector& Position( int iVertex ) const; + + unsigned int Color( int iVertex ) const; + + const float *TexCoord( int iVertex, int stage ) const; + void TexCoord2f( int iVertex, int stage, float &s, float &t ) const; + const Vector2D& TexCoordVector2D( int iVertex, int stage ) const; + + int NumBoneWeights() const; + float Wrinkle( int iVertex ) const; + + const Vector &Normal( int iVertex ) const; + void Normal( int iVertex, Vector &vNormal ) const; + + const Vector &TangentS( int iVertex ) const; + const Vector &TangentT( int iVertex ) const; + float BoneWeight( int iVertex ) const; + +#ifdef NEW_SKINNING + float* BoneMatrix( int iVertex ) const; +#else + unsigned char* BoneMatrix( int iVertex ) const; +#endif +}; + + +//----------------------------------------------------------------------------- +// CBaseMeshReader implementation. +//----------------------------------------------------------------------------- + +inline CBaseMeshReader::CBaseMeshReader() +{ + m_pMesh = NULL; +} + +inline CBaseMeshReader::~CBaseMeshReader() +{ + Assert( !m_pMesh ); +} + +inline void CBaseMeshReader::BeginRead( + IMesh* pMesh, + int firstVertex, + int numVertices, + int firstIndex, + int numIndices ) +{ + Assert( pMesh && (!m_pMesh) ); + + if ( numVertices < 0 ) + { + numVertices = pMesh->VertexCount(); + } + + if ( numIndices < 0 ) + { + numIndices = pMesh->IndexCount(); + } + + m_pMesh = pMesh; + m_MaxVertices = numVertices; + m_MaxIndices = numIndices; + + // UNDONE: support reading from compressed VBs if needed + VertexCompressionType_t compressionType = CompressionType( pMesh->GetVertexFormat() ); + Assert( compressionType == VERTEX_COMPRESSION_NONE ); + if ( compressionType != VERTEX_COMPRESSION_NONE ) + { + Warning( "Cannot use CBaseMeshReader with compressed vertices! Will get junk data or a crash.\n" ); + } + + // Locks mesh for modifying + pMesh->ModifyBeginEx( true, firstVertex, numVertices, firstIndex, numIndices, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CBaseMeshReader::EndRead() +{ + Assert( m_pMesh ); + m_pMesh->ModifyEnd( *this ); + m_pMesh = NULL; +} + +inline void CBaseMeshReader::BeginRead_Direct( const MeshDesc_t &desc, int nVertices, int nIndices ) +{ + MeshDesc_t *pThis = this; + *pThis = desc; + m_MaxVertices = nVertices; + m_MaxIndices = nIndices; + + // UNDONE: support reading from compressed verts if necessary + Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE ); + if ( desc.m_CompressionType != VERTEX_COMPRESSION_NONE ) + { + Warning( "Cannot use CBaseMeshReader with compressed vertices!\n" ); + } +} + +inline void CBaseMeshReader::Reset() +{ +} + + + + +// -------------------------------------------------------------------------------------- // +// CMeshReader implementation. +// -------------------------------------------------------------------------------------- // + +inline int CMeshReader::NumIndices() const +{ + return m_MaxIndices; +} + +inline unsigned short CMeshReader::Index( int index ) const +{ + Assert( (index >= 0) && (index < m_MaxIndices) ); + return m_pIndices[index * m_nIndexSize]; +} + +inline const Vector& CMeshReader::Position( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(Vector*)((char*)m_pPosition + iVertex * m_VertexSize_Position); +} + +inline unsigned int CMeshReader::Color( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + unsigned char *pColor = m_pColor + iVertex * m_VertexSize_Color; + return (pColor[0] << 16) | (pColor[1] << 8) | (pColor[2]) | (pColor[3] << 24); +} + +inline const float *CMeshReader::TexCoord( int iVertex, int iStage ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] ); +} + +inline void CMeshReader::TexCoord2f( int iVertex, int iStage, float &s, float &t ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + float *p = (float*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] ); + s = p[0]; + t = p[1]; +} + +inline const Vector2D& CMeshReader::TexCoordVector2D( int iVertex, int iStage ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + Vector2D *p = (Vector2D*)( (char*)m_pTexCoord[iStage] + iVertex * m_VertexSize_TexCoord[iStage] ); + return *p; +} + +inline float CMeshReader::Wrinkle( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(float*)( (char*)m_pWrinkle + iVertex * m_VertexSize_Wrinkle ); +} + +inline int CMeshReader::NumBoneWeights() const +{ + return m_NumBoneWeights; +} + +inline const Vector &CMeshReader::Normal( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(const Vector *)(const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal ); +} + +inline void CMeshReader::Normal( int iVertex, Vector &vNormal ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + const float *p = (const float*)( (char*)m_pNormal + iVertex * m_VertexSize_Normal ); + vNormal.Init( p[0], p[1], p[2] ); +} + +inline const Vector &CMeshReader::TangentS( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(const Vector*)( (char*)m_pTangentS + iVertex * m_VertexSize_TangentS ); +} + +inline const Vector &CMeshReader::TangentT( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + return *(const Vector*)( (char*)m_pTangentT + iVertex * m_VertexSize_TangentT ); +} + +inline float CMeshReader::BoneWeight( int iVertex ) const +{ + Assert( iVertex >= 0 && iVertex < m_MaxVertices ); + float *p = (float*)( (char*)m_pBoneWeight + iVertex * m_VertexSize_BoneWeight ); + return *p; +} + +#endif // MESHREADER_H + + + + + + + diff --git a/mp/src/public/materialsystem/shader_vcs_version.h b/mp/src/public/materialsystem/shader_vcs_version.h index ed2c8c71..eebad901 100644 --- a/mp/src/public/materialsystem/shader_vcs_version.h +++ b/mp/src/public/materialsystem/shader_vcs_version.h @@ -1,75 +1,75 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef SHADER_VCS_VERSION_H
-#define SHADER_VCS_VERSION_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-// 1 = hl2 shipped
-// 2 = compressed with diffs version (lostcoast)
-// 3 = compressed with bzip
-// 4 = v2 + crc32
-// 5 = v3 + crc32
-// 6 = v5 + duplicate static combo records
-#define SHADER_VCS_VERSION_NUMBER 6
-
-#define MAX_SHADER_UNPACKED_BLOCK_SIZE (1<<17)
-#define MAX_SHADER_PACKED_SIZE (1+MAX_SHADER_UNPACKED_BLOCK_SIZE)
-
-#pragma pack(1)
-struct ShaderHeader_t
-{
- int32 m_nVersion;
- int32 m_nTotalCombos;
- int32 m_nDynamicCombos;
- uint32 m_nFlags;
- uint32 m_nCentroidMask;
- uint32 m_nNumStaticCombos; // includes sentinal key
- uint32 m_nSourceCRC32; // NOTE: If you move this, update copyshaders.pl, *_prep.pl, updateshaders.pl
-};
-#pragma pack()
-
-#pragma pack(1)
-struct ShaderHeader_t_v4 // still used for assembly shaders
-{
- int32 m_nVersion;
- int32 m_nTotalCombos;
- int32 m_nDynamicCombos;
- uint32 m_nFlags;
- uint32 m_nCentroidMask;
- uint32 m_nDiffReferenceSize;
- uint32 m_nSourceCRC32; // NOTE: If you move this, update copyshaders.pl, *_prep.pl, updateshaders.pl
-};
-#pragma pack()
-
-// for old format files
-struct ShaderDictionaryEntry_t
-{
- int m_Offset;
- int m_Size;
-};
-
-// record for one static combo
-struct StaticComboRecord_t
-{
- uint32 m_nStaticComboID;
- uint32 m_nFileOffset;
-};
-
-
-struct StaticComboAliasRecord_t // for duplicate static combos
-{
- uint32 m_nStaticComboID; // this combo
- uint32 m_nSourceStaticCombo; // the combo it is the same as
-};
-
-
-
-
-#endif // SHADER_VCS_VERSION_H
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef SHADER_VCS_VERSION_H +#define SHADER_VCS_VERSION_H +#ifdef _WIN32 +#pragma once +#endif + +// 1 = hl2 shipped +// 2 = compressed with diffs version (lostcoast) +// 3 = compressed with bzip +// 4 = v2 + crc32 +// 5 = v3 + crc32 +// 6 = v5 + duplicate static combo records +#define SHADER_VCS_VERSION_NUMBER 6 + +#define MAX_SHADER_UNPACKED_BLOCK_SIZE (1<<17) +#define MAX_SHADER_PACKED_SIZE (1+MAX_SHADER_UNPACKED_BLOCK_SIZE) + +#pragma pack(1) +struct ShaderHeader_t +{ + int32 m_nVersion; + int32 m_nTotalCombos; + int32 m_nDynamicCombos; + uint32 m_nFlags; + uint32 m_nCentroidMask; + uint32 m_nNumStaticCombos; // includes sentinal key + uint32 m_nSourceCRC32; // NOTE: If you move this, update copyshaders.pl, *_prep.pl, updateshaders.pl +}; +#pragma pack() + +#pragma pack(1) +struct ShaderHeader_t_v4 // still used for assembly shaders +{ + int32 m_nVersion; + int32 m_nTotalCombos; + int32 m_nDynamicCombos; + uint32 m_nFlags; + uint32 m_nCentroidMask; + uint32 m_nDiffReferenceSize; + uint32 m_nSourceCRC32; // NOTE: If you move this, update copyshaders.pl, *_prep.pl, updateshaders.pl +}; +#pragma pack() + +// for old format files +struct ShaderDictionaryEntry_t +{ + int m_Offset; + int m_Size; +}; + +// record for one static combo +struct StaticComboRecord_t +{ + uint32 m_nStaticComboID; + uint32 m_nFileOffset; +}; + + +struct StaticComboAliasRecord_t // for duplicate static combos +{ + uint32 m_nStaticComboID; // this combo + uint32 m_nSourceStaticCombo; // the combo it is the same as +}; + + + + +#endif // SHADER_VCS_VERSION_H + |