⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 meshdx8.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//=========== (C) Copyright 1999 Valve, L.L.C. 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: $
//
// The dx8 implementation of the shader API
//=============================================================================

#include "locald3dtypes.h"
#include "IMeshDX8.h"
#include "ShaderAPIDX8_Global.h"
#include "tier0/vprof.h"

// fixme - stick this in a header file.
#ifdef _DEBUG
// define this if you want to range check all indices when drawing
#define CHECK_INDICES
#endif

#ifdef CHECK_INDICES
#define CHECK_INDICES_MAX_NUM_STREAMS 2
#endif

#include "DynamicIB.h"
#include "DynamicVB.h"
#include "UtlVector.h"
#include "ShaderAPI.h"
#include "IMaterialInternal.h"
#include "ShaderAPIDX8.h"
#include "IShaderUtil.h"
#include "CMaterialSystemStats.h"
#include "materialsystem/IMaterialSystemHardwareConfig.h"
#include "materialsystem/MaterialSystem_Config.h"
#include "tier0/memdbgon.h"

//-----------------------------------------------------------------------------
// Uncomment this to test buffered state
//-----------------------------------------------------------------------------

//#define DEBUG_BUFFERED_MESHES 1
//#define DRAW_SELECTION 1

//-----------------------------------------------------------------------------
// Important enumerations
//-----------------------------------------------------------------------------
enum
{
	VERTEX_BUFFER_SIZE = 32768,
	INDEX_BUFFER_SIZE = 32768,
};


//-----------------------------------------------------------------------------
// Standard vertex formats (must be sorted from smallest to largest)
//-----------------------------------------------------------------------------
static VertexFormat_t s_pStandardFormats[] =
{
	// 32 byte formats

	// position, color, two tex coordinates (32 bytes)
	VERTEX_POSITION | VERTEX_COLOR | 
			VERTEX_NUM_TEXCOORDS(2) |
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2),

	// position, normal, one tex coordinate	(32 bytes)
	VERTEX_POSITION | VERTEX_NORMAL | 
			VERTEX_NUM_TEXCOORDS(1) | 
			VERTEX_TEXCOORD_SIZE(0, 2),

	// 48 byte formats

	// position, normal, color, specular, two tex coordinates (48 bytes)
	VERTEX_POSITION | VERTEX_COLOR | VERTEX_SPECULAR | VERTEX_NORMAL |
			VERTEX_NUM_TEXCOORDS(2) | 
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2),

	// position, 2 bones, normal, color, one tex coord (48 bytes)
	VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL |
			VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX | 
			VERTEX_NUM_TEXCOORDS(1) | VERTEX_TEXCOORD_SIZE(0, 2),

	// 64 byte formats

	// position, normal, color, specular, four tex coordinates (64 bytes)
	VERTEX_POSITION | VERTEX_COLOR | VERTEX_SPECULAR | VERTEX_NORMAL |
			VERTEX_NUM_TEXCOORDS(4) | 
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2) | 
			VERTEX_TEXCOORD_SIZE(2, 2) | VERTEX_TEXCOORD_SIZE(3, 2),

	// position, 1 bone, normal, color, specular, four tex coords (64 bytes)
	VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL |
			VERTEX_BONEWEIGHT(1) | 
			VERTEX_NUM_TEXCOORDS(4) | 
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2) | 
			VERTEX_TEXCOORD_SIZE(2, 2) | VERTEX_TEXCOORD_SIZE(3, 2),

	// position, normal, color, four tex coordinates (64 bytes), 3d tex coord in stage 2
	VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL |
			VERTEX_NUM_TEXCOORDS(4) | 
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2) | 
			VERTEX_TEXCOORD_SIZE(2, 3) | VERTEX_TEXCOORD_SIZE(3, 2),

	// position, color, tangentS, tangentT, three tex coordinates (64 bytes)
	VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T |  
			VERTEX_NUM_TEXCOORDS(3) | 
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2) | 
			VERTEX_TEXCOORD_SIZE(2, 2),

	// 80 byte formats

	// Position, normal, color, specular, tangentS, tangentT, 3 2D tex coordinates (80 bytes)
	VERTEX_POSITION | VERTEX_NORMAL | VERTEX_COLOR | VERTEX_SPECULAR | VERTEX_TANGENT_S | VERTEX_TANGENT_T | 
			VERTEX_NUM_TEXCOORDS(3) | 
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2) | 
			VERTEX_TEXCOORD_SIZE(2, 2),

	// Position, normal, tangentS, tangentT, 4 2D tex coordinates (80 bytes)
	VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T | 
			VERTEX_NUM_TEXCOORDS(4) | 
			VERTEX_TEXCOORD_SIZE(0, 2) | VERTEX_TEXCOORD_SIZE(1, 2) | 
			VERTEX_TEXCOORD_SIZE(2, 2) | VERTEX_TEXCOORD_SIZE(3, 2),

	// This must be last
	0
};


//-----------------------------------------------------------------------------
// Shared mesh methods
//-----------------------------------------------------------------------------
class CBaseMeshDX8 : public IMeshDX8
{
public:
	// constructor, destructor
	CBaseMeshDX8();
	virtual ~CBaseMeshDX8();

	// Locks mesh for modifying
	void ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc );
	void ModifyEnd();

	// Sets/gets the vertex format
	virtual void SetVertexFormat( VertexFormat_t format );
	virtual VertexFormat_t GetVertexFormat() const;

	// Sets the material
	virtual void SetMaterial( IMaterial* pMaterial );

	// Uses pre-defined index buffers
	void GenerateSequentialIndexBuffer( unsigned short* pIndexBuffer, int numIndices, int firstVertex );
	void GenerateQuadIndexBuffer( unsigned short* pIndexBuffer, int numIndices, int firstVertex );
	void GeneratePolygonIndexBuffer( unsigned short* pIndexBuffer, int numIndices, int firstVertex );
	void GenerateLineStripIndexBuffer( unsigned short* pIndexMemory, int numIndices, int firstVertex );
	void GenerateLineLoopIndexBuffer( unsigned short* pIndexMemory, int numIndices, int firstVertex );

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

	void SetColorMesh( IMesh *pColorMesh )
	{
		Assert( 0 );
	}

	bool HasColorMesh( ) const { return false; }
	
	// Draws the mesh
	void DrawMesh( );

	// Begins a pass
	void BeginPass( );

	// Spews the mesh data
	void Spew( int numVerts, int numIndices, MeshDesc_t const& desc );

	// Call this in debug mode to make sure our data is good.
	virtual void ValidateData( int numVerts, int numIndices, MeshDesc_t const& desc );

	void Draw( CPrimList *pLists, int nLists );

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

	// returns the primitive type
	virtual MaterialPrimitiveType_t GetPrimitiveType() const = 0;

	// Returns the number of indices in a mesh..
	virtual int NumIndices( ) const = 0;

	// returns a static vertex buffer...
	virtual CVertexBuffer*	GetVertexBuffer() { return 0; }
	virtual CIndexBuffer*	GetIndexBuffer() { return 0; }

	// Do I need to reset the vertex format?
	virtual bool NeedsVertexFormatReset( VertexFormat_t fmt ) const;

	// Do I have enough room?
	virtual bool HasEnoughRoom( int numVerts, int numIndices ) const;

	// Operation to do pre-lock
	virtual void PreLock() {}

	// Sets the software vertex shader
	virtual void SetSoftwareVertexShader( SoftwareVertexShader_t shader ) = 0;

protected:
	bool DebugTrace() const;
	
	// The vertex format we're using...
	VertexFormat_t m_VertexFormat;

#ifdef _DEBUG
	IMaterialInternal* m_pMaterial;
	bool m_IsDrawing;
#endif
};


//-----------------------------------------------------------------------------
// Implementation of the mesh
//-----------------------------------------------------------------------------
class CMeshDX8 : public CBaseMeshDX8
{
public:
	// constructor
	CMeshDX8( );
	virtual ~CMeshDX8();

	// Locks/unlocks the mesh
	void LockMesh( int numVerts, int numIndices, MeshDesc_t& desc );
	void UnlockMesh( int numVerts, int numIndices, MeshDesc_t& desc );

	// Locks mesh for modifying
	void ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc );
	void ModifyEnd();

	// returns the # of vertices (static meshes only)
	int NumVertices() const;

	// returns the # of indices 
	int NumIndices( ) const;

	// Sets up the vertex and index buffers
	void UseIndexBuffer( CIndexBuffer* pBuffer );
	void UseVertexBuffer( CVertexBuffer* pBuffer );

	// returns a static vertex buffer...
	CVertexBuffer*	GetVertexBuffer() { return m_pVertexBuffer; }
	CIndexBuffer*	GetIndexBuffer() { return m_pIndexBuffer; }

	void SetColorMesh( IMesh *pColorMesh );
	bool HasColorMesh( ) const;
	
	// Draws the mesh
	void Draw( int firstIndex, int numIndices );
	void Draw( CPrimList *pLists, int nLists );

	// Draws a single pass
	void RenderPass();

	// Sets the primitive type
	void SetPrimitiveType( MaterialPrimitiveType_t type );
	MaterialPrimitiveType_t GetPrimitiveType() const;

	bool IsStatic() { return true; };

	void SetSoftwareVertexShader( SoftwareVertexShader_t shader );
	void CallSoftwareVertexShader( CMeshBuilder *pMeshBuilder );

protected:
	// Sets the render state.
	bool SetRenderState( int firstVertexIdx = 0 );

	// Is the vertex format valid?
	bool IsValidVertexFormat();

	// Locks/ unlocks the vertex buffer
	void LockVertexBuffer( int numVerts, MeshDesc_t& desc );
	void UnlockVertexBuffer( int numVerts );

	// Locks/unlocks the index buffer
	// Pass in firstIndex=-1 to lock wherever the index buffer is. Pass in a value 
	// >= 0 to specify where to lock.
	int  LockIndexBuffer( int firstIndex, int numIndices, MeshDesc_t& pIndices );
	void UnlockIndexBuffer( int numIndices );

	// Computes the primitive mode
	D3DPRIMITIVETYPE ComputeMode( MaterialPrimitiveType_t mode );

	// computes how many primitives we've got
	int NumPrimitives( int numVerts, int numIndices ) const;

	// Debugging output...
	void SpewMaterialVerts( );

	// The vertex and index buffers
	CVertexBuffer* m_pVertexBuffer;
	CIndexBuffer* m_pIndexBuffer;

	CMeshDX8 *m_pColorMesh;
	
	// Primitive type
	MaterialPrimitiveType_t m_Type;

	// Primitive mode
	D3DPRIMITIVETYPE m_Mode;

	// Number of primitives
	unsigned short m_NumVertices;
	unsigned short m_NumIndices;

	// Is it locked?
	bool	m_IsVBLocked;
	bool	m_IsIBLocked;

	// Used in rendering sub-parts of the mesh
	static CPrimList	*s_pPrims;
	static int			s_nPrims;
	static unsigned int s_FirstVertex;
	static unsigned int s_NumVertices;
	int			m_FirstIndex;

#ifdef RECORDING
	int		m_LockVertexBufferSize;
	void*	m_LockVertexBuffer;
#endif

#if defined( RECORDING ) || defined( CHECK_INDICES )
	void*	m_LockIndexBuffer;
	int		m_LockIndexBufferSize;
#endif

};

//-----------------------------------------------------------------------------
// A little extra stuff for the dynamic version
//-----------------------------------------------------------------------------

class CDynamicMeshDX8 : public CMeshDX8
{
public:
	// constructor, destructor
	CDynamicMeshDX8();
	virtual ~CDynamicMeshDX8();

	// Sets the vertex format
	void SetVertexFormat( VertexFormat_t format );

	// Resets the state in case of a task switch
	void Reset();

	// Do I have enough room in the buffer?
	bool HasEnoughRoom( int numVerts, int numIndices ) const;

	// returns the # of indices
	int NumIndices( ) const;

	// Locks the mesh
	void LockMesh( int numVerts, int numIndices, MeshDesc_t& desc );

	// Unlocks the mesh
	void UnlockMesh( int numVerts, int numIndices, MeshDesc_t& desc );

	// Override vertex + index buffer
	void OverrideVertexBuffer( CVertexBuffer* pStaticVertexBuffer );
	void OverrideIndexBuffer( CIndexBuffer* pStaticIndexBuffer );

	// Do I need to reset the vertex format?
	bool NeedsVertexFormatReset(VertexFormat_t fmt) const;

	// Draws it						   
	void Draw( int firstIndex, int numIndices );

	// Simply draws what's been buffered up immediately, without state change 
	void DrawSinglePassImmediately();

	// Operation to do pre-lock
	void PreLock();

	bool IsStatic() { return false; };

	virtual void SetSoftwareVertexShader( SoftwareVertexShader_t shader );
	
	virtual void CallSoftwareVertexShader( CMeshBuilder *pMeshBuilder );

private:
	// Resets buffering state
	void ResetVertexAndIndexCounts();

	// total queued vertices
	int m_TotalVertices;
	int	m_TotalIndices;

	// the first vertex and index since the last draw
	int m_FirstVertex;
	int m_FirstIndex;

	// Have we drawn since the last lock?
	bool m_HasDrawn;

	// Any overrides?
	bool m_VertexOverride;
	bool m_IndexOverride;

	SoftwareVertexShader_t m_SoftwareVertexShader;
};


//-----------------------------------------------------------------------------
// A mesh that stores temporary vertex data in the correct format (for modification)
//-----------------------------------------------------------------------------

class CTempMeshDX8 : public CBaseMeshDX8
{
public:
	// constructor, destructor
	CTempMeshDX8( bool isDynamic );
	virtual ~CTempMeshDX8();

	// Sets the material
	void SetVertexFormat( VertexFormat_t format );

	// Locks/unlocks the mesh
	void LockMesh( int numVerts, int numIndices, MeshDesc_t& desc );
	void UnlockMesh( int numVerts, int numIndices, MeshDesc_t& desc );

	// Locks mesh for modifying
	virtual void ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc );
	virtual void ModifyEnd();

	// Number of indices + vertices
	int NumVertices() const;
	int NumIndices() const;

	// Sets the primitive type
	void SetPrimitiveType( MaterialPrimitiveType_t type );
	MaterialPrimitiveType_t GetPrimitiveType() const;

	// Begins a pass
	void BeginPass( );

	// Draws a single pass
	void RenderPass();

	// Draws the entire beast
	void Draw( int firstIndex, int numIndices );

	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 );

	virtual void SetSoftwareVertexShader( SoftwareVertexShader_t shader );
	
	virtual void CallSoftwareVertexShader( CMeshBuilder *pMeshBuilder );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -