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

📄 imesh.h

📁 hl2 source code. Do not use it illegal.
💻 H
📖 第 1 页 / 共 3 页
字号:
		Assert( (numVerts & 0x3) == 0 );
		return (numVerts * 6) / 4;
	}
	else if (type == MATERIAL_POLYGON)
	{
		Assert( numVerts >= 3 );
		return (numVerts - 2) * 3;
	}
	else if (type == MATERIAL_LINE_STRIP)
	{
		Assert( numVerts >= 2 );
		return (numVerts - 1) * 2;
	}
	else if (type == MATERIAL_LINE_LOOP)
	{
		Assert( numVerts >= 3 );
		return numVerts * 2;
	}

	return numVerts;
}

//-----------------------------------------------------------------------------
// Begins modifying the mesh
//-----------------------------------------------------------------------------

inline void CMeshBuilder::Begin( IMesh* pMesh, MaterialPrimitiveType_t type, int numPrimitives )
{
	Assert( pMesh && (!m_pMesh) );
	m_pMesh = pMesh;
	m_bModify = false;

	Assert( type != MATERIAL_HETEROGENOUS );

	ComputeNumVertsAndIndices( type, numPrimitives );
	m_NumIndices = 0; m_NumVertices = 0;
	m_GenerateIndices = true;
	m_Type = type;

	if ((type == MATERIAL_QUADS) || (type == MATERIAL_POLYGON))
	{
		m_pMesh->SetPrimitiveType( MATERIAL_TRIANGLES );
	}
	else if ((type == MATERIAL_LINE_STRIP) || (type == MATERIAL_LINE_LOOP))
	{
		m_pMesh->SetPrimitiveType( MATERIAL_LINES );
	}
	else
	{
		m_pMesh->SetPrimitiveType( type );
	}

	// Lock the mesh
	m_pMesh->LockMesh( m_MaxVertices, m_MaxIndices, *this );

	// Point to the start of the index and vertex buffers
	Reset();
}

inline void CMeshBuilder::Begin( IMesh* pMesh, MaterialPrimitiveType_t type, int numVertices, int numIndices )
{
	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_POLYGON) &&
		(type != MATERIAL_LINE_STRIP) && (type != MATERIAL_LINE_LOOP));

	// Dx8 doesn't support indexed points...
	Assert( type != MATERIAL_POINTS );

	m_pMesh = pMesh;
	m_bModify = false;

	// Set the primitive type
	m_pMesh->SetPrimitiveType( type );

	m_MaxVertices = numVertices;
	m_MaxIndices = numIndices;
	m_NumIndices = 0; m_NumVertices = 0;
	m_GenerateIndices = false;
 	m_Type = type;

	// Lock the vertex and index buffer
	m_pMesh->LockMesh( m_MaxVertices, m_MaxIndices, *this );

	// Point to the start of the buffers..
	Reset();
}


//-----------------------------------------------------------------------------
// Use this when you're done modifying the mesh
//-----------------------------------------------------------------------------
inline void CMeshBuilder::End( bool spewData, bool bDraw )
{
	// Make sure they called Begin()
	Assert( !m_bModify );

	if (m_GenerateIndices)
	{
		m_NumIndices = IndicesFromVertices( m_Type, m_NumVertices ); 
		if (m_Type == MATERIAL_QUADS)
		{
			m_pMesh->GenerateQuadIndexBuffer( m_pIndices, m_NumIndices, m_FirstVertex );
		}
		else if (m_Type == MATERIAL_POLYGON)
		{
			m_pMesh->GeneratePolygonIndexBuffer( m_pIndices, m_NumIndices, m_FirstVertex );
		}
		else if (m_Type == MATERIAL_LINE_STRIP)
		{
			m_pMesh->GenerateLineStripIndexBuffer( m_pIndices, m_NumIndices, m_FirstVertex );
		}
		else if (m_Type == MATERIAL_LINE_LOOP)
		{
			m_pMesh->GenerateLineLoopIndexBuffer( m_pIndices, m_NumIndices, m_FirstVertex );
		}
		else if (m_Type != MATERIAL_POINTS)
		{
			m_pMesh->GenerateSequentialIndexBuffer( m_pIndices, m_NumIndices, m_FirstVertex );
		}
	}

	if( m_NumVertices > 0 )
	{
		m_pMesh->CallSoftwareVertexShader( this );
	}
	
	if (spewData)
		m_pMesh->Spew( m_NumVertices, m_NumIndices, *this );
#ifdef _DEBUG
	m_pMesh->ValidateData( m_NumVertices, m_NumIndices, *this );
#endif

	// Unlock our buffers
	m_pMesh->UnlockMesh( m_NumVertices, m_NumIndices, *this );

	if( bDraw )
		m_pMesh->Draw();

	m_pMesh = 0;
	m_MaxVertices = m_MaxIndices = 0;

#ifdef _DEBUG
	// Null out our pointers...
	m_pCurrPosition = NULL;
	m_pCurrNormal = NULL;
	m_pCurrColor = NULL;
	m_pCurrTexCoord[0] = NULL;
	m_pCurrTexCoord[1] = NULL;
	m_pCurrTexCoord[2] = NULL;
	m_pCurrTexCoord[3] = NULL;
	memset( (MeshDesc_t*)this, 0, sizeof(MeshDesc_t) );
#endif
}


//-----------------------------------------------------------------------------
// Locks the vertex buffer to modify existing data
//-----------------------------------------------------------------------------

inline void CMeshBuilder::BeginModify( IMesh* pMesh, int firstVertex, int numVertices, int firstIndex, int numIndices )
{
	Assert( pMesh && (!m_pMesh) );

	if (numVertices < 0)
		numVertices = pMesh->NumVertices();
	
	m_pMesh = pMesh;
	m_MaxVertices = m_NumVertices = numVertices;
	m_MaxIndices = m_NumIndices = numIndices;
	m_GenerateIndices = false;
	m_bModify = true;

	// Locks mesh for modifying
	pMesh->ModifyBegin( firstVertex, numVertices, firstIndex, numIndices, *this );

	// Point to the start of the buffers..
	Reset();
}

inline void CMeshBuilder::EndModify( bool spewData )
{
	Assert( m_pMesh );
	Assert( m_bModify );	// Make sure they called BeginModify.

	if (spewData)
		m_pMesh->Spew( m_NumVertices, m_NumIndices, *this );
#ifdef _DEBUG
	m_pMesh->ValidateData( m_NumVertices, m_NumIndices, *this );
#endif

	// Unlocks mesh
	m_pMesh->ModifyEnd( );
	m_pMesh = 0;
	m_MaxVertices = m_MaxIndices = 0;

#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_CurrentVertex = 0;
	m_CurrentIndex = 0;

	m_pCurrPosition = m_pPosition;
	m_pCurrNormal = m_pNormal;
	m_pCurrTexCoord[0] = m_pTexCoord[0];
	m_pCurrTexCoord[1] = m_pTexCoord[1];
	m_pCurrTexCoord[2] = m_pTexCoord[2];
	m_pCurrTexCoord[3] = m_pTexCoord[3];
	m_pCurrColor = m_pColor;
}


//-----------------------------------------------------------------------------
// returns a float 
//-----------------------------------------------------------------------------
inline float const* CMeshBuilder::OffsetFloatPointer( float const* pBufferPointer, int numVerts, int vertexSize ) const
{
	return reinterpret_cast<float const*>(
		reinterpret_cast<unsigned char const*>(pBufferPointer) + 
		numVerts * vertexSize);
}

inline float* CMeshBuilder::OffsetFloatPointer( float* pBufferPointer, int numVerts, int vertexSize )
{
	return reinterpret_cast<float*>(
		reinterpret_cast<unsigned char*>(pBufferPointer) + 
		numVerts * vertexSize);
}

inline void CMeshBuilder::IncrementFloatPointer( float* &pBufferPointer, int vertexSize )
{
	pBufferPointer = reinterpret_cast<float*>( reinterpret_cast<unsigned char*>(pBufferPointer) + vertexSize );
}


//-----------------------------------------------------------------------------
// Selects the current Vertex and Index 
//-----------------------------------------------------------------------------
inline void CMeshBuilder::SelectVertex( int idx )
{
	// NOTE: This index is expected to be relative 
	Assert( (idx >= 0) && (idx < m_MaxVertices) );
	m_CurrentVertex = idx;

	m_pCurrPosition = OffsetFloatPointer( m_pPosition, m_CurrentVertex, m_VertexSize_Position );
	m_pCurrNormal = OffsetFloatPointer( m_pNormal, m_CurrentVertex, m_VertexSize_Normal );
	m_pCurrTexCoord[0] = OffsetFloatPointer( m_pTexCoord[0], m_CurrentVertex, m_VertexSize_TexCoord[0] );
	m_pCurrTexCoord[1] = OffsetFloatPointer( m_pTexCoord[1], m_CurrentVertex, m_VertexSize_TexCoord[1] );
	m_pCurrTexCoord[2] = OffsetFloatPointer( m_pTexCoord[2], m_CurrentVertex, m_VertexSize_TexCoord[2] );
	m_pCurrTexCoord[3] = OffsetFloatPointer( m_pTexCoord[3], m_CurrentVertex, m_VertexSize_TexCoord[3] );
	m_pCurrColor = m_pColor + m_CurrentVertex * m_VertexSize_Color;
}

inline void CMeshBuilder::SelectVertexFromIndex( int idx )
{
	// NOTE: This index is expected to be relative 
	int vertIdx = idx - m_FirstVertex;
	SelectVertex( vertIdx );
}

inline void CMeshBuilder::SelectIndex( int idx )
{
	Assert( (idx >= 0) && (idx < m_NumIndices) );
	m_CurrentIndex = idx;
}


//-----------------------------------------------------------------------------
// Advances the current vertex and index by one
//-----------------------------------------------------------------------------
inline void CMeshBuilder::AdvanceVertex()
{
	if (++m_CurrentVertex > m_NumVertices)
		m_NumVertices = m_CurrentVertex;
	
	IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position );
	IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal );
	IncrementFloatPointer( m_pCurrTexCoord[0], m_VertexSize_TexCoord[0] );
	IncrementFloatPointer( m_pCurrTexCoord[1], m_VertexSize_TexCoord[1] );
	IncrementFloatPointer( m_pCurrTexCoord[2], m_VertexSize_TexCoord[2] );
	IncrementFloatPointer( m_pCurrTexCoord[3], m_VertexSize_TexCoord[3] );
	m_pCurrColor += m_VertexSize_Color;
}

inline void CMeshBuilder::AdvanceVertices( int nVerts )
{
	m_CurrentVertex += nVerts;
	if (m_CurrentVertex > m_NumVertices)
		m_NumVertices = m_CurrentVertex;
	
	IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position*nVerts );
	IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal*nVerts );
	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 );
	m_pCurrColor += m_VertexSize_Color*nVerts;
}

inline void CMeshBuilder::AdvanceIndex()
{
	if (++m_CurrentIndex > m_NumIndices)
		m_NumIndices = m_CurrentIndex; 
}

inline void CMeshBuilder::AdvanceIndices( int nIndices )
{
	m_CurrentIndex += nIndices;
	if (m_CurrentIndex > m_NumIndices)
		m_NumIndices = m_CurrentIndex; 
}

inline int CMeshBuilder::GetCurrentVertex()
{
	return m_CurrentVertex;
}

inline int CMeshBuilder::GetCurrentIndex()
{
	return m_CurrentIndex;
}


//-----------------------------------------------------------------------------
// A helper method since this seems to be done a whole bunch.
//-----------------------------------------------------------------------------
inline void CMeshBuilder::DrawQuad( IMesh* pMesh, float const* v1, float const* v2, 
	float const* v3, float const* v4, unsigned char const* pColor, bool wireframe )
{
	if (!wireframe)
	{
		Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );

		Position3fv (v1);
		Color4ubv( pColor );
		AdvanceVertex();

		Position3fv (v2);
		Color4ubv( pColor );
		AdvanceVertex();

		Position3fv (v4);
		Color4ubv( pColor );
		AdvanceVertex();

		Position3fv (v3);
		Color4ubv( pColor );
		AdvanceVertex();
	}
	else
	{
		Begin( pMesh, MATERIAL_LINE_LOOP, 4 );
		Position3fv (v1);
		Color4ubv( pColor );
		AdvanceVertex();

		Position3fv (v2);
		Color4ubv( pColor );
		AdvanceVertex();

		Position3fv (v3);
		Color4ubv( pColor );
		AdvanceVertex();

		Position3fv (v4);
		Color4ubv( pColor );
		AdvanceVertex();
	}

	End();
	pMesh->Draw();
}


//-----------------------------------------------------------------------------
// returns the number of indices and vertices
//-----------------------------------------------------------------------------

inline int CMeshBuilder::NumVertices() const
{
	return m_NumVertices;
}

inline int CMeshBuilder::NumIndices() const
{
	return m_NumIndices;
}

	
//-----------------------------------------------------------------------------
// Returns the base vertex memory pointer
//-----------------------------------------------------------------------------

inline void* CMeshBuilder::BaseVertexData()
{
	// FIXME: If there's no position specified, we need to find
	// the base address 
	Assert( m_pPosition );
	return m_pPosition;
}


//-----------------------------------------------------------------------------
// Data retrieval...
//-----------------------------------------------------------------------------
inline float const* CMeshBuilder::Position( ) const
{
	Assert( m_CurrentVertex < m_MaxVertices );
	return m_pCurrPosition;
}

inline float const* CMeshBuilder::Normal( )	const
{
	Assert( m_CurrentVertex < m_MaxVertices );
	return m_pCurrNormal;
}

inline unsigned int CMeshBuilder::Color( ) const
{
	// Swizzle it so it returns the same format as accepted by Color4ubv
	Assert( m_CurrentVertex < m_MaxVertices );
	return (m_pCurrColor[0] << 16) | (m_pCurrColor[1] << 8) | (m_pCurrColor[2]) | (m_pCurrColor[3] << 24);
}

inline float const* CMeshBuilder::TexCoord( int stage ) const
{
	Assert( m_CurrentVertex < m_MaxVertices );
	return m_pCurrTexCoord[stage];
}

inline float const* CMeshBuilder::TangentS( ) const
{
	Assert( m_CurrentVertex < m_MaxVertices );

⌨️ 快捷键说明

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