diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/public/materialsystem/imaterial.h | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/public/materialsystem/imaterial.h')
| -rw-r--r-- | mp/src/public/materialsystem/imaterial.h | 1224 |
1 files changed, 612 insertions, 612 deletions
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 |