📄 d3dfile.cpp
字号:
// Provide some relief to bogus normals
if( Magnitude( pNormals[i] ) < 0.1f )
pNormals[i] = D3DVECTOR( 0.0f, 0.0f, 1.0f );
pNormals[i] = Normalize( pNormals[i] );
m_pVertices[i].nx = pNormals[i].x;
m_pVertices[i].ny = pNormals[i].y;
m_pVertices[i].nz = pNormals[i].z;
}
delete pNormals;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
VOID CD3DFileObject::SetNormals( D3DVECTOR* pNormals )
{
for( DWORD i=0; i<m_dwNumVertices; i++ )
{
m_pVertices[i].nx = pNormals[i].x;
m_pVertices[i].ny = pNormals[i].y;
m_pVertices[i].nz = pNormals[i].z;
}
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
VOID CD3DFileObject::SetTextureCoords( FLOAT* pTexCoords )
{
for( DWORD i=0; i<m_dwNumVertices; i++ )
{
m_pVertices[i].tu = pTexCoords[2*i+0];
m_pVertices[i].tv = pTexCoords[2*i+1];
}
}
//-----------------------------------------------------------------------------
// Name: ParseXXXX()
// Desc: The following routines implement the DirectX .X file loader.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT ParseMaterial( LPDIRECTXFILEDATA pFileData, CD3DFileObject* pMesh,
DWORD dwMaterial )
{
// Read data from the file
LONG pData;
DWORD dwSize;
TCHAR strTexture[128];
if( FAILED( pFileData->GetData( NULL, &dwSize, (VOID**)&pData ) ) )
return NULL;
// Set the material properties for the mesh
D3DMATERIAL7 mtrl;
ZeroMemory( &mtrl, sizeof(mtrl) );
memcpy( &mtrl.diffuse, (VOID*)(pData+0), sizeof(FLOAT)*4 );
memcpy( &mtrl.ambient, (VOID*)(pData+0), sizeof(FLOAT)*4 );
memcpy( &mtrl.power, (VOID*)(pData+16), sizeof(FLOAT)*1 );
memcpy( &mtrl.specular, (VOID*)(pData+20), sizeof(FLOAT)*3 );
memcpy( &mtrl.emissive, (VOID*)(pData+32), sizeof(FLOAT)*3 );
strTexture[0] = 0;
LPDIRECTXFILEOBJECT pChildObj;
if( SUCCEEDED( pFileData->GetNextObject(&pChildObj) ) )
{
LPDIRECTXFILEDATA pChildData;
if( SUCCEEDED( pChildObj->QueryInterface( IID_IDirectXFileData,
(VOID**)&pChildData) ) )
{
const GUID* pguid;
pChildData->GetType( &pguid );
if( TID_D3DRMTextureFilename == *pguid )
{
TCHAR** string;
if( FAILED( pChildData->GetData( NULL, &dwSize, (VOID**)&string ) ) )
return NULL;
D3DTextr_CreateTextureFromFile( *string );
lstrcpyn( strTexture, *string, 128 );
}
pChildData->Release();
}
pChildObj->Release();
}
pMesh->SetMaterialData( dwMaterial, &mtrl, strTexture );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT ParseMeshMaterialList( LPDIRECTXFILEDATA pFileData,
CD3DFileObject* pMesh )
{
LPDIRECTXFILEOBJECT pChildObj;
LPDIRECTXFILEDATA pChildData;
LPDIRECTXFILEDATAREFERENCE pChildDataRef;
DWORD dwMaterial = 0;
while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
{
if( SUCCEEDED( pChildObj->QueryInterface( IID_IDirectXFileData,
(VOID**)&pChildData) ) )
{
const GUID* pguid;
pChildData->GetType( &pguid );
if( TID_D3DRMMaterial == *pguid )
{
ParseMaterial(pChildData, pMesh, dwMaterial++);
}
pChildData->Release();
}
if( SUCCEEDED( pChildObj->QueryInterface( IID_IDirectXFileDataReference,
(VOID**)&pChildDataRef) ) )
{
if( SUCCEEDED( pChildDataRef->Resolve( &pChildData ) ) )
{
const GUID* pguid;
pChildData->GetType( &pguid );
if( TID_D3DRMMaterial == *pguid )
{
ParseMaterial( pChildData, pMesh, dwMaterial++ );
}
pChildData->Release();
}
pChildDataRef->Release();
}
pChildObj->Release();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT ParseMesh( LPDIRECTXFILEDATA pFileData, CD3DFileObject* pParentFrame )
{
DWORD dwNameLen=80;
TCHAR strName[80];
if( FAILED( pFileData->GetName( strName, &dwNameLen ) ) )
return E_FAIL;
// Read the Mesh data from the file
LONG pData;
DWORD dwSize;
if( FAILED( pFileData->GetData( NULL, &dwSize, (VOID**)&pData ) ) )
return E_FAIL;
DWORD dwNumVertices = *((DWORD*)pData); pData += 4;
D3DVECTOR* pVertices = ((D3DVECTOR*)pData); pData += 12*dwNumVertices;
DWORD dwNumFaces = *((DWORD*)pData); pData += 4;
DWORD* pFaceData = (DWORD*)pData;
// Create the Mesh object
CD3DFileObject* pMesh = new CD3DFileObject( strName );
pMesh->SetMeshGeometry( pVertices, dwNumVertices, pFaceData, dwNumFaces );
BOOL bHasNormals = FALSE;
BOOL bHasMaterials = FALSE;
// Enumerate child objects.
LPDIRECTXFILEOBJECT pChildObj;
while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
{
LPDIRECTXFILEDATA pChildData;
if( SUCCEEDED( pChildObj->QueryInterface( IID_IDirectXFileData,
(VOID**)&pChildData ) ) )
{
const GUID* pGUID;
LONG pData;
DWORD dwSize;
pChildData->GetType( &pGUID );
if( FAILED( pChildData->GetData( NULL, &dwSize, (VOID**)&pData ) ) )
{
delete pMesh;
return NULL;
}
if( TID_D3DRMMeshMaterialList == *pGUID )
{
DWORD dwNumMaterials = *((DWORD*)pData); pData += 4;
DWORD dwNumMatFaces = *((DWORD*)pData); pData += 4;
DWORD* pMatFace = (DWORD*)pData;
if( dwNumMaterials == 1 || dwNumMatFaces != dwNumFaces )
{
// Only one material add all faces at once
pMesh->AddFace( 0, pFaceData, dwNumFaces );
}
else
{
// Multiple materials, add in sorted order
for( DWORD mat=0; mat<dwNumMaterials; mat++ )
{
for( DWORD face=0; face<dwNumMatFaces; face++ )
{
if( pMatFace[face] == mat )
pMesh->AddFace( mat, GetFace( pFaceData, face ), 1 );
}
}
}
ParseMeshMaterialList( pChildData, pMesh );
bHasMaterials = TRUE;
}
if( TID_D3DRMMeshNormals == *pGUID )
{
DWORD dwNumNormals = *((DWORD*)pData);
D3DVECTOR* pNormals = (D3DVECTOR*)(pData+4);
if( dwNumNormals == dwNumVertices )
{
pMesh->SetNormals( pNormals );
bHasNormals = TRUE;
}
}
if( TID_D3DRMMeshTextureCoords == *pGUID )
{
// Copy the texture coords into the mesh's vertices
DWORD dwNumTexCoords = *((DWORD*)pData);
FLOAT* pTexCoords = (FLOAT*)(pData+4);
if( dwNumTexCoords == dwNumVertices )
pMesh->SetTextureCoords( pTexCoords );
}
pChildData->Release();
}
pChildObj->Release();
}
if( FALSE == bHasMaterials )
pMesh->AddFace( 0, pFaceData, dwNumFaces );
if( FALSE == bHasNormals )
pMesh->ComputeNormals();
pParentFrame->AddChild( pMesh );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT ParseFrame( LPDIRECTXFILEDATA pFileData, CD3DFileObject* pParentFrame )
{
DWORD dwNameLen=80;
TCHAR strName[80];
if( FAILED( pFileData->GetName( strName, &dwNameLen ) ) )
return E_FAIL;
CD3DFileObject* pFrame = new CD3DFileObject( strName );
// Enumerate child objects.
LPDIRECTXFILEOBJECT pChildObj;
while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
{
LPDIRECTXFILEDATA pChildData;
if( SUCCEEDED( pChildObj->QueryInterface( IID_IDirectXFileData,
(VOID**)&pChildData ) ) )
{
const GUID* pGUID;
pChildData->GetType( &pGUID );
if( TID_D3DRMFrame == *pGUID )
ParseFrame( pChildData, pFrame );
if( TID_D3DRMMesh == *pGUID )
ParseMesh( pChildData, pFrame );
if( TID_D3DRMFrameTransformMatrix == *pGUID )
{
DWORD dwSize;
VOID* pData;
if( FAILED( pChildData->GetData( NULL, &dwSize, &pData ) ) )
{
delete pFrame;
return NULL;
}
if( dwSize == sizeof(D3DMATRIX) )
{
// Convert from a left- to a right-handed cordinate system
D3DMATRIX* pmatFrame = (D3DMATRIX*)pData;
pmatFrame->_13 *= -1.0f;
pmatFrame->_31 *= -1.0f;
pmatFrame->_23 *= -1.0f;
pmatFrame->_32 *= -1.0f;
pmatFrame->_43 *= -1.0f;
pFrame->SetMatrix( pmatFrame );
}
}
pChildData->Release();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -