📄 d3dfile.cpp
字号:
}
pChildObj->Release();
}
pParentFrame->AddChild( pFrame );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CD3DFile()
// Desc: Class constructor
//-----------------------------------------------------------------------------
CD3DFile::CD3DFile()
{
m_pRoot = NULL;
}
//-----------------------------------------------------------------------------
// Name: ~CD3DFile()
// Desc: Class destructor
//-----------------------------------------------------------------------------
CD3DFile::~CD3DFile()
{
SAFE_DELETE( m_pRoot );
}
//-----------------------------------------------------------------------------
// Name: Load()
// Desc: Loads a .X geometry file, and creates a hierarchy of frames and meshes
// to represent the geometry in that file.
//-----------------------------------------------------------------------------
HRESULT CD3DFile::Load( TCHAR* strFilename )
{
HRESULT hr;
LPDIRECTXFILE pDXFile;
LPDIRECTXFILEENUMOBJECT pEnumObj;
LPDIRECTXFILEDATA pFileData;
const GUID* pGUID;
CD3DFileObject* pFrame = NULL;
// Cleanup any existing object
SAFE_DELETE( m_pRoot );
// Create the file object, and register the D3DRM templates for .X files
if( FAILED( DirectXFileCreate( &pDXFile ) ) )
return E_FAIL;
if( FAILED( pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
D3DRM_XTEMPLATE_BYTES ) ) )
{
pDXFile->Release();
return E_FAIL;
}
// Create an enumerator object, to enumerate through the .X file objects.
// This will open the file in the current directory.
hr = pDXFile->CreateEnumObject( strFilename, DXFILELOAD_FROMFILE, &pEnumObj );
if( FAILED(hr) )
{
TCHAR strPath[512] = _T("");
lstrcat( strPath, D3DUtil_GetDXSDKMediaPath() );
lstrcat( strPath, strFilename );
hr = pDXFile->CreateEnumObject( strPath, DXFILELOAD_FROMFILE,
&pEnumObj );
if( FAILED(hr) )
{
pDXFile->Release();
return hr;
}
}
// Create a root object for the X file object
m_pRoot = new CD3DFileObject( _T("D3DFile_Root") );
// Cycle through each object. Parse meshes and frames as appropriate
while( SUCCEEDED( hr = pEnumObj->GetNextDataObject( &pFileData ) ) )
{
pFileData->GetType( &pGUID );
if( *pGUID == TID_D3DRMFrame )
ParseFrame( pFileData, m_pRoot );
if( *pGUID == TID_D3DRMMesh )
ParseMesh( pFileData, m_pRoot );
pFileData->Release();
}
// Success will result in hr == DXFILEERR_NOMOREOBJECTS
if( DXFILEERR_NOMOREOBJECTS == hr )
hr = S_OK;
else
SAFE_DELETE( m_pRoot );
pEnumObj->Release();
pDXFile->Release();
return hr;
}
//-----------------------------------------------------------------------------
// Name: GetMeshVertices()
// Desc: Traverse the hierarchy of frames and meshes that make up the file
// object, and retrieves the vertices for the specified mesh.
//-----------------------------------------------------------------------------
HRESULT CD3DFile::GetMeshVertices( TCHAR* strName, D3DVERTEX** ppVertices,
DWORD* pdwNumVertices )
{
CD3DFileObject* pObject = FindObject( strName );
if( pObject )
return pObject->GetMeshGeometry( ppVertices, pdwNumVertices, NULL, NULL );
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: GetMeshVertices()
// Desc: Traverse the hierarchy of frames and meshes that make up the file
// object, and retrieves the vertices for the specified mesh.
//-----------------------------------------------------------------------------
HRESULT CD3DFile::GetMeshIndices( TCHAR* strName, WORD** ppIndices,
DWORD* pdwNumIndices )
{
CD3DFileObject* pObject = FindObject( strName );
if( pObject )
return pObject->GetMeshGeometry( NULL, NULL, ppIndices, pdwNumIndices );
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: EnumObjects()
// Desc: Enumerates all objects in the file.
//-----------------------------------------------------------------------------
BOOL CD3DFileObject::EnumObjects( BOOL (*fnCallback)(CD3DFileObject*,D3DMATRIX*,VOID*),
D3DMATRIX* pmat, VOID* pContext )
{
if( fnCallback( this, pmat, pContext ) == TRUE )
return TRUE;
if( m_pChild )
{
// Concat matrix set
D3DMATRIX matSave = (*pmat);
(*pmat) = (*pmat) * m_mat;
if( m_pChild->EnumObjects( fnCallback, pmat, pContext ) == TRUE )
return TRUE;
// Restore matrix set
(*pmat) = matSave;
}
if( m_pNext )
if( m_pNext->EnumObjects( fnCallback, pmat, pContext ) == TRUE )
return TRUE;
return FALSE;
}
//-----------------------------------------------------------------------------
// Name: EnumObjects()
// Desc: Enumerates all objects in the file.
//-----------------------------------------------------------------------------
VOID CD3DFile::EnumObjects( BOOL (*fnCallback)(CD3DFileObject*,D3DMATRIX*,VOID*),
D3DMATRIX* pmat, VOID* pContext )
{
if( m_pRoot )
{
D3DMATRIX mat;
if( pmat )
mat = *pmat;
else
D3DUtil_SetIdentityMatrix( mat );
m_pRoot->EnumObjects( fnCallback, &mat, pContext );
}
}
//-----------------------------------------------------------------------------
// Name: ScaleMeshCB()
// Desc: Callback to scale a mesh
//-----------------------------------------------------------------------------
BOOL ScaleMeshCB( CD3DFileObject* pFileObject, D3DMATRIX*, VOID* pContext )
{
D3DVERTEX* pVertices;
DWORD dwNumVertices;
if( SUCCEEDED( pFileObject->GetMeshGeometry( &pVertices, &dwNumVertices,
NULL, NULL ) ) )
{
for( DWORD i=0; i<dwNumVertices; i++ )
{
pVertices[i].x *= (*((FLOAT*)pContext));
pVertices[i].y *= (*((FLOAT*)pContext));
pVertices[i].z *= (*((FLOAT*)pContext));
}
}
// Keep enumerating
return FALSE;
}
//-----------------------------------------------------------------------------
// Name: FindMeshCB()
// Desc: Callback to scale a mesh
//-----------------------------------------------------------------------------
BOOL FindMeshCB( CD3DFileObject* pFileObject, D3DMATRIX*, VOID* pContext )
{
struct FINDMESHRECORD
{
TCHAR* strName;
CD3DFileObject* pObject;
};
FINDMESHRECORD* data = (FINDMESHRECORD*)pContext;
if( 0 == lstrcmpi( data->strName, pFileObject->GetName() ) )
{
data->pObject = pFileObject;
return TRUE;
}
// Keep enumerating
return FALSE;
}
//-----------------------------------------------------------------------------
// Name: Scale()
// Desc: Scales all meshes in the file
//-----------------------------------------------------------------------------
VOID CD3DFile::Scale( FLOAT fScale )
{
EnumObjects( ScaleMeshCB, NULL, (VOID*)&fScale );
}
//-----------------------------------------------------------------------------
// Name: FindObject()
// Desc: Searches all meshes in file object and returns named mesh
//-----------------------------------------------------------------------------
CD3DFileObject* CD3DFile::FindObject( TCHAR* strName )
{
if( NULL == strName )
return m_pRoot;
struct FINDMESHRECORD
{
TCHAR* strName;
CD3DFileObject* pObject;
};
FINDMESHRECORD data = { strName, NULL };
EnumObjects( FindMeshCB, NULL, (VOID*)&data );
return data.pObject;
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Renders the hierarchy of frames and meshes that make up the file
// object
//-----------------------------------------------------------------------------
HRESULT CD3DFile::Render( LPDIRECT3DDEVICE7 pd3dDevice )
{
LPDIRECTDRAWSURFACE7 pddsSavedTexture;
D3DMATRIX matSaved;
D3DMATERIAL7 mtrlSaved;
DWORD dwAlphaState, dwSrcBlendState, dwDestBlendState;
if( m_pRoot )
{
// State render states that will be overwritten
pd3dDevice->GetMaterial( &mtrlSaved );
pd3dDevice->GetTexture( 0, &pddsSavedTexture );
pd3dDevice->GetTransform( D3DTRANSFORMSTATE_WORLD, &matSaved );
pd3dDevice->GetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, &dwAlphaState );
pd3dDevice->GetRenderState( D3DRENDERSTATE_SRCBLEND, &dwSrcBlendState );
pd3dDevice->GetRenderState( D3DRENDERSTATE_DESTBLEND, &dwDestBlendState );
// Render the opaque file object's hierarchy of frames and meshes
m_pRoot->Render( pd3dDevice, FALSE );
// Render the transparent file object's hierarchy of frames and meshes
pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
m_pRoot->Render( pd3dDevice, TRUE );
// Restore the render states
pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, dwAlphaState );
pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, dwSrcBlendState );
pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, dwDestBlendState );
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matSaved );
pd3dDevice->SetTexture( 0, pddsSavedTexture );
pd3dDevice->SetMaterial( &mtrlSaved );
// Keep the ref count of the texture consistent
if( pddsSavedTexture )
pddsSavedTexture->Release();
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -