📄 meshdx8.cpp
字号:
Assert(0);
}
//-----------------------------------------------------------------------------
// Begins a pass
//-----------------------------------------------------------------------------
void CBaseMeshDX8::BeginPass( )
{
}
//-----------------------------------------------------------------------------
// Sets the render state and gets the drawing going
//-----------------------------------------------------------------------------
inline void CBaseMeshDX8::DrawMesh( )
{
MEASURE_TIMED_STAT( MATERIAL_SYSTEM_STATS_DRAW_MESH );
#ifdef _DEBUG
// Make sure we're not drawing...
Assert( !m_IsDrawing );
m_IsDrawing = true;
#endif
// This is going to cause RenderPass to get called a bunch
ShaderAPI()->DrawMesh( this );
#ifdef _DEBUG
m_IsDrawing = false;
#endif
}
static void PrintVertexFormat( unsigned int vertexFormat )
{
char buf[256];
if( vertexFormat & VERTEX_POSITION )
{
OutputDebugString( "VERTEX_POSITION|" );
}
if( vertexFormat & VERTEX_NORMAL )
{
OutputDebugString( "VERTEX_NORMAL|" );
}
if( vertexFormat & VERTEX_COLOR )
{
OutputDebugString( "VERTEX_COLOR|" );
}
if( vertexFormat & VERTEX_SPECULAR )
{
OutputDebugString( "VERTEX_SPECULAR|" );
}
if( vertexFormat & VERTEX_TANGENT_S )
{
OutputDebugString( "VERTEX_TANGENT_S|" );
}
if( vertexFormat & VERTEX_TANGENT_T )
{
OutputDebugString( "VERTEX_TANGENT_T|" );
}
if( vertexFormat & VERTEX_BONE_INDEX )
{
OutputDebugString( "VERTEX_BONE_INDEX|" );
}
if( vertexFormat & VERTEX_FORMAT_VERTEX_SHADER )
{
OutputDebugString( "VERTEX_FORMAT_VERTEX_SHADER|" );
}
if( NumBoneWeights( vertexFormat ) > 0 )
{
sprintf( buf, "VERTEX_BONEWEIGHT(%d)|", NumBoneWeights( vertexFormat ) );
OutputDebugString( buf );
}
if( UserDataSize( vertexFormat ) > 0 )
{
sprintf( buf, "VERTEX_USERDATA_SIZE(%d)|", UserDataSize( vertexFormat ) );
OutputDebugString( buf );
}
if( NumTextureCoordinates( vertexFormat ) > 0 )
{
sprintf( buf, "VERTEX_NUM_TEXCOORDS(%d)|", NumTextureCoordinates( vertexFormat ) );
OutputDebugString( buf );
}
int i;
for( i = 0; i < NumTextureCoordinates( vertexFormat ); i++ )
{
sprintf( buf, "VERTEX_TEXCOORD_SIZE(%d,%d)", i, TexCoordSize( i, vertexFormat ) );
OutputDebugString( buf );
}
OutputDebugString( "\n" );
}
//-----------------------------------------------------------------------------
// Spews the mesh data
//-----------------------------------------------------------------------------
void CBaseMeshDX8::Spew( int numVerts, int numIndices, MeshDesc_t const& spewDesc )
{
int i;
#ifdef _DEBUG
if( m_pMaterial )
{
OutputDebugString( ( const char * )m_pMaterial->GetName() );
OutputDebugString( "\n" );
}
#endif // _DEBUG
// This is needed so buffering can just use this
VertexFormat_t fmt = m_VertexFormat;
// Set up the vertex descriptor
MeshDesc_t desc;
memcpy( &desc, &spewDesc, sizeof(MeshDesc_t) );
char tempbuf[256];
char* temp = tempbuf;
sprintf( tempbuf,"\nVerts: (Vertex Format %x)\n", fmt);
OutputDebugString(tempbuf);
PrintVertexFormat( fmt );
int numBoneWeights = NumBoneWeights( fmt );
for ( i = 0; i < numVerts; ++i )
{
temp += sprintf( temp, "[%4d] ", i + desc.m_FirstVertex );
if( fmt & VERTEX_POSITION )
{
D3DXVECTOR3& pos = Position( desc, i );
temp += sprintf(temp, "P %8.2f %8.2f %8.2f ",
pos[0], pos[1], pos[2]);
}
if (numBoneWeights > 0)
{
float* pWeight = BoneWeight( desc, i );
temp += sprintf(temp, "BW ");
for (int j = 0; j < numBoneWeights; ++j)
{
temp += sprintf(temp, "%1.2f ", pWeight[j]);
}
if( fmt & VERTEX_BONE_INDEX )
{
unsigned char *pIndex = BoneIndex( desc, i );
temp += sprintf( temp, "BI %d %d %d %d ", ( int )pIndex[0], ( int )pIndex[1], ( int )pIndex[2], ( int )pIndex[3] );
Assert( pIndex[0] >= 0 && pIndex[0] < 16 );
Assert( pIndex[1] >= 0 && pIndex[1] < 16 );
Assert( pIndex[2] >= 0 && pIndex[2] < 16 );
Assert( pIndex[3] >= 0 && pIndex[3] < 16 );
}
}
if( fmt & VERTEX_NORMAL )
{
D3DXVECTOR3& normal = Normal( desc, i );
temp += sprintf(temp, "N %1.2f %1.2f %1.2f ",
normal[0], normal[1], normal[2]);
}
if (fmt & VERTEX_COLOR)
{
unsigned char* pColor = Color( desc, i );
temp += sprintf(temp, "C b %3d g %3d r %3d a %3d ",
pColor[0], pColor[1], pColor[2], pColor[3]);
}
for (int j = 0; j < HardwareConfig()->GetNumTextureUnits(); ++j)
{
if( TexCoordSize( (TextureStage_t)j, fmt ) > 0)
{
D3DXVECTOR2& texcoord = TexCoord( desc, i, j );
temp += sprintf(temp, "T%d %.2f %.2f ", j,texcoord[0], texcoord[1]);
}
}
if (fmt & VERTEX_TANGENT_S)
{
D3DXVECTOR3& tangentS = TangentS( desc, i );
temp += sprintf(temp, "S %1.2f %1.2f %1.2f ",
tangentS[0], tangentS[1], tangentS[2]);
}
if (fmt & VERTEX_TANGENT_T)
{
D3DXVECTOR3& tangentT = TangentT( desc, i );
temp += sprintf(temp, "T %1.2f %1.2f %1.2f ",
tangentT[0], tangentT[1], tangentT[2]);
}
sprintf(temp,"\n");
OutputDebugString(tempbuf);
temp = tempbuf;
}
sprintf( tempbuf,"\nIndices: %d\n", numIndices );
OutputDebugString(tempbuf);
for ( i = 0; i < numIndices; ++i )
{
temp += sprintf(temp, "%d ", desc.m_pIndices[i] );
if ((i & 0x0F) == 0x0F)
{
sprintf(temp,"\n");
OutputDebugString(tempbuf);
temp = tempbuf;
}
}
sprintf(temp,"\n");
OutputDebugString(temp);
}
void CBaseMeshDX8::ValidateData( int numVerts, int numIndices, MeshDesc_t const& spewDesc )
{
#ifdef BLAH_DEBUG
int i;
// This is needed so buffering can just use this
VertexFormat_t fmt = m_VertexFormat;
// Set up the vertex descriptor
MeshDesc_t desc;
memcpy( &desc, &spewDesc, sizeof(MeshDesc_t) );
int numBoneWeights = NumBoneWeights( fmt );
for ( i = 0; i < numVerts; ++i )
{
if (numBoneWeights > 0)
{
float* pWeight = BoneWeight( desc, i );
for (int j = 0; j < numBoneWeights; ++j)
{
Assert( pWeight[j] >= 0.0f && pWeight[j] <= 1.0f );
}
if( fmt & VERTEX_BONE_INDEX )
{
unsigned char *pIndex = BoneIndex( desc, i );
Assert( pIndex[0] >= 0 && pIndex[0] < 16 );
Assert( pIndex[1] >= 0 && pIndex[1] < 16 );
Assert( pIndex[2] >= 0 && pIndex[2] < 16 );
Assert( pIndex[3] >= 0 && pIndex[3] < 16 );
}
}
if( fmt & VERTEX_NORMAL )
{
D3DXVECTOR3& normal = Normal( desc, i );
Assert( normal[0] >= -1.05f && normal[0] <= 1.05f );
Assert( normal[1] >= -1.05f && normal[1] <= 1.05f );
Assert( normal[2] >= -1.05f && normal[2] <= 1.05f );
}
}
#endif // _DEBUG
}
void CBaseMeshDX8::Draw( CPrimList *pLists, int nLists )
{
Assert( !"CBaseMeshDX8::Draw(CPrimList, int): should never get here." );
}
// Copy verts and/or indices to a mesh builder. This only works for temp meshes!
void CBaseMeshDX8::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 )
{
Assert( false );
Warning( "CopyToMeshBuilder called on something other than a temp mesh.\n" );
}
//-----------------------------------------------------------------------------
//
// static mesh
//
//-----------------------------------------------------------------------------
CPrimList *CMeshDX8::s_pPrims;
int CMeshDX8::s_nPrims;
unsigned int CMeshDX8::s_FirstVertex;
unsigned int CMeshDX8::s_NumVertices;
//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
CMeshDX8::CMeshDX8( ) : m_NumVertices(0), m_NumIndices(0), m_pVertexBuffer(0),
m_pColorMesh( 0 ),
m_pIndexBuffer(0), m_Type(MATERIAL_TRIANGLES), m_IsVBLocked(false),
m_IsIBLocked(false)
{
m_Mode = ComputeMode(m_Type);
}
CMeshDX8::~CMeshDX8()
{
// Don't release the vertex buffer
if (!g_MeshMgr.IsDynamicMesh(this))
{
if (m_pVertexBuffer)
delete m_pVertexBuffer;
if (m_pIndexBuffer)
delete m_pIndexBuffer;
}
}
void CMeshDX8::SetColorMesh( IMesh *pColorMesh )
{
m_pColorMesh = ( CMeshDX8 * )pColorMesh; // dangerous conversion! garymcthack
#ifdef _DEBUG
if( pColorMesh )
{
int numVerts = NumVertices();
int numVertsColorMesh = m_pColorMesh->NumVertices();
Assert( numVerts == numVertsColorMesh );
}
#endif
}
bool CMeshDX8::HasColorMesh( ) const
{
return (m_pColorMesh != NULL);
}
//-----------------------------------------------------------------------------
// Locks/ unlocks the vertex buffer
//-----------------------------------------------------------------------------
void CMeshDX8::LockVertexBuffer( int numVerts, MeshDesc_t& desc )
{
Assert( !m_IsVBLocked );
// Just give the app crap buffers to fill up while we're suppressed...
if (ShaderAPI()->IsDeactivated() || (numVerts == 0))
{
// Set up the vertex descriptor
g_MeshMgr.ComputeVertexDescription( 0, 0, desc );
desc.m_FirstVertex = 0;
return;
}
MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_BUFFER_LOCK_TIME);
MaterialSystemStats()->IncrementCountedStat( MATERIAL_SYSTEM_STATS_NUM_BUFFER_LOCK, 1 );
// Static vertex buffer case
if (!m_pVertexBuffer)
{
int size = g_MeshMgr.VertexFormatSize( m_VertexFormat );
m_pVertexBuffer = new CVertexBuffer( D3DDevice(), 0, size, numVerts );
}
// Lock it baby
Assert( numVerts <= VERTEX_BUFFER_SIZE );
unsigned char* pVertexMemory = m_pVertexBuffer->Lock( numVerts, desc.m_FirstVertex );
if( !pVertexMemory )
{
if( numVerts > VERTEX_BUFFER_SIZE )
{
Assert( 0 );
Error( "Too many verts for a dynamic vertex buffer (%d>%d) Tell a programmer to up VERTEX_BUFFER_SIZE.\n",
( int )numVerts, ( int )VERTEX_BUFFER_SIZE );
}
else
{
Assert( 0 );
Error( "failed to lock vertex buffer in CMeshDX8::LockVertexBuffer\n" );
}
g_MeshMgr.ComputeVertexDescription( 0, 0, desc );
return;
}
// Set up the vertex descriptor
g_MeshMgr.ComputeVertexDescription( pVertexMemory, m_VertexFormat, desc );
m_IsVBLocked = true;
#ifdef RECORDING
m_LockVertexBufferSize = numVerts * desc.m_ActualVertexSize;
m_LockVertexBuffer = pVertexMemory;
#endif
}
void CMeshDX8::UnlockVertexBuffer( int numVerts )
{
// NOTE: This can happen if another application finishes
// initializing during the construction of a mesh
if (!m_IsVBLocked)
return;
// This is recorded for debugging. . not sent to dx.
RECORD_COMMAND( DX8_SET_VERTEX_BUFFER_FORMAT, 2 );
RECORD_INT( m_pVertexBuffer->UID() );
RECORD_INT( m_VertexFormat );
RECORD_COMMAND( DX8_VERTEX_DATA, 3 );
RECORD_INT( m_pVertexBuffer->UID() );
RECORD_INT( m_LockVertexBufferSize );
RECORD_STRUCT( m_LockVertexBuffer, m_LockVertexBufferSize );
MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_BUFFER_UNLOCK_TIME);
Assert(m_pVertexBuffer);
m_pVertexBuffer->Unlock(numVerts);
m_IsVBLocked = false;
}
//-----------------------------------------------------------------------------
// Locks/unlocks the index buffer
//-----------------------------------------------------------------------------
int CMeshDX8::LockIndexBuffer( int firstIndex, int numIndices, MeshDesc_t& desc )
{
Assert( !m_IsIBLocked );
// Just give the app crap buffers to fill up while we're suppressed...
if (ShaderAPI()->IsDeactivated() || (numIndices == 0))
{
// Set up a bogus index descriptor
desc.m_pIndices = NULL;
return 0;
}
MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_BUFFER_LOCK_TIME);
MaterialSystemStats()->IncrementCountedStat( MATERIAL_SYSTEM_STATS_NUM_BUFFER_LOCK, 1 );
// Static vertex buffer case
if (!m_pIndexBuffer)
m_pIndexBuffer = new CIndexBuffer( D3DDevice(), numIndices );
int startIndex;
desc.m_pIndices = m_pIndexBuffer->Lock( numIndices, startIndex, firstIndex );
m_IsIBLocked = true;
#if defined( RECORDING ) || defined( CHECK_INDICES )
m_LockIndexBufferSize = numIndices * 2;
m_LockIndexBuffer = desc.m_pIndices;
#endif
return startIndex;
}
void CMeshDX8::UnlockIndexBuffer( int numIndices )
{
// NOTE: This can happen if another application finishes
// initializing during the construction of a mesh
if (!m_IsIBLocked)
return;
RECORD_COMMAND( DX8_INDEX_DATA, 3 );
RECORD_INT( m_pIndexBuffer->UID() );
RECORD_INT( m_LockIndexBufferSize );
RECORD_STRUCT( m_LockIndexBuffer, m_LockIndexBufferSize );
MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_BUFFER_UNLOCK_TIME);
Assert(m_pIndexBuffer);
#ifdef CHECK_INDICES
m_pIndexBuffer->UpdateShadowIndices( ( unsigned short * )m_LockIndexBuffer );
#endif // CHECK_INDICES
// Unlock, and indicate how many vertices we actually used
m_pIndexBuffer->Unlock(numIndices);
m_IsIBLocked = false;
}
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -