Dirext3DX UtilityLibrary を使う 2 Xファイルをロードして表示する

66のプロジェクトを利用した場合の、Xファイルをロードして表示するソースは以下のとおり。

赤い部分を追加する。
 

///------------------------------------------------------
// File: XFile.cpp
// Note: This code uses the D3D Framework helper library.
//-------------------------------------------------------
#define STRICT
#define D3D_OVERLOADS
#include <windows.h>
#include <commdlg.h>
#include <math.h>
#include <stdio.h>
#include "D3DApp.h"
#include "D3DTextr.h"
#include "D3DUtil.h"
#include "D3DMath.h"
#include "D3DFile.h"
//#include "resource.h"
 
#define IDM_LOADFILE 300
 
//------------------------------------------------------
// Name: class CMyD3DApplication
//------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
 CD3DFile* m_pFileObject;
 FLOAT m_fObjectRadius;
 FLOAT m_fEyeDistance;

 
 D3DMATRIX m_matSave;
 D3DMATRIX m_matRotate;
 BOOL m_fLMouseCapture;
 POINT m_ptCursorCenter;
 
 BOOL m_bCull;
 BOOL m_bFlat;
 BOOL m_bWire;

 
 HRESULT LoadFile();
 
 protected:
 HRESULT OneTimeSceneInit();
 HRESULT InitDeviceObjects();
 HRESULT DeleteDeviceObjects();
 HRESULT Render();
 HRESULT FrameMove( FLOAT fTimeKey );
 HRESULT FinalCleanup();
 
 public:
 CMyD3DApplication();
 
 LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
};
 
//----------------------------------------------------
// Name: WinMain()
//----------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
 CMyD3DApplication d3dApp;
 
 if( FAILED( d3dApp.Create( hInst, strCmdLine ) ) )
  return 0;
 
return d3dApp.Run();
}
 
//---------------------------------------------------
// Name: CMyD3DApplication()
//---------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
:CD3DApplication()
{
 m_strWindowTitle = TEXT( "XFile: Loading .X files in D3DIM" );
 m_bAppUseZBuffer = TRUE;
 m_bShowStats = TRUE;
 m_fnConfirmDevice = NULL;
 
 m_pFileObject = NULL;
 m_fObjectRadius = 0.0f;
 m_fEyeDistance = 0.0f;
 m_bCull = TRUE;
 m_bFlat = FALSE;
 m_bWire = FALSE;
 m_fLMouseCapture = FALSE;

}
 
//----------------------------------------------------
// 初期化
//----------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
 D3DUtil_SetIdentityMatrix( m_matSave );
 D3DUtil_SetIdentityMatrix( m_matRotate );

 return S_OK;
}
 
//----------------------------------------------------
// シーンを組み立てる(演算)
//----------------------------------------------------
HRESULT CMyD3DApplication::FrameMove( FLOAT fTimeKey )
{
// Use mouse input to setup the world matrix
if( m_fLMouseCapture )
{
 POINT ptCursor;
 GetCursorPos( &ptCursor );

 
 int dx = ptCursor.x - m_ptCursorCenter.x;
 int dy = ptCursor.y - m_ptCursorCenter.y;

 
 D3DMATRIX mX,mY;
 D3DUtil_SetRotateYMatrix( mX, -dx * 2.0f * g_PI / 512.0f );
 D3DUtil_SetRotateXMatrix( mY, dy * 2.0f * g_PI / 512.0f );
 D3DMath_MatrixMultiply( m_matRotate, mY, mX );
 D3DMath_MatrixMultiply( m_matRotate, m_matRotate, m_matSave );
}
else
 m_matSave = m_matRotate;

 
// Set the object's world matrix
m_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &m_matRotate );

 
// Adjust the camera position
D3DVECTOR vEyePt = D3DVECTOR( 0.0f, 0.0f, 0.0f );
D3DVECTOR vLookatPt = D3DVECTOR( 0.0f, 0.0f, 0.0f );
D3DVECTOR vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f );
vEyePt.z += m_fObjectRadius*3.0f + m_fObjectRadius*m_fEyeDistance;
 
// Set the view matrix
D3DMATRIX matView;
D3DUtil_SetViewMatrix( matView, vEyePt, vLookatPt, vUpVec );
m_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );

 
// Just for kicks, demonstrate the feature to find a frame and animate it.
// Here, if the user loads a file with a frame named "prop" (such as
// "triplane.x"), this code will find the matrix for that frame and
// animate it.
if( m_pFileObject )
{
 CD3DFileObject* pObject = m_pFileObject->FindObject( "prop" );
 if( pObject )
 {
  D3DMATRIX* pmat = pObject->GetMatrix();
  D3DUtil_SetRotateZMatrix( *pmat, 5.0f*fTimeKey );
 }
}

 return S_OK;
}
 
//---------------------------------------------------
// 描画
//---------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
 // Clear the viewport
 m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
 0x000000ff, 1.0f, 0L );
 
 DWORD dwCullMode = m_bCull ? D3DCULL_CCW : D3DCULL_NONE;
 DWORD dwShadeMode = m_bFlat ? D3DSHADE_FLAT : D3DSHADE_GOURAUD;
 DWORD dwFillMode = m_bWire ? D3DFILL_WIREFRAME : D3DFILL_SOLID;
 m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, dwCullMode );
 m_pd3dDevice->SetRenderState( D3DRENDERSTATE_SHADEMODE, dwShadeMode );
 m_pd3dDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, dwFillMode );

 
 // Begin the scene
if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
{
 if( m_pFileObject )
  m_pFileObject->Render( m_pd3dDevice ); // 読み込んだファイルの描画

 
 // End the scene.
 m_pd3dDevice->EndScene();
}

 return S_OK;
}
 
//----------------------------------------------------
// オブジェクトの初期化
//----------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
// Load a DirectX .X file the first time around
static BOOL bFirstInstance = TRUE;
 
if( bFirstInstance )
{
 Pause( TRUE );
 LoadFile();
 Pause( FALSE );
 bFirstInstance = FALSE;
}
// Setup a material
D3DMATERIAL7 mtrl;
D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
m_pd3dDevice->SetMaterial( &mtrl );

 
// Setup the textures
D3DTextr_RestoreAllTextures( m_pd3dDevice );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
m_pd3dDevice->SetRenderState( D3DRENDERSTATE_DITHERENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRENDERSTATE_SPECULARENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRENDERSTATE_NORMALIZENORMALS, TRUE );

 
// Set the projection matrix
D3DVIEWPORT7 vp;
m_pd3dDevice->GetViewport(&vp);
FLOAT fAspect = ((FLOAT)vp.dwHeight) / vp.dwWidth;

 
D3DMATRIX matProj;
D3DUtil_SetProjectionMatrix( matProj, g_PI/4, fAspect, 1.0f, m_fObjectRadius*10 );
m_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );

 
// Set up the light
if( m_pDeviceInfo->ddDeviceDesc.dwVertexProcessingCaps &
 D3DVTXPCAPS_DIRECTIONALLIGHTS )
{
 D3DLIGHT7 light;
 D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, 0.0f, -1.0f, -1.0f );
 m_pd3dDevice->SetLight( 0, &light );
 m_pd3dDevice->LightEnable( 0, TRUE );
 m_pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );
 m_pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0x00000000 );
}
else
 m_pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0xffffffff );

 return S_OK;
}
 
//---------------------------------------------------
// オブジェクトの消去
//---------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
 D3DTextr_InvalidateAllTextures();
 
 return S_OK;
}
 
//---------------------------------------------------
// 終了
//---------------------------------------------------
HRESULT CMyD3DApplication::FinalCleanup()
{
 SAFE_DELETE( m_pFileObject );
 return S_OK;
}
 
//---------------------------------------------------
// オブジェクトのサイズ変更
//---------------------------------------------------
BOOL CalcFileObjectSizeCB( CD3DFileObject* pObject, D3DMATRIX* pmat,
VOID* pContext )
{ FLOAT* pfRadius = (FLOAT*)pContext;
 D3DVERTEX* pVertices;
 DWORD dwNumVertices;

 
if( SUCCEEDED( pObject->GetMeshGeometry( &pVertices, &dwNumVertices,
 NULL, NULL ) ) )
{
for( DWORD i=0; i<dwNumVertices; i++ )
{
 FLOAT x = pVertices[i].x;
 FLOAT y = pVertices[i].y;
 FLOAT z = pVertices[i].z;

 
 FLOAT mx = x*pmat->_11 + y*pmat->_21 + z*pmat->_31 + pmat->_41;
 FLOAT my = x*pmat->_12 + y*pmat->_22 + z*pmat->_32 + pmat->_42;
 FLOAT mz = x*pmat->_13 + y*pmat->_23 + z*pmat->_33 + pmat->_43;

 
 // Store the largest r (radius) for any point in the mesh
 FLOAT r = sqrtf( mx*mx + my*my + mz*mz );
if( r > (*pfRadius) )
 (*pfRadius) = r;
}
}

// Keep enumerating file objects
return FALSE;
}
 
//----------------------------------------------------
// ファイルのロード
//----------------------------------------------------
HRESULT CMyD3DApplication::LoadFile()
{
 
static TCHAR strInitialDir[512] = "";
static TCHAR strFileName[512];
TCHAR strCurrentName[512] = "*.x";
 
if( '\0' == strInitialDir[0] )
 strcpy( strInitialDir, D3DUtil_GetDXSDKMediaPath() );

 
OPENFILENAME ofn = { sizeof(OPENFILENAME), m_hWnd, NULL,
"X Files (*.x)\0*.x\0\0",
NULL, 0, 1, strCurrentName, 512, strFileName, 512,
strInitialDir, "Open X File", OFN_FILEMUSTEXIST, 0, 1,
".X", 0, NULL, NULL };

 
// Run the OpenFileName dialog.
if( FALSE == GetOpenFileName( &ofn ) )
 return S_OK;

 
// Store the initial directory for next time
strcpy( strInitialDir, strCurrentName );
strstr( strInitialDir, strFileName )[0] = '\0';

 
CD3DFile* pFileObject = new CD3DFile();

if( FAILED( pFileObject->Load( strFileName ) ) )
{
 MessageBox( NULL, TEXT("Error loading specified X file"),
 TEXT("XFile"), MB_OK|MB_ICONERROR );
 return E_FAIL;
}

 
// If the file was successfully loaded, delete the old one and use this one
// instead.
SAFE_DELETE( m_pFileObject );
m_pFileObject = pFileObject;

 
// Get the new object position and size
D3DUtil_SetIdentityMatrix( m_matRotate );
D3DUtil_SetIdentityMatrix( m_matSave );
m_fObjectRadius = 0.0f;
m_pFileObject->EnumObjects( CalcFileObjectSizeCB, NULL, (VOID*)&m_fObjectRadius );

 
// Set the projection matrix
D3DVIEWPORT7 vp;
m_pd3dDevice->GetViewport(&vp);
FLOAT fAspect = ((FLOAT)vp.dwHeight) / vp.dwWidth;

 
D3DMATRIX matProj;
D3DUtil_SetProjectionMatrix( matProj, g_PI/4, fAspect, 1.0f, m_fObjectRadius*10 );
m_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );

 
// Restore the textures (if there's a device).
D3DTextr_RestoreAllTextures( m_pd3dDevice );

 
// Return successful
return S_OK;
}
 
//---------------------------------------------------
// Name: MsgProc()
// Desc: App custom WndProc function for handling mouse and keyboard input.
//---------------------------------------------------
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam )
{
switch( uMsg )
{
case WM_COMMAND:
 // Handle menu and key commands
switch( LOWORD(wParam) )
{
 
case IDM_LOADFILE:
 Pause( TRUE );
 LoadFile();
 Pause( FALSE );
 break;
}
break;
 
case WM_LBUTTONDOWN:
 break;
 
case WM_LBUTTONUP:
 // The user released the left mouse button
 break;
}
 
// Fall through to the app's main windows proc function
 return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
}
 

ビルドして実行し、ファイルの読み込みでXファイル(dolphin.x)を指定すると以下のように表示される。
dolphin.x はあなたのハードディスクのどこかにあるので検索してコピーしておく。
なければDirectxのインストールCDから持ってくる。