📄 meshdx8.cpp
字号:
int i;
for( i = 0; i < 2; i++ )
{
CVertexBuffer *pMesh;
if( i == 0 )
{
pMesh = g_pLastVertex;
Assert( pMesh );
}
else
{
if( !g_pLastColorMesh )
{
continue;
}
pMesh = g_pLastColorMesh->m_pVertexBuffer;
if( !pMesh )
{
continue;
}
}
Assert( s_FirstVertex >= 0 &&
s_FirstVertex + m_FirstIndex < pMesh->VertexCount() );
int numIndices = 0;
if( m_Mode == D3DPT_TRIANGLELIST )
{
numIndices = numPrimitives * 3;
}
else if( m_Mode == D3DPT_TRIANGLESTRIP )
{
numIndices = numPrimitives + 2;
}
else
{
Assert( 0 );
}
int j;
for( j = 0; j < numIndices; j++ )
{
int index = g_pLastIndex->GetShadowIndex( j + pPrim->m_FirstIndex );
Assert( index >= s_FirstVertex );
Assert( index < s_FirstVertex + s_NumVertices );
}
}
#endif // CHECK_INDICES
RECORD_COMMAND( DX8_DRAW_INDEXED_PRIMITIVE, 6 );
RECORD_INT( m_Mode );
RECORD_INT( s_FirstVertex );
RECORD_INT( m_FirstIndex );
RECORD_INT( s_NumVertices );
RECORD_INT( pPrim->m_FirstIndex );
RECORD_INT( numPrimitives );
MaterialSystemStats()->IncrementCountedStat(MATERIAL_SYSTEM_STATS_NUM_PRIMITIVES, numPrimitives );
{
VPROF( "D3DDevice()->DrawIndexedPrimitive" );
hr = D3DDevice()->DrawIndexedPrimitive( m_Mode, m_FirstIndex, s_FirstVertex,
s_NumVertices, pPrim->m_FirstIndex, numPrimitives );
}
}
Assert( !FAILED(hr) );
}
MaterialSystemStats()->IncrementCountedStat(MATERIAL_SYSTEM_STATS_NUM_INDEX_PRIMITIVE_CALLS, 1 );
}
void CMeshDX8::CallSoftwareVertexShader( CMeshBuilder *pMeshBuilder )
{
}
void CMeshDX8::SetSoftwareVertexShader( SoftwareVertexShader_t shader )
{
Assert( 0 );
}
//-----------------------------------------------------------------------------
//
// Dynamic mesh implementation
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
CDynamicMeshDX8::CDynamicMeshDX8()
{
ResetVertexAndIndexCounts();
}
CDynamicMeshDX8::~CDynamicMeshDX8()
{
}
//-----------------------------------------------------------------------------
// Resets buffering state
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::ResetVertexAndIndexCounts()
{
m_TotalVertices = m_TotalIndices = 0;
m_FirstIndex = m_FirstVertex = -1;
m_HasDrawn = 0;
}
//-----------------------------------------------------------------------------
// Resets the state in case of a task switch
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::Reset()
{
m_VertexFormat = 0;
m_pVertexBuffer = 0;
m_pIndexBuffer = 0;
ResetVertexAndIndexCounts();
// Force the render state to be updated next time
ResetRenderState();
}
//-----------------------------------------------------------------------------
// Sets the material associated with the dynamic mesh
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::SetVertexFormat( VertexFormat_t format )
{
if (ShaderAPI()->IsDeactivated())
return;
if ((format != m_VertexFormat) || m_VertexOverride || m_IndexOverride)
{
m_VertexFormat = format;
UseVertexBuffer( g_MeshMgr.FindOrCreateVertexBuffer( format ) );
UseIndexBuffer( g_MeshMgr.GetDynamicIndexBuffer() );
m_VertexOverride = m_IndexOverride = false;
}
}
void CDynamicMeshDX8::OverrideVertexBuffer( CVertexBuffer* pVertexBuffer )
{
UseVertexBuffer( pVertexBuffer );
m_VertexOverride = true;
}
void CDynamicMeshDX8::OverrideIndexBuffer( CIndexBuffer* pIndexBuffer )
{
UseIndexBuffer( pIndexBuffer );
m_IndexOverride = true;
}
//-----------------------------------------------------------------------------
// Do I need to reset the vertex format?
//-----------------------------------------------------------------------------
bool CDynamicMeshDX8::NeedsVertexFormatReset( VertexFormat_t fmt ) const
{
return m_VertexOverride || m_IndexOverride || (m_VertexFormat != fmt);
}
//-----------------------------------------------------------------------------
// Locks/unlocks the entire mesh
//-----------------------------------------------------------------------------
bool CDynamicMeshDX8::HasEnoughRoom( int numVerts, int numIndices ) const
{
if (ShaderAPI()->IsDeactivated())
return false;
// We need space in both the vertex and index buffer
return m_pVertexBuffer->HasEnoughRoom( numVerts ) &&
m_pIndexBuffer->HasEnoughRoom( numIndices );
}
//-----------------------------------------------------------------------------
// returns the number of indices in the mesh
//-----------------------------------------------------------------------------
int CDynamicMeshDX8::NumIndices( ) const
{
return m_TotalIndices;
}
//-----------------------------------------------------------------------------
// Operation to do pre-lock (only called for buffered meshes)
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::PreLock()
{
if (m_HasDrawn)
{
// Start again then
ResetVertexAndIndexCounts();
}
}
//-----------------------------------------------------------------------------
// Locks/unlocks the entire mesh
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::LockMesh( int numVerts, int numIndices, MeshDesc_t& desc )
{
#ifdef MEASURE_STATS
MaterialSystemStats()->BeginTimedStat(MATERIAL_SYSTEM_STATS_MESH_BUILD_TIME);
#endif
// Yes, this may well also be called from BufferedMesh but that's ok
PreLock();
if (m_VertexOverride)
numVerts = 0;
if (m_IndexOverride)
numIndices = 0;
LockVertexBuffer( numVerts, desc );
if (m_FirstVertex < 0)
m_FirstVertex = desc.m_FirstVertex;
// When we're using a static index buffer, the indices assume vertices start at 0
if (m_IndexOverride)
desc.m_FirstVertex -= m_FirstVertex;
// Don't add indices for points; DrawIndexedPrimitive not supported for them.
if (m_Type != MATERIAL_POINTS)
{
int firstIndex = LockIndexBuffer( -1, numIndices, desc );
if (m_FirstIndex < 0)
m_FirstIndex = firstIndex;
}
else
{
desc.m_pIndices = 0;
}
}
//-----------------------------------------------------------------------------
// Unlocks the mesh
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::UnlockMesh( int numVerts, int numIndices, MeshDesc_t& desc )
{
m_TotalVertices += numVerts;
m_TotalIndices += numIndices;
if (DebugTrace())
Spew( numVerts, numIndices, desc );
CMeshDX8::UnlockMesh( numVerts, numIndices, desc );
}
//-----------------------------------------------------------------------------
// Draws it
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::Draw( int firstIndex, int numIndices )
{
VPROF( "CDynamicMeshDX8::Draw" );
if ( ShaderUtil()->IsInStubMode() )
return;
m_HasDrawn = true;
if (m_IndexOverride || m_VertexOverride ||
((m_TotalVertices > 0) && (m_TotalIndices > 0)) )
{
Assert( !m_IsDrawing );
// only have a non-zero first vertex when we are using static indices
int firstVertex = m_VertexOverride ? 0 : m_FirstVertex;
int actualFirstVertex = m_IndexOverride ? firstVertex : 0;
int baseIndex = m_IndexOverride ? 0 : m_FirstIndex;
if (!SetRenderState(actualFirstVertex))
return;
// Draws a portion of the mesh
int numVertices = m_VertexOverride ? m_pVertexBuffer->VertexCount() :
m_TotalVertices;
if ((firstIndex != -1) && (numIndices != 0))
{
firstIndex += baseIndex;
}
else
{
// by default we draw the whole thing
firstIndex = baseIndex;
if( m_IndexOverride )
{
numIndices = m_pIndexBuffer->IndexCount();
Assert( numIndices != 0 );
}
else
{
numIndices = m_TotalIndices;
Assert( numIndices != 0 );
}
}
// Fix up firstVertex to indicate the first vertex used in the data
actualFirstVertex = firstVertex - actualFirstVertex;
s_FirstVertex = actualFirstVertex;
s_NumVertices = numVertices;
// Build a primlist with 1 element..
CPrimList prim;
prim.m_FirstIndex = firstIndex;
prim.m_NumIndices = numIndices;
Assert( numIndices != 0 );
s_pPrims = &prim;
s_nPrims = 1;
DrawMesh();
s_pPrims = NULL;
}
}
//-----------------------------------------------------------------------------
// This is useful when we need to dynamically modify data; just set the
// render state and draw the pass immediately
//-----------------------------------------------------------------------------
void CDynamicMeshDX8::DrawSinglePassImmediately()
{
if ((m_TotalVertices > 0) || (m_TotalIndices > 0))
{
Assert( !m_IsDrawing );
// Set the render state
if (SetRenderState(0))
{
s_FirstVertex = m_FirstVertex;
s_NumVertices = m_TotalVertices;
// Make a temporary PrimList to hold the indices.
CPrimList prim( m_FirstIndex, m_TotalIndices );
Assert( m_TotalIndices != 0 );
s_pPrims = &prim;
s_nPrims = 1;
// Render it
RenderPass();
}
// We're done with our data
ResetVertexAndIndexCounts();
}
}
void CDynamicMeshDX8::CallSoftwareVertexShader( CMeshBuilder *pMeshBuilder )
{
if( m_SoftwareVertexShader )
{
pMeshBuilder->Reset();
IMaterialInternal *pMaterial = ShaderAPI()->GetBoundMaterial();
Assert( pMaterial );
#ifdef _DEBUG
// const char *matName = pMaterial->GetName();
#endif
m_SoftwareVertexShader( *pMeshBuilder, pMaterial->GetShaderParams(), ShaderAPI() );
}
}
void CDynamicMeshDX8::SetSoftwareVertexShader( SoftwareVertexShader_t shader )
{
m_SoftwareVertexShader = shader;
}
//-----------------------------------------------------------------------------
//
// A mesh that stores temporary vertex data in the correct format (for modification)
//
//-----------------------------------------------------------------------------
// Used in rendering sub-parts of the mesh
unsigned int CTempMeshDX8::s_NumIndices;
unsigned int CTempMeshDX8::s_FirstIndex;
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
CTempMeshDX8::CTempMeshDX8( bool isDynamic ) : m_VertexSize(0xFFFF), m_IsDynamic(isDynamic)
{
#ifdef _DEBUG
m_Locked = false;
m_InPass = false;
#endif
}
CTempMeshDX8::~CTempMeshDX8()
{
}
//-----------------------------------------------------------------------------
// Sets the material
//-----------------------------------------------------------------------------
void CTempMeshDX8::SetVertexFormat( VertexFormat_t format )
{
CBaseMeshDX8::SetVertexFormat(format);
m_VertexSize = g_MeshMgr.VertexFormatSize( format );
}
//-----------------------------------------------------------------------------
// returns the # of vertices (static meshes only)
//-----------------------------------------------------------------------------
int CTempMeshDX8::NumVertices() const
{
return m_VertexSize ? m_VertexData.Size() / m_VertexSize : 0;
}
//-----------------------------------------------------------------------------
// returns the # of indices
//-----------------------------------------------------------------------------
int CTempMeshDX8::NumIndices( ) const
{
return m_IndexData.Size();
}
void CTempMeshDX8::ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc )
{
Assert( !m_Locked );
m_LockedVerts = numVerts;
m_LockedIndices = numIndices;
if( numVerts > 0 )
{
int vertexByteOffset = m_VertexSize * firstVertex;
// Lock it baby
unsigned char* pVertexMemory = &m_VertexData[vertexByteOffset];
// Compute the vertex index..
desc.m_FirstVertex = vertexByteOffset / m_VertexSize;
// Set up the mesh descriptor
g_MeshMgr.ComputeVertexDescription( pVertexMemory, m_VertexFormat, desc );
}
else
{
desc.m_FirstVertex = 0;
// Set up the mesh descriptor
g_MeshMgr.ComputeVertexDescription( 0, 0, desc );
}
if (m_Type != MATERIAL_POINTS && numIndices > 0 )
{
desc.m_pIndices = &m_Index
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -