📄 meshdx8.cpp
字号:
private:
// Selection mode
void TestSelection( );
void ClipTriangle( D3DXVECTOR3** ppVert, float zNear, D3DXMATRIX& proj );
CDynamicMeshDX8* GetDynamicMesh();
CUtlVector< unsigned char > m_VertexData;
CUtlVector< unsigned short > m_IndexData;
unsigned short m_VertexSize;
MaterialPrimitiveType_t m_Type;
int m_LockedVerts;
int m_LockedIndices;
bool m_IsDynamic;
// Used in rendering sub-parts of the mesh
static unsigned int s_NumIndices;
static unsigned int s_FirstIndex;
#ifdef _DEBUG
bool m_Locked;
bool m_InPass;
#endif
};
//-----------------------------------------------------------------------------
// This is a version that buffers up vertex data so we can blast through it later
//-----------------------------------------------------------------------------
class CBufferedMeshDX8 : public CBaseMeshDX8
{
public:
// constructor, destructor
CBufferedMeshDX8();
virtual ~CBufferedMeshDX8();
// checks to see if it was rendered..
void ResetRendered();
bool WasNotRendered() const;
// Sets the mesh we're really going to draw into
void SetMesh( CBaseMeshDX8* pMesh );
// Sets the vertex format
void SetVertexFormat( VertexFormat_t format );
VertexFormat_t GetVertexFormat() const;
// Sets the material
void SetMaterial( IMaterial* pMaterial );
// returns the number of indices (should never be called!)
int NumIndices() const { Assert(0); return 0; }
// Locks the mesh
void LockMesh( int numVerts, int numIndices, MeshDesc_t& desc );
void UnlockMesh( int numVerts, int numIndices, MeshDesc_t& desc );
// Sets the primitive type
void SetPrimitiveType( MaterialPrimitiveType_t type );
MaterialPrimitiveType_t GetPrimitiveType( ) const;
// Draws it
void Draw( int firstIndex, int numIndices );
// Renders a pass
void RenderPass();
// Flushes queued data
void Flush( );
virtual void SetSoftwareVertexShader( SoftwareVertexShader_t shader );
virtual void CallSoftwareVertexShader( CMeshBuilder *pMeshBuilder );
private:
// The actual mesh we need to render....
CBaseMeshDX8* m_pMesh;
// The index of the last vertex (for tristrip fixup)
unsigned short m_LastIndex;
// Extra padding indices for tristrips
unsigned short m_ExtraIndices;
// Am I currently flushing?
bool m_IsFlushing;
// has the dynamic mesh been rendered?
bool m_WasRendered;
// Do I need to flush?
bool m_FlushNeeded;
#ifdef DEBUG_BUFFERED_MESHES
// for debugging only
bool m_BufferedStateSet;
BufferedState_t m_BufferedState;
#endif
};
//-----------------------------------------------------------------------------
// Implementation of the mesh manager
//-----------------------------------------------------------------------------
class CMeshMgr : public IMeshMgr
{
public:
// constructor, destructor
CMeshMgr();
virtual ~CMeshMgr();
// Initialize, shutdown
void Init();
void Shutdown();
// Task switch...
void ReleaseBuffers();
void RestoreBuffers();
// Releases all dynamic vertex buffers
void DestroyVertexBuffers();
// Flushes the dynamic mesh
void Flush();
// Flushes the vertex buffers
void DiscardVertexBuffers();
// Creates, destroys static meshes
IMesh* CreateStaticMesh( IMaterial* pMaterial, bool bForceTempMesh );
IMesh* CreateStaticMesh( VertexFormat_t vertexFormat, bool bSoftwareVertexShader );
void DestroyStaticMesh( IMesh* pMesh );
// Gets at the dynamic mesh (spoofs it though)
IMesh* GetDynamicMesh( IMaterial* pMaterial, bool buffered,
IMesh* pVertexOverride, IMesh* pIndexOverride );
// Gets at the *actual* dynamic mesh
IMesh* GetActualDynamicMesh( VertexFormat_t vertexFormat );
// Computes a 'standard' format to use that's at least as large
// as the passed-in format and is cached aligned
VertexFormat_t ComputeVertexFormat( unsigned int flags,
int numTexCoords, int* pTexCoordDimensions, int numBoneWeights,
int userDataSize ) const;
// Computes one of our standard formats that can fit the requested one.
VertexFormat_t ComputeStandardFormat( VertexFormat_t fmt ) const;
// Returns a vertex buffer appropriate for the flags
CVertexBuffer* FindOrCreateVertexBuffer( VertexFormat_t fmt );
CIndexBuffer* GetDynamicIndexBuffer();
// Is the mesh dynamic?
bool IsDynamicMesh( IMesh* pMesh ) const;
// Returns the vertex size
int VertexFormatSize( VertexFormat_t vertexFormat ) const;
// Computes the vertex buffer pointers
void ComputeVertexDescription( unsigned char* pBuffer,
VertexFormat_t vertexFormat, MeshDesc_t& desc ) const;
// Returns the number of buffers...
int BufferCount() const
{
#ifdef _DEBUG
return CVertexBuffer::BufferCount() + CIndexBuffer::BufferCount();
#else
return 0;
#endif
}
private:
struct VertexBufferLookup_t
{
CVertexBuffer* m_pBuffer;
int m_VertexSize;
};
void CopyStaticMeshIndexBufferToTempMeshIndexBuffer( CTempMeshDX8 *pDstIndexMesh,
CMeshDX8 *pSrcIndexMesh );
// Cleans up the class
void CleanUp();
// The dynamic index buffer
CIndexBuffer* m_pDynamicIndexBuffer;
// The dynamic vertex buffers
CUtlVector< VertexBufferLookup_t > m_DynamicVertexBuffers;
// The buffered mesh
CBufferedMeshDX8 m_BufferedMesh;
// The current dynamic mesh
CDynamicMeshDX8 m_DynamicMesh;
// The dynamic mesh temp version (for shaders that modify vertex data)
CTempMeshDX8 m_DynamicTempMesh;
// Am I buffering or not?
bool m_BufferedMode;
};
//-----------------------------------------------------------------------------
// Singleton...
//-----------------------------------------------------------------------------
static CMeshMgr g_MeshMgr;
IMeshMgr* MeshMgr()
{
return &g_MeshMgr;
}
//-----------------------------------------------------------------------------
// Helpers with meshdescs...
//-----------------------------------------------------------------------------
inline D3DXVECTOR3& Position( MeshDesc_t const& desc, int vert )
{
return *(D3DXVECTOR3*)((unsigned char*)desc.m_pPosition + vert * desc.m_VertexSize_Position );
}
inline D3DXVECTOR3& BoneWeight( MeshDesc_t const& desc, int vert )
{
return *(D3DXVECTOR3*)((unsigned char*)desc.m_pBoneWeight + vert * desc.m_VertexSize_BoneWeight );
}
inline unsigned char *BoneIndex( MeshDesc_t const& desc, int vert )
{
return desc.m_pBoneMatrixIndex + vert * desc.m_VertexSize_BoneMatrixIndex;
}
inline D3DXVECTOR3& Normal( MeshDesc_t const& desc, int vert )
{
return *(D3DXVECTOR3*)((unsigned char*)desc.m_pNormal + vert * desc.m_VertexSize_Normal );
}
inline unsigned char* Color( MeshDesc_t const& desc, int vert )
{
return desc.m_pColor + vert * desc.m_VertexSize_Color;
}
inline D3DXVECTOR2& TexCoord( MeshDesc_t const& desc, int vert, int stage )
{
return *(D3DXVECTOR2*)((unsigned char*)desc.m_pTexCoord[stage] + vert * desc.m_VertexSize_TexCoord[stage] );
}
inline D3DXVECTOR3& TangentS( MeshDesc_t const& desc, int vert )
{
return *(D3DXVECTOR3*)((unsigned char*)desc.m_pTangentS + vert * desc.m_VertexSize_TangentS );
}
inline D3DXVECTOR3& TangentT( MeshDesc_t const& desc, int vert )
{
return *(D3DXVECTOR3*)((unsigned char*)desc.m_pTangentT + vert * desc.m_VertexSize_TangentT );
}
//-----------------------------------------------------------------------------
//
// Base mesh
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
CBaseMeshDX8::CBaseMeshDX8() : m_VertexFormat(0)
{
#ifdef _DEBUG
m_IsDrawing = false;
m_pMaterial = 0;
#endif
}
CBaseMeshDX8::~CBaseMeshDX8()
{
}
//-----------------------------------------------------------------------------
// For debugging...
//-----------------------------------------------------------------------------
bool CBaseMeshDX8::DebugTrace() const
{
#ifdef _DEBUG
if (m_pMaterial)
return m_pMaterial->PerformDebugTrace();
#endif
return false;
}
void CBaseMeshDX8::SetMaterial( IMaterial* pMaterial )
{
#ifdef _DEBUG
m_pMaterial = static_cast<IMaterialInternal*>(pMaterial);
#endif
}
//-----------------------------------------------------------------------------
// Sets, gets the material
//-----------------------------------------------------------------------------
void CBaseMeshDX8::SetVertexFormat( VertexFormat_t format )
{
m_VertexFormat = format;
}
VertexFormat_t CBaseMeshDX8::GetVertexFormat() const
{
return m_VertexFormat;
}
//-----------------------------------------------------------------------------
// Do I need to reset the vertex format?
//-----------------------------------------------------------------------------
bool CBaseMeshDX8::NeedsVertexFormatReset( VertexFormat_t fmt ) const
{
return m_VertexFormat != fmt;
}
//-----------------------------------------------------------------------------
// Do I have enough room?
//-----------------------------------------------------------------------------
bool CBaseMeshDX8::HasEnoughRoom( int numVerts, int numIndices ) const
{
// by default, we do
return true;
}
//-----------------------------------------------------------------------------
// Uses pre-defined index buffers
//-----------------------------------------------------------------------------
void CBaseMeshDX8::GenerateSequentialIndexBuffer( unsigned short* pIndices, int numIndices, int firstVertex )
{
if( !pIndices )
{
// app probably isn't active
return;
}
// Format the sequential buffer
for ( int i = 0; i < numIndices; ++i)
{
pIndices[i] = i + firstVertex;
}
}
void CBaseMeshDX8::GenerateQuadIndexBuffer( unsigned short* pIndices, int numIndices, int firstVertex )
{
if( !pIndices )
{
// app probably isn't active
return;
}
// Format the quad buffer
int i;
int numQuads = numIndices / 6;
int baseVertex = firstVertex;
for ( i = 0; i < numQuads; ++i)
{
// Triangle 1
pIndices[0] = baseVertex;
pIndices[1] = baseVertex + 1;
pIndices[2] = baseVertex + 2;
// Triangle 2
pIndices[3] = baseVertex;
pIndices[4] = baseVertex + 2;
pIndices[5] = baseVertex + 3;
baseVertex += 4;
pIndices += 6;
}
}
void CBaseMeshDX8::GeneratePolygonIndexBuffer( unsigned short* pIndices, int numIndices, int firstVertex )
{
if( !pIndices )
{
// app probably isn't active
return;
}
int i, baseVertex;
int numPolygons = numIndices / 3;
baseVertex = firstVertex;
for ( i = 0; i < numPolygons; ++i)
{
// Triangle 1
pIndices[0] = firstVertex;
pIndices[1] = firstVertex + i + 1;
pIndices[2] = firstVertex + i + 2;
pIndices += 3;
}
}
void CBaseMeshDX8::GenerateLineStripIndexBuffer( unsigned short* pIndices,
int numIndices, int firstVertex )
{
if( !pIndices )
{
// app probably isn't active
return;
}
int i, baseVertex;
int numLines = numIndices / 2;
baseVertex = firstVertex;
for ( i = 0; i < numLines; ++i)
{
pIndices[0] = firstVertex + i;
pIndices[1] = firstVertex + i + 1;
pIndices += 2;
}
}
void CBaseMeshDX8::GenerateLineLoopIndexBuffer( unsigned short* pIndices,
int numIndices, int firstVertex )
{
if( !pIndices )
{
// app probably isn't active
return;
}
int i, baseVertex;
int numLines = numIndices / 2;
baseVertex = firstVertex;
pIndices[0] = firstVertex + numLines - 1;
pIndices[1] = firstVertex;
pIndices += 2;
for ( i = 1; i < numLines; ++i)
{
pIndices[0] = firstVertex + i - 1;
pIndices[1] = firstVertex + i;
pIndices += 2;
}
}
//-----------------------------------------------------------------------------
// Locks mesh for modifying
//-----------------------------------------------------------------------------
void CBaseMeshDX8::ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc )
{
// for the time being, disallow for most cases
Assert(0);
}
void CBaseMeshDX8::ModifyEnd()
{
// for the time being, disallow for most cases
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -