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

📄 meshdx8.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Locks/unlocks the entire mesh
//-----------------------------------------------------------------------------

void CMeshDX8::LockMesh( int numVerts, int numIndices, MeshDesc_t& desc )
{
#ifdef MEASURE_STATS
	MaterialSystemStats()->BeginTimedStat(MATERIAL_SYSTEM_STATS_MESH_BUILD_TIME);
#endif

	LockVertexBuffer( numVerts, desc );
	if (m_Type != MATERIAL_POINTS)
		LockIndexBuffer( -1, numIndices, desc );
	else
		desc.m_pIndices = 0;
}

void CMeshDX8::UnlockMesh( int numVerts, int numIndices, MeshDesc_t& desc )
{
	UnlockVertexBuffer(numVerts);
	if (m_Type != MATERIAL_POINTS)
		UnlockIndexBuffer(numIndices);
																	    
	// The actual # we wrote
	m_NumVertices = numVerts;
	m_NumIndices = numIndices;

#ifdef MEASURE_STATS
	MaterialSystemStats()->EndTimedStat(MATERIAL_SYSTEM_STATS_MESH_BUILD_TIME);
#endif
}

 
//-----------------------------------------------------------------------------
// Locks mesh for modifying
//-----------------------------------------------------------------------------

void CMeshDX8::ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc )
{
#ifdef MEASURE_STATS
	MaterialSystemStats()->BeginTimedStat(MATERIAL_SYSTEM_STATS_MESH_BUILD_TIME);
#endif

	// Just give the app crap buffers to fill up while we're suppressed...
	if (ShaderAPI()->IsDeactivated())
	{
		// Set up a bogus descriptor
		g_MeshMgr.ComputeVertexDescription( 0, 0, desc );
		desc.m_pIndices = 0;
		return;
	}

	Assert( m_pVertexBuffer );

	// Lock it baby
	unsigned char* pVertexMemory = m_pVertexBuffer->Modify( firstVertex, numVerts );
	if ( pVertexMemory )
	{
		m_IsVBLocked = true;
		g_MeshMgr.ComputeVertexDescription( pVertexMemory, m_VertexFormat, desc );

#ifdef RECORDING
		m_LockVertexBufferSize = numVerts * desc.m_ActualVertexSize;
		m_LockVertexBuffer = pVertexMemory;
#endif
	}

	desc.m_FirstVertex = firstVertex;

	LockIndexBuffer( firstIndex, numIndices, desc );
}

void CMeshDX8::ModifyEnd( )
{
	UnlockIndexBuffer(0);
	UnlockVertexBuffer(0);

#ifdef MEASURE_STATS
	MaterialSystemStats()->EndTimedStat(MATERIAL_SYSTEM_STATS_MESH_BUILD_TIME);
#endif
}

//-----------------------------------------------------------------------------
// returns the # of vertices (static meshes only)
//-----------------------------------------------------------------------------

int CMeshDX8::NumVertices() const
{
	return m_pVertexBuffer ? m_pVertexBuffer->VertexCount() : 0;
}

//-----------------------------------------------------------------------------
// returns the # of indices 
//-----------------------------------------------------------------------------

int CMeshDX8::NumIndices( ) const
{
	return m_pIndexBuffer ? m_pIndexBuffer->IndexCount() : 0;
}

//-----------------------------------------------------------------------------
// Sets up the vertex and index buffers
//-----------------------------------------------------------------------------

void CMeshDX8::UseIndexBuffer( CIndexBuffer* pBuffer )
{
	m_pIndexBuffer = pBuffer;
}

void CMeshDX8::UseVertexBuffer( CVertexBuffer* pBuffer )
{
	m_pVertexBuffer = pBuffer;
}


//-----------------------------------------------------------------------------
// Computes the mode
//-----------------------------------------------------------------------------

D3DPRIMITIVETYPE CMeshDX8::ComputeMode( MaterialPrimitiveType_t type )
{
	switch(type)
	{
	case MATERIAL_POINTS:
		return D3DPT_POINTLIST;
		
	case MATERIAL_LINES:
		return D3DPT_LINELIST;

	case MATERIAL_TRIANGLES:
		return D3DPT_TRIANGLELIST;

	case MATERIAL_TRIANGLE_STRIP:
		return D3DPT_TRIANGLESTRIP;

	// Here, we expect to have the type set later. only works for static meshes
	case MATERIAL_HETEROGENOUS:
		return (D3DPRIMITIVETYPE)-1;

	default:
		Assert(0);
		return (D3DPRIMITIVETYPE)-1;
	}
}

//-----------------------------------------------------------------------------
// Sets the primitive type
//-----------------------------------------------------------------------------

void CMeshDX8::SetPrimitiveType( MaterialPrimitiveType_t type )
{
	m_Type = type;
	m_Mode = ComputeMode( type );
}

MaterialPrimitiveType_t CMeshDX8::GetPrimitiveType( ) const
{
	return m_Type;
}


//-----------------------------------------------------------------------------
// Computes the number of primitives we're gonna draw
//-----------------------------------------------------------------------------

int CMeshDX8::NumPrimitives( int numVerts, int numIndices ) const
{
	switch(m_Mode)
	{
	case D3DPT_POINTLIST:
		return numVerts;
		
	case D3DPT_LINELIST:
		return numIndices / 2;

	case D3DPT_TRIANGLELIST:
		return numIndices / 3;

	case D3DPT_TRIANGLESTRIP:
		return numIndices - 2;

	default:
		// invalid, baby!
		Assert(0);
	}

	return 0;
}


//-----------------------------------------------------------------------------
// Checks if it's a valid format
//-----------------------------------------------------------------------------

static void OutputVertexFormat( VertexFormat_t format )
{
	if( format & VERTEX_POSITION )
	{
		Warning( "VERTEX_POSITION|" );
	}
	if( format & VERTEX_NORMAL )
	{
		Warning( "VERTEX_NORMAL|" );
	}
	if( format & VERTEX_COLOR )
	{
		Warning( "VERTEX_COLOR|" );
	}
	if( format & VERTEX_SPECULAR )
	{
		Warning( "VERTEX_SPECULAR|" );
	}
	if( format & VERTEX_TANGENT_S )
	{
		Warning( "VERTEX_TANGENT_S|" );
	}
	if( format & VERTEX_TANGENT_T )
	{
		Warning( "VERTEX_TANGENT_T|" );
	}
	if( format & VERTEX_BONE_INDEX )
	{
		Warning( "VERTEX_BONE_INDEX|" );
	}
	if( format & VERTEX_FORMAT_VERTEX_SHADER )
	{
		Warning( "VERTEX_FORMAT_VERTEX_SHADER|" );
	}
	Warning( "Bone weights: %d\n", 
		( int )( ( format & VERTEX_BONE_WEIGHT_MASK ) >> VERTEX_BONE_WEIGHT_BIT ) );
	Warning( "user data size: %d\n", 
		( int )( ( format & USER_DATA_SIZE_MASK ) >> USER_DATA_SIZE_BIT ) );
	Warning( "num tex coords: %d\n", 
		( int )( ( format & NUM_TEX_COORD_MASK ) >> NUM_TEX_COORD_BIT ) );
	// NOTE: This doesn't print texcoord sizes.
}

bool CMeshDX8::IsValidVertexFormat()
{
	IMaterialInternal* pMaterial = ShaderAPI()->GetBoundMaterial();
	Assert( pMaterial );

	VertexFormat_t fmt = pMaterial->GetVertexFormat() & ~VERTEX_FORMAT_VERTEX_SHADER;
	bool isValid = (fmt == (m_VertexFormat  & ~VERTEX_FORMAT_VERTEX_SHADER));
#ifdef _DEBUG
	if( !isValid )
	{
		Warning( "material format:" );
		OutputVertexFormat( fmt );
		Warning( "mesh format:" );
		OutputVertexFormat( m_VertexFormat );
	}
#endif
	return isValid;
}


//-----------------------------------------------------------------------------
// Flushes queued data
//-----------------------------------------------------------------------------
static CIndexBuffer* g_pLastIndex = 0;
static CVertexBuffer* g_pLastVertex = 0;
static int g_LastVertexIdx = -1;
static CMeshDX8 *g_pLastColorMesh = 0;


//-----------------------------------------------------------------------------
// Makes sure that the render state is always set next time
//-----------------------------------------------------------------------------
static void ResetRenderState()
{
	g_pLastIndex = 0;
	g_pLastVertex = 0;
	g_LastVertexIdx = -1;
}

bool CMeshDX8::SetRenderState( int firstVertexIdx )
{
	MEASURE_TIMED_STAT( MATERIAL_SYSTEM_STATS_SET_RENDER_STATE );

	// Can't set the state if we're deactivated
	if (ShaderAPI()->IsDeactivated())
	{
		ResetRenderState();
		return false;
	}

	// make sure the vertex format is a superset of the current material's
	// vertex format...
	if (!IsValidVertexFormat())
	{
		Warning("Material %s is being applied to a model, you need $model=1 in the .vmt file!\n",
			ShaderAPI()->GetBoundMaterial()->GetName() );
		return false;
	}

	if( m_pColorMesh != g_pLastColorMesh )
	{
		HRESULT hr;
		if( m_pColorMesh )
		{
			RECORD_COMMAND( DX8_SET_STREAM_SOURCE, 3 );
			RECORD_INT( m_pColorMesh->GetVertexBuffer()->UID() );
			RECORD_INT( 1 );
			RECORD_INT( m_pColorMesh->GetVertexBuffer()->VertexSize() );

			hr = D3DDevice()->SetStreamSource( 1, 
				m_pColorMesh->GetVertexBuffer()->GetInterface(), 
				0, 
				m_pColorMesh->GetVertexBuffer()->VertexSize() );
		}
		else
		{
			RECORD_COMMAND( DX8_SET_STREAM_SOURCE, 3 );
			RECORD_INT( -1 );	// vertex buffer id
			RECORD_INT( 1 );	// stream
			RECORD_INT( 0 );	// vertex size

			hr = D3DDevice()->SetStreamSource( 1, 0, 0, 0 );
		}
		Assert( !FAILED(hr) );
		g_pLastColorMesh = m_pColorMesh;
	}

	if (g_pLastVertex != m_pVertexBuffer)
	{
		Assert( m_pVertexBuffer );

		RECORD_COMMAND( DX8_SET_STREAM_SOURCE, 3 );
		RECORD_INT( m_pVertexBuffer->UID() );
		RECORD_INT( 0 );
		RECORD_INT( m_pVertexBuffer->VertexSize() );

		HRESULT hr;
		hr = D3DDevice()->SetStreamSource( 0, 
			m_pVertexBuffer->GetInterface(), 0, m_pVertexBuffer->VertexSize() );
		Assert( !FAILED(hr) );

		MaterialSystemStats()->IncrementCountedStat(MATERIAL_SYSTEM_STATS_DYNAMIC_STATE, 1 );

		g_pLastVertex = m_pVertexBuffer;
	}


	if ((g_pLastIndex != m_pIndexBuffer) || (firstVertexIdx != g_LastVertexIdx))
	{
		Assert( m_pIndexBuffer );

		RECORD_COMMAND( DX8_SET_INDICES, 2 );
		RECORD_INT( m_pIndexBuffer->UID() );
		RECORD_INT( firstVertexIdx );

		HRESULT hr;
		hr = D3DDevice()->SetIndices( m_pIndexBuffer->GetInterface() );
		m_FirstIndex = firstVertexIdx;
		Assert( !FAILED(hr) );

		MaterialSystemStats()->IncrementCountedStat(MATERIAL_SYSTEM_STATS_DYNAMIC_STATE, 1 );

		g_pLastIndex = m_pIndexBuffer;
		g_LastVertexIdx = firstVertexIdx;
	}

	return true;
}

//-----------------------------------------------------------------------------
// Draws the static mesh
//-----------------------------------------------------------------------------

void CMeshDX8::Draw( int firstIndex, int numIndices )
{
	if ( ShaderUtil()->IsInStubMode() )
		return;

	CPrimList primList;
	if( firstIndex == -1 || numIndices == 0 )
	{
		primList.m_FirstIndex = 0;
		primList.m_NumIndices = m_NumIndices;
	}
	else
	{
		primList.m_FirstIndex = firstIndex;
		primList.m_NumIndices = numIndices;
	}
	Draw( &primList, 1 );
}


void CMeshDX8::Draw( CPrimList *pLists, int nLists )
{
	if ( ShaderUtil()->IsInStubMode() )
		return;

	// Make sure there's something to draw..
	int i;
	for( i=0; i < nLists; i++ )
	{
		if( pLists[i].m_NumIndices > 0 )
			break;
	}
	if( i == nLists )
		return;

	// can't do these in selection mode!
	Assert( !ShaderAPI()->IsInSelectionMode() );

	if (!SetRenderState(0))
		return;

	s_pPrims = pLists;
	s_nPrims = nLists;

#ifdef _DEBUG
	for ( i = 0; i < nLists; ++i)
	{
		Assert( pLists[i].m_NumIndices > 0 );
	}
#endif

	s_FirstVertex = 0;
	s_NumVertices = m_pVertexBuffer->VertexCount();

	DrawMesh();
}

//-----------------------------------------------------------------------------
// Actually does the dirty deed of rendering
//-----------------------------------------------------------------------------

void CMeshDX8::RenderPass()
{
	VPROF( "CMeshDX8::RenderPass" );
	MEASURE_TIMED_STAT( MATERIAL_SYSTEM_STATS_DRAW_INDEXED_PRIMITIVE );

	HRESULT hr;
	Assert( m_Type != MATERIAL_HETEROGENOUS );

	for( int iPrim=0; iPrim < s_nPrims; iPrim++ )
	{
		CPrimList *pPrim = &s_pPrims[iPrim];

		if (pPrim->m_NumIndices == 0)
			continue;

		if (m_Type == MATERIAL_POINTS)
		{
			RECORD_COMMAND( DX8_DRAW_PRIMITIVE, 3 );
			RECORD_INT( m_Mode );
			RECORD_INT(	s_FirstVertex );
			RECORD_INT( pPrim->m_NumIndices );

			// (For point lists, we don't actually fill in indices, but we treat it as
			// though there are indices for the list up until here).
			hr = D3DDevice()->DrawPrimitive( m_Mode, s_FirstVertex, pPrim->m_NumIndices );
			MaterialSystemStats()->IncrementCountedStat(MATERIAL_SYSTEM_STATS_NUM_PRIMITIVES, pPrim->m_NumIndices );
		}
		else
		{
			int numPrimitives = NumPrimitives( s_NumVertices, pPrim->m_NumIndices );

#ifdef CHECK_INDICES_NOT_RIGHT_NOW_NO_LINELIST_SUPPORT_WHICH_MAKES_THIS_PAINFUL_FOR_DEBUG_MODE
			// g_pLastVertex - this is the current vertex buffer
			// g_pLastColorMesh - this is the curent color mesh, if there is one.
			// g_pLastIndex - this is the current index buffer.
			// vertoffset : m_FirstIndex
			Assert( m_Mode == D3DPT_TRIANGLELIST || m_Mode == D3DPT_TRIANGLESTRIP );
			Assert( pPrim->m_FirstIndex >= 0 && pPrim->m_FirstIndex < g_pLastIndex->IndexCount() );

⌨️ 快捷键说明

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