📄 dxutmesh.cpp
字号:
for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index )
{
if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL )
{
bHadNormal = true;
}
if( aOldDecl[index].Usage == D3DDECLUSAGE_TANGENT )
{
bHadTangent = true;
}
}
}
// Check if the new declaration contains a normal.
bool bHaveNormalNow = false;
bool bHaveTangentNow = false;
D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE];
if( pTempMesh && SUCCEEDED( pTempMesh->GetDeclaration( aNewDecl ) ) )
{
for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index )
{
if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL )
{
bHaveNormalNow = true;
}
if( aNewDecl[index].Usage == D3DDECLUSAGE_TANGENT )
{
bHaveTangentNow = true;
}
}
}
SAFE_RELEASE( m_pMesh );
if( pTempMesh )
{
m_pMesh = pTempMesh;
if( !bHadNormal && bHaveNormalNow && bAutoComputeNormals )
{
// Compute normals in case the meshes have them
D3DXComputeNormals( m_pMesh, NULL );
}
if( bHaveNormalNow && !bHadTangent && bHaveTangentNow && bAutoComputeTangents )
{
ID3DXMesh* pNewMesh;
HRESULT hr;
DWORD *rgdwAdjacency = NULL;
rgdwAdjacency = new DWORD[m_pMesh->GetNumFaces() * 3];
if( rgdwAdjacency == NULL )
return E_OUTOFMEMORY;
V( m_pMesh->GenerateAdjacency(1e-6f,rgdwAdjacency) );
float fPartialEdgeThreshold;
float fSingularPointThreshold;
float fNormalEdgeThreshold;
if( bSplitVertexForOptimalTangents )
{
fPartialEdgeThreshold = 0.01f;
fSingularPointThreshold = 0.25f;
fNormalEdgeThreshold = 0.01f;
}
else
{
fPartialEdgeThreshold = -1.01f;
fSingularPointThreshold = 0.01f;
fNormalEdgeThreshold = -1.01f;
}
// Compute tangents, which are required for normal mapping
hr = D3DXComputeTangentFrameEx( m_pMesh,
D3DDECLUSAGE_TEXCOORD, 0,
D3DDECLUSAGE_TANGENT, 0,
D3DX_DEFAULT, 0,
D3DDECLUSAGE_NORMAL, 0,
0, rgdwAdjacency,
fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold,
&pNewMesh, NULL );
SAFE_DELETE_ARRAY( rgdwAdjacency );
if( FAILED(hr) )
return hr;
SAFE_RELEASE( m_pMesh );
m_pMesh = pNewMesh;
}
}
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
{
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::InvalidateDeviceObjects()
{
SAFE_RELEASE( m_pIB );
SAFE_RELEASE( m_pVB );
SAFE_RELEASE( m_pDecl );
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::Destroy()
{
InvalidateDeviceObjects();
for( UINT i=0; i<m_dwNumMaterials; i++ )
SAFE_RELEASE( m_pTextures[i] );
SAFE_DELETE_ARRAY( m_pTextures );
SAFE_DELETE_ARRAY( m_pMaterials );
SAFE_DELETE_ARRAY( m_strMaterials );
SAFE_RELEASE( m_pMesh );
m_dwNumMaterials = 0L;
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets,
bool bDrawAlphaSubsets )
{
if( NULL == m_pMesh )
return E_FAIL;
// Frist, draw the subsets without alpha
if( bDrawOpaqueSubsets )
{
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a < 1.0f )
continue;
pd3dDevice->SetMaterial( &m_pMaterials[i] );
pd3dDevice->SetTexture( 0, m_pTextures[i] );
}
m_pMesh->DrawSubset( i );
}
}
// Then, draw the subsets with alpha
if( bDrawAlphaSubsets && m_bUseMaterials )
{
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_pMaterials[i].Diffuse.a == 1.0f )
continue;
// Set the material and texture
pd3dDevice->SetMaterial( &m_pMaterials[i] );
pd3dDevice->SetTexture( 0, m_pTextures[i] );
m_pMesh->DrawSubset( i );
}
}
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::Render( ID3DXEffect *pEffect,
D3DXHANDLE hTexture,
D3DXHANDLE hDiffuse,
D3DXHANDLE hAmbient,
D3DXHANDLE hSpecular,
D3DXHANDLE hEmissive,
D3DXHANDLE hPower,
bool bDrawOpaqueSubsets,
bool bDrawAlphaSubsets )
{
if( NULL == m_pMesh )
return E_FAIL;
UINT cPasses;
// Frist, draw the subsets without alpha
if( bDrawOpaqueSubsets )
{
pEffect->Begin( &cPasses, 0 );
for( UINT p = 0; p < cPasses; ++p )
{
pEffect->BeginPass( p );
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a < 1.0f )
continue;
if( hTexture )
pEffect->SetTexture( hTexture, m_pTextures[i] );
// D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
// No conversion is needed.
if( hDiffuse )
pEffect->SetVector( hDiffuse, (D3DXVECTOR4*)&m_pMaterials[i].Diffuse );
if( hAmbient )
pEffect->SetVector( hAmbient, (D3DXVECTOR4*)&m_pMaterials[i].Ambient );
if( hSpecular )
pEffect->SetVector( hSpecular, (D3DXVECTOR4*)&m_pMaterials[i].Specular );
if( hEmissive )
pEffect->SetVector( hEmissive, (D3DXVECTOR4*)&m_pMaterials[i].Emissive );
if( hPower )
pEffect->SetFloat( hPower, m_pMaterials[i].Power );
pEffect->CommitChanges();
}
m_pMesh->DrawSubset( i );
}
pEffect->EndPass();
}
pEffect->End();
}
// Then, draw the subsets with alpha
if( bDrawAlphaSubsets && m_bUseMaterials )
{
pEffect->Begin( &cPasses, 0 );
for( UINT p = 0; p < cPasses; ++p )
{
pEffect->BeginPass( p );
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a == 1.0f )
continue;
if( hTexture )
pEffect->SetTexture( hTexture, m_pTextures[i] );
// D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
// No conversion is needed.
if( hDiffuse )
pEffect->SetVector( hDiffuse, (D3DXVECTOR4*)&m_pMaterials[i].Diffuse );
if( hAmbient )
pEffect->SetVector( hAmbient, (D3DXVECTOR4*)&m_pMaterials[i].Ambient );
if( hSpecular )
pEffect->SetVector( hSpecular, (D3DXVECTOR4*)&m_pMaterials[i].Specular );
if( hEmissive )
pEffect->SetVector( hEmissive, (D3DXVECTOR4*)&m_pMaterials[i].Emissive );
if( hPower )
pEffect->SetFloat( hPower, m_pMaterials[i].Power );
pEffect->CommitChanges();
}
m_pMesh->DrawSubset( i );
}
pEffect->EndPass();
}
pEffect->End();
}
return S_OK;
}
//-----------------------------------------------------------------------------
CDXUTMeshFrame::CDXUTMeshFrame( LPCWSTR strName )
{
StringCchCopy( m_strName, 512, strName );
D3DXMatrixIdentity( &m_mat );
m_pMesh = NULL;
m_pChild = NULL;
m_pNext = NULL;
}
//-----------------------------------------------------------------------------
CDXUTMeshFrame::~CDXUTMeshFrame()
{
SAFE_DELETE( m_pChild );
SAFE_DELETE( m_pNext );
}
//-----------------------------------------------------------------------------
bool CDXUTMeshFrame::EnumMeshes( bool (*EnumMeshCB)(CDXUTMesh*,void*),
void* pContext )
{
if( m_pMesh )
EnumMeshCB( m_pMesh, pContext );
if( m_pChild )
m_pChild->EnumMeshes( EnumMeshCB, pContext );
if( m_pNext )
m_pNext->EnumMeshes( EnumMeshCB, pContext );
return TRUE;
}
//-----------------------------------------------------------------------------
CDXUTMesh* CDXUTMeshFrame::FindMesh( LPCWSTR strMeshName )
{
CDXUTMesh* pMesh;
if( m_pMesh )
if( !lstrcmpi( m_pMesh->m_strName, strMeshName ) )
return m_pMesh;
if( m_pChild )
if( NULL != ( pMesh = m_pChild->FindMesh( strMeshName ) ) )
return pMesh;
if( m_pNext )
if( NULL != ( pMesh = m_pNext->FindMesh( strMeshName ) ) )
return pMesh;
return NULL;
}
//-----------------------------------------------------------------------------
CDXUTMeshFrame* CDXUTMeshFrame::FindFrame( LPCWSTR strFrameName )
{
CDXUTMeshFrame* pFrame;
if( !lstrcmpi( m_strName, strFrameName ) )
return this;
if( m_pChild )
if( NULL != ( pFrame = m_pChild->FindFrame( strFrameName ) ) )
return pFrame;
if( m_pNext )
if( NULL != ( pFrame = m_pNext->FindFrame( strFrameName ) ) )
return pFrame;
return NULL;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFrame::Destroy()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -