📄 dxutmesh.cpp
字号:
{
if( m_pMesh ) m_pMesh->Destroy();
if( m_pChild ) m_pChild->Destroy();
if( m_pNext ) m_pNext->Destroy();
SAFE_DELETE( m_pMesh );
SAFE_DELETE( m_pNext );
SAFE_DELETE( m_pChild );
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
{
if( m_pMesh ) m_pMesh->RestoreDeviceObjects( pd3dDevice );
if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );
if( m_pNext ) m_pNext->RestoreDeviceObjects( pd3dDevice );
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFrame::InvalidateDeviceObjects()
{
if( m_pMesh ) m_pMesh->InvalidateDeviceObjects();
if( m_pChild ) m_pChild->InvalidateDeviceObjects();
if( m_pNext ) m_pNext->InvalidateDeviceObjects();
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFrame::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets,
bool bDrawAlphaSubsets, D3DXMATRIX* pmatWorldMatrix )
{
// For pure devices, specify the world transform. If the world transform is not
// specified on pure devices, this function will fail.
D3DXMATRIX matSavedWorld, matWorld;
if ( NULL == pmatWorldMatrix )
pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
else
matSavedWorld = *pmatWorldMatrix;
D3DXMatrixMultiply( &matWorld, &m_mat, &matSavedWorld );
pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
if( m_pMesh )
m_pMesh->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
if( m_pChild )
m_pChild->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matWorld );
pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
if( m_pNext )
m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matSavedWorld );
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFile::LoadFrame( LPDIRECT3DDEVICE9 pd3dDevice,
LPD3DXFILEDATA pFileData,
CDXUTMeshFrame* pParentFrame )
{
LPD3DXFILEDATA pChildData = NULL;
GUID Guid;
SIZE_T cbSize;
CDXUTMeshFrame* pCurrentFrame;
HRESULT hr;
// Get the type of the object
if( FAILED( hr = pFileData->GetType( &Guid ) ) )
return hr;
if( Guid == TID_D3DRMMesh )
{
hr = LoadMesh( pd3dDevice, pFileData, pParentFrame );
if( FAILED(hr) )
return hr;
}
if( Guid == TID_D3DRMFrameTransformMatrix )
{
D3DXMATRIX* pmatMatrix;
hr = pFileData->Lock(&cbSize, (LPCVOID*)&pmatMatrix );
if( FAILED(hr) )
return hr;
// Update the parent's matrix with the new one
pParentFrame->SetMatrix( pmatMatrix );
}
if( Guid == TID_D3DRMFrame )
{
// Get the frame name
CHAR strAnsiName[512] = "";
WCHAR strName[512];
SIZE_T dwNameLength = 512;
SIZE_T cChildren;
if( FAILED( hr = pFileData->GetName( strAnsiName, &dwNameLength ) ) )
return hr;
MultiByteToWideChar( CP_ACP, 0, strAnsiName, -1, strName, 512 );
strName[511] = 0;
// Create the frame
pCurrentFrame = new CDXUTMeshFrame( strName );
if( pCurrentFrame == NULL )
return E_OUTOFMEMORY;
pCurrentFrame->m_pNext = pParentFrame->m_pChild;
pParentFrame->m_pChild = pCurrentFrame;
// Enumerate child objects
pFileData->GetChildren(&cChildren);
for (UINT iChild = 0; iChild < cChildren; iChild++)
{
// Query the child for its FileData
hr = pFileData->GetChild(iChild, &pChildData );
if( SUCCEEDED(hr) )
{
hr = LoadFrame( pd3dDevice, pChildData, pCurrentFrame );
SAFE_RELEASE( pChildData );
}
if( FAILED(hr) )
return hr;
}
}
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFile::LoadMesh( LPDIRECT3DDEVICE9 pd3dDevice,
LPD3DXFILEDATA pFileData,
CDXUTMeshFrame* pParentFrame )
{
// Currently only allowing one mesh per frame
if( pParentFrame->m_pMesh )
return E_FAIL;
// Get the mesh name
CHAR strAnsiName[512] = {0};
WCHAR strName[512];
SIZE_T dwNameLength = 512;
HRESULT hr;
if( FAILED( hr = pFileData->GetName( strAnsiName, &dwNameLength ) ) )
return hr;
MultiByteToWideChar( CP_ACP, 0, strAnsiName, -1, strName, 512 );
strName[511] = 0;
// Create the mesh
pParentFrame->m_pMesh = new CDXUTMesh( strName );
if( pParentFrame->m_pMesh == NULL )
return E_OUTOFMEMORY;
pParentFrame->m_pMesh->Create( pd3dDevice, pFileData );
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFile::CreateFromResource( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strResource, LPCWSTR strType )
{
LPD3DXFILE pDXFile = NULL;
LPD3DXFILEENUMOBJECT pEnumObj = NULL;
LPD3DXFILEDATA pFileData = NULL;
HRESULT hr;
SIZE_T cChildren;
// Create a x file object
if( FAILED( hr = D3DXFileCreate( &pDXFile ) ) )
return E_FAIL;
// Register templates for d3drm and patch extensions.
if( FAILED( hr = pDXFile->RegisterTemplates( (void*)D3DRM_XTEMPLATES,
D3DRM_XTEMPLATE_BYTES ) ) )
{
SAFE_RELEASE( pDXFile );
return E_FAIL;
}
CHAR strTypeAnsi[MAX_PATH];
CHAR strResourceAnsi[MAX_PATH];
WideCharToMultiByte( CP_ACP, 0, strType, -1, strTypeAnsi, MAX_PATH, NULL, NULL );
strTypeAnsi[MAX_PATH-1] = 0;
WideCharToMultiByte( CP_ACP, 0, strResource, -1, strResourceAnsi, MAX_PATH, NULL, NULL );
strResourceAnsi[MAX_PATH-1] = 0;
D3DXF_FILELOADRESOURCE dxlr;
dxlr.hModule = NULL;
dxlr.lpName = strResourceAnsi;
dxlr.lpType = strTypeAnsi;
// Create enum object
hr = pDXFile->CreateEnumObject( (void*)&dxlr, D3DXF_FILELOAD_FROMRESOURCE,
&pEnumObj );
if( FAILED(hr) )
{
SAFE_RELEASE( pDXFile );
return hr;
}
// Enumerate top level objects (which are always frames)
pEnumObj->GetChildren(&cChildren);
for (UINT iChild = 0; iChild < cChildren; iChild++)
{
hr = pEnumObj->GetChild(iChild, &pFileData);
if (FAILED(hr))
return hr;
hr = LoadFrame( pd3dDevice, pFileData, this );
SAFE_RELEASE( pFileData );
if( FAILED(hr) )
{
SAFE_RELEASE( pEnumObj );
SAFE_RELEASE( pDXFile );
return E_FAIL;
}
}
SAFE_RELEASE( pFileData );
SAFE_RELEASE( pEnumObj );
SAFE_RELEASE( pDXFile );
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFile::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename )
{
LPD3DXFILE pDXFile = NULL;
LPD3DXFILEENUMOBJECT pEnumObj = NULL;
LPD3DXFILEDATA pFileData = NULL;
HRESULT hr;
SIZE_T cChildren;
// Create a x file object
if( FAILED( hr = D3DXFileCreate( &pDXFile ) ) )
return E_FAIL;
// Register templates for d3drm and patch extensions.
if( FAILED( hr = pDXFile->RegisterTemplates( (void*)D3DRM_XTEMPLATES,
D3DRM_XTEMPLATE_BYTES ) ) )
{
SAFE_RELEASE( pDXFile );
return E_FAIL;
}
// Find the path to the file, and convert it to ANSI (for the D3DXOF API)
WCHAR strPath[MAX_PATH];
CHAR strPathANSI[MAX_PATH];
DXUTFindDXSDKMediaFileCch( strPath, sizeof(strPath) / sizeof(WCHAR), strFilename );
WideCharToMultiByte( CP_ACP, 0, strPath, -1, strPathANSI, MAX_PATH, NULL, NULL );
strPathANSI[MAX_PATH-1] = 0;
// Create enum object
hr = pDXFile->CreateEnumObject( (void*)strPathANSI, D3DXF_FILELOAD_FROMFILE,
&pEnumObj );
if( FAILED(hr) )
{
SAFE_RELEASE( pDXFile );
return hr;
}
// Enumerate top level objects (which are always frames)
pEnumObj->GetChildren(&cChildren);
for (UINT iChild = 0; iChild < cChildren; iChild++)
{
hr = pEnumObj->GetChild(iChild, &pFileData);
if (FAILED(hr))
return hr;
hr = LoadFrame( pd3dDevice, pFileData, this );
SAFE_RELEASE( pFileData );
if( FAILED(hr) )
{
SAFE_RELEASE( pEnumObj );
SAFE_RELEASE( pDXFile );
return E_FAIL;
}
}
SAFE_RELEASE( pFileData );
SAFE_RELEASE( pEnumObj );
SAFE_RELEASE( pDXFile );
return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT CDXUTMeshFile::Render( LPDIRECT3DDEVICE9 pd3dDevice, D3DXMATRIX* pmatWorldMatrix )
{
// For pure devices, specify the world transform. If the world transform is not
// specified on pure devices, this function will fail.
// Set up the world transformation
D3DXMATRIX matSavedWorld, matWorld;
if ( NULL == pmatWorldMatrix )
pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
else
matSavedWorld = *pmatWorldMatrix;
D3DXMatrixMultiply( &matWorld, &matSavedWorld, &m_mat );
pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
// Render opaque subsets in the meshes
if( m_pChild )
m_pChild->Render( pd3dDevice, TRUE, FALSE, &matWorld );
// Enable alpha blending
pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
// Render alpha subsets in the meshes
if( m_pChild )
m_pChild->Render( pd3dDevice, FALSE, TRUE, &matWorld );
// Restore state
pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -