aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/materialsystem
diff options
context:
space:
mode:
authorNarendra Umate <[email protected]>2013-12-02 23:36:05 -0800
committerNarendra Umate <[email protected]>2013-12-02 23:36:05 -0800
commit8737f191f3b59f001a77bf6c08091109211c1c9f (patch)
treedbbf05c004d9b026f2c1f23f06600fe0add82c36 /mp/src/public/materialsystem
parentUpdate .gitignore. (diff)
parentMake .xcconfigs text files too. (diff)
downloadsource-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.tar.xz
source-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'mp/src/public/materialsystem')
-rw-r--r--mp/src/public/materialsystem/IColorCorrection.h146
-rw-r--r--mp/src/public/materialsystem/IShader.h410
-rw-r--r--mp/src/public/materialsystem/MaterialSystemUtil.cpp510
-rw-r--r--mp/src/public/materialsystem/MaterialSystemUtil.h198
-rw-r--r--mp/src/public/materialsystem/deformations.h116
-rw-r--r--mp/src/public/materialsystem/hardwareverts.h172
-rw-r--r--mp/src/public/materialsystem/idebugtextureinfo.h138
-rw-r--r--mp/src/public/materialsystem/imaterial.h1224
-rw-r--r--mp/src/public/materialsystem/imaterialproxy.h64
-rw-r--r--mp/src/public/materialsystem/imaterialproxyfactory.h50
-rw-r--r--mp/src/public/materialsystem/imaterialsystem.h3516
-rw-r--r--mp/src/public/materialsystem/imaterialsystemhardwareconfig.h424
-rw-r--r--mp/src/public/materialsystem/imaterialsystemstub.h62
-rw-r--r--mp/src/public/materialsystem/imaterialvar.h490
-rw-r--r--mp/src/public/materialsystem/imesh.h8094
-rw-r--r--mp/src/public/materialsystem/imorph.h502
-rw-r--r--mp/src/public/materialsystem/ishaderapi.h86
-rw-r--r--mp/src/public/materialsystem/itexture.h264
-rw-r--r--mp/src/public/materialsystem/ivballoctracker.h70
-rw-r--r--mp/src/public/materialsystem/materialsystem_config.h444
-rw-r--r--mp/src/public/materialsystem/meshreader.h536
-rw-r--r--mp/src/public/materialsystem/shader_vcs_version.h150
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
+