3Dプログラミング基本 1-4

別モデルのロードと表示

まずは以下のリンクから、別モデル(hedra.x)のデータをダウンロードしてほしい。

データは、現在作業中のフォルダに貼り付けること。


URL:

1-4-1.モデルの追加ロード

CDXUTMesh       *h_mesh;                    //  モデルを扱うポインタ変数			
D3DXMATRIX      h_matrix;                   //  別モデルのマトリクス			
#define CHILD_DISTANCE 4.0f                 //  表示モデルの距離。今回は定数を使用			
D3DXVECTOR3     h_rot = D3DXVECTOR3(0,0,0); //  回転			
        
h_mesh = new CDXUTMesh();                           // モデルを実体化しポインタを取得			
h_mesh->Create(DXUTGetD3DDevice(),_T("hedra.x"));   // モデルのロード(これは描画用でない)			
h_mesh->RestoreDeviceObjects(DXUTGetD3DDevice());   // 描画用モデルの作成		
        

▲TOP

1-4-2.モデルの表示

DXUTGetD3DDevice()->SetTransform(D3DTS_WORLD, &h_matrix);   //  マトリクスのセット	
h_mesh->Render( DXUTGetD3DDevice() );                       //  表示	
        
  

▲TOP

1-4-3.モデルの公転処理

//  別モデルの回転量を加算		
h_rot.y += 0.02f;												
        
//  別モデルのマトリクス作成											
D3DXMatrixTranslation( &h_matrix , CHILD_DISTANCE , 0 ,0 ); //  別モデルの移動マトリクスの作成			
D3DXMatrixRotationY(&t_matrix,h_rot.y);                     //  別モデルの回転マトリクスの作成			
											
//  ここで移動マトリクスと回転マトリクスを合成する										
//  合成の手順のイメージとしては「移動してから回転」するのか「回転してから移動」するのかでよく考えること										
											
h_matrix = h_matrix * t_matrix * g_matrix;
											
//  h_matrix = t_matrix * h_matrix * g_matrix;  //  こちらは間違いの処理	
                                                //  なぜ間違いなのか考えながら、			
                                                //  試しにやってみてほしい。											
        
//  モデルの解放		
SAFE_DELETE( h_mesh );										
        
  

▲TOP

1-4-4.プログラミング

※追加箇所はマーカーで表記

//--------------------------------------------------------------------------------------													
// File: EmptyProject.cpp													
//													
// Empty starting point for new Direct3D applications													
//													
// Copyright (c) Microsoft Corporation. All rights reserved.													
//--------------------------------------------------------------------------------------													
#include "dxstdafx.h"													
#include "resource.h"													
													
//	フォント変数												
LPD3DXFONT pFont;													
																									
//変数宣言													
CDXUTMesh       *g_mesh;                        //  モデルを扱うポインタ変数						
D3DXVECTOR3     g_pos = D3DXVECTOR3(0,0,0);     //  座標						
D3DXVECTOR3     g_rot = D3DXVECTOR3(0,0,0);     //  回転						
D3DXVECTOR3     g_scal = D3DXVECTOR3(1,1,1);    //  拡大縮小						
D3DXMATRIX      g_matrix;                       //  上記の3変数をまとめて管理する行列変数						
													
#define CHILD_DISTANCE 4.0f//モデル間の距離。今回は定数を使用					
CDXUTMesh       *h_mesh;                        //  モデルを扱うポインタ変数						
D3DXMATRIX      h_matrix;                       //  別モデルのマトリクス						
D3DXVECTOR3     h_rot = D3DXVECTOR3(0,0,0);     //  回転						
//--------------------------------------------------------------------------------------													
// Rejects any devices that aren't acceptable by returning false													
//--------------------------------------------------------------------------------------													
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 													
                                  D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )													
{													
    // Typically want to skip backbuffer formats that don't support alpha blending													
    IDirect3D9* pD3D = DXUTGetD3DObject(); 													
    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,													
                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 													
                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )													
        return false;													
													
    return true;													
}													
													
//--------------------------------------------------------------------------------------													
// Before a device is created, modify the device settings as needed													
//--------------------------------------------------------------------------------------													
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )													
{													
    return true;													
}													
													
//--------------------------------------------------------------------------------------													
// Create any D3DPOOL_MANAGED resources here 													
//--------------------------------------------------------------------------------------													
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )													
{													
    return S_OK;													
}													
													
//--------------------------------------------------------------------------------------													
// Create any D3DPOOL_DEFAULT resources here 													
//--------------------------------------------------------------------------------------													
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 													
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )													
{													
    return S_OK;													
}															
        

↓ Handle updates to the scene

//--------------------------------------------------------------------------------------													
// Handle updates to the scene													
//--------------------------------------------------------------------------------------													
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )													
{													
	D3DXMATRIX t_matrix;        //  作業用行列変数						
													
	//キーボード入力												
	if(DXUTIsKeyDown(VK_UP))    //  上キー入力							
	{												
		g_pos.z += 0.2f;        //  Z方向に0.2f分加算							
	}												
	if(DXUTIsKeyDown(VK_DOWN))  //  下キー入力							
	{												
		g_pos.z -= 0.2f;        //  Z方向に0.2f分減算							
	}												
	if(DXUTIsKeyDown(VK_RIGHT)) //  右キー入力							
	{												
		g_pos.x += 0.2f;        //  X方向に0.2f分加算							
	}												
	if(DXUTIsKeyDown(VK_LEFT))  //  左キー入力							
	{												
		g_pos.x -= 0.2f;        //  X方向に0.2f分減算							
	}												
													
	if(DXUTIsKeyDown(VK_SHIFT)) //  SHIFTキー入力							
	{												
		//  ピッチ(X軸回転)											
		if(DXUTIsKeyDown('Q'))  //  Qキー入力							
		{											
			g_rot.x += 0.2f;    //  X軸方向に0.2f分加算回転							
		}											
		if(DXUTIsKeyDown('W'))  //  Wキー入力							
		{											
			g_rot.x -= 0.2f;    //  X軸方向に0.2f分減算回転							
		}											
		//  ヨー(Y軸回転)											
		if(DXUTIsKeyDown('A'))  //  Aキー入力							
		{											
			g_rot.y += 0.2f;    //  Y軸方向に0.2f分加算回転							
		}											
		if(DXUTIsKeyDown('S'))  //  Sキー入力							
		{											
			g_rot.y -= 0.2f;    //  Y軸方向に0.2f分減算回転							
		}											
		//  ロール(Z軸回転)											
		if(DXUTIsKeyDown('Z'))  //  Zキー入力							
		{											
			g_rot.z += 0.2f;    //  Z軸方向に0.2f分加算回転							
		}											
		if(DXUTIsKeyDown('X')   //  Xキー入力							
		{											
			g_rot.z -= 0.2f;    //  Z軸方向に0.2f分減算回転							
		}											
	}												
	else												
	{												
		//  X軸拡縮											
		if(DXUTIsKeyDown('Q'))  //  Qキー入力							
		{											
			g_scal.x += 0.2f;   //  X方向に0.2f分拡大							
		}											
		if(DXUTIsKeyDown('W'))  //  Wキー入力							
		{											
			g_scal.x -= 0.2f;   //  X方向に0.2f分縮小							
		}											
		//Y軸拡縮											
		if(DXUTIsKeyDown('A'))  //  Aキー入力							
		{											
			g_scal.y += 0.2f;   //  Y方向に0.2f分拡大							
		}											
		if(DXUTIsKeyDown('S'))  //  Sキー入力							
		{											
			g_scal.y -= 0.2f;   //  Y方向に0.2f分縮小							
		}											
		//Z軸拡縮											
		if(DXUTIsKeyDown('Z'))  //  Zキー入力							
		{											
			g_scal.z += 0.2f;   //  Z方向に0.2f分拡大							
		}											
		if(DXUTIsKeyDown('X'))  //  Xキー入力							
		{											
			g_scal.z -= 0.2f;   //  Z方向に0.2f分縮小							
		}											
	}												
													
	//  別モデルの回転量を加算												
	h_rot.y += 0.02f;												
													
	//  モデルを表示するためのマトリクス作成											
	D3DXMatrixTranslation(&g_matrix , g_pos.x , g_pos.y ,g_pos.z);  //  移動マトリクスの作成			
	D3DXMatrixScaling(&t_matrix , g_scal.x , g_scal.y ,g_scal.z);   //  拡大縮小マトリクスの作成
		
	//  ここで移動マトリクスと拡大縮小マトリクスを合成する											
	g_matrix = t_matrix * g_matrix;	
	D3DXMatrixRotationYawPitchRoll(&t_matrix , g_rot.y , g_rot.x , g_rot.z);    //  回転マトリクスの作成

	//  ここで移動&拡大縮小マトリクスと回転マトリクスを合成する											
	g_matrix = t_matrix * g_matrix;												
													
	//  別モデルのマトリクス作成												
	D3DXMatrixTranslation( &h_matrix , CHILD_DISTANCE , 0 ,0 );     //  別モデルの移動マトリクスの作成			
	D3DXMatrixRotationY(&t_matrix,h_rot.y);                         //  別モデルの回転マトリクスの作成			
													
	//  ここで移動マトリクスと回転マトリクスを合成する											
	//  合成の手順のイメージとしては「移動してから回転」するのか「回転してから移動」するのかでよく考えること											
													
	h_matrix = h_matrix * t_matrix * g_matrix;												
	//  h_matrix = t_matrix * h_matrix * g_matrix;    //  こちらは間違いだが、			
                                                    //  なぜ間違いなのか考えながら、			
                                                    //  試してみてほしい			
}										
        

↓ Render the scene

//--------------------------------------------------------------------------------------												
// Render the scene 												
//--------------------------------------------------------------------------------------												
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )												
{												
    HRESULT hr;												
												
    //  Clear the render target and the zbuffer 												
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );												
												
    //  Render the scene												
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )												
    {												
		//  モデルの表示									
		DXUTGetD3DDevice()->SetTransform(D3DTS_WORLD, &g_matrix);   // マトリクスのセット		
		g_mesh->Render( DXUTGetD3DDevice() );										
												
		DXUTGetD3DDevice()->SetTransform(D3DTS_WORLD, &h_matrix);   // マトリクスのセット		
		h_mesh->Render( DXUTGetD3DDevice() );			
												
		//  文字列の準備と生成・表示									
		TCHAR str[255];										
		RECT rect;										
												
		SetRect( &rect , 0,0,640,480);										
		_stprintf( str ,_T("座標:%.2f %.2f %.2f"),g_pos.x , g_pos.y ,g_pos.z);										
		pFont->DrawText( NULL,str,-1,&rect,NULL,D3DCOLOR_RGBA(255,255,255,255));										
		SetRect( &rect , 0,20,640,480);										
		_stprintf( str ,_T("拡大縮小:%.2f %.2f %.2f"),g_scal.x , g_scal.y ,g_scal.z);										
		pFont->DrawText( NULL,str,-1,&rect,NULL,D3DCOLOR_RGBA(255,255,255,255));										
		SetRect( &rect , 0,40,640,480);										
		_stprintf( str ,_T("回転:%.2f %.2f %.2f"),g_rot.x , g_rot.y ,g_rot.z);										
		pFont->DrawText( NULL,str,-1,&rect,NULL,D3DCOLOR_RGBA(255,255,255,255));										
																						
		V( pd3dDevice->EndScene() );										
    }												
}												
												
//--------------------------------------------------------------------------------------												
// Handle messages to the application 												
//--------------------------------------------------------------------------------------												
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 												
                          bool* pbNoFurtherProcessing, void* pUserContext )												
{												
    return 0;												
}												
												
//--------------------------------------------------------------------------------------												
// Release resources created in the OnResetDevice callback here 												
//--------------------------------------------------------------------------------------												
void CALLBACK OnLostDevice( void* pUserContext )												
{												
}												
												
//--------------------------------------------------------------------------------------												
// Release resources created in the OnCreateDevice callback here												
//--------------------------------------------------------------------------------------												
void CALLBACK OnDestroyDevice( void* pUserContext )												
{												
	//  3Dモデルの解放										
	SAFE_DELETE( g_mesh );											
	SAFE_DELETE( h_mesh );											
												
	//  フォント変数の解放											
	SAFE_RELEASE( pFont );											
}												
												
//  アプリケーション初期化関数											
void InitApp( void )												
{												
	//  モデルのロード										
	g_mesh = new CDXUTMesh();                           //  モデルを実体化しポインタを取得			
	g_mesh->Create(DXUTGetD3DDevice(),_T("isu.x"));     //  モデルのロード(これは描画用でない)			
	g_mesh->RestoreDeviceObjects(DXUTGetD3DDevice());   //  描画用モデルの作成			
												
	h_mesh = new CDXUTMesh();                           //  モデルを実体化しポインタを取得			
	h_mesh->Create(DXUTGetD3DDevice(),_T("hedra.x"));   //  モデルのロード(これは描画用でない)			
	h_mesh->RestoreDeviceObjects(DXUTGetD3DDevice());   //  描画用モデルの作成			
												
	/////////////////////////////////////////////////////////////////////////////////////////////											
	//  3D環境の設定										
	//  カメラセット										
	D3DXMATRIX matview;//カメラ情報を格納するための行列変数
						
	//  注視マトリクスの生成  (順番に、カメラ位置、注視点、上方向の定義)					
	D3DXMatrixLookAtLH( &matview , &D3DXVECTOR3(0,10,-10),&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,1,0));											
	DXUTGetD3DDevice()->SetTransform(D3DTS_VIEW,&matview);//マトリクスのセット			
												
	//  プロジェクション(パース)の生成										
	D3DXMATRIX matproj;     //  プロジェクション情報を格納するための行列変数
			
	//  注視マトリクスの生成  (順番に、行列変数、視野角、アスペクト比、クリッピング領域(前方、後方))							
	D3DXMatrixPerspectiveFovLH ( &matproj , D3DXToRadian(45),640.0f/480.0f , 0.1f,2000.0f);											
	DXUTGetD3DDevice()->SetTransform(D3DTS_PROJECTION,&matproj);    //  マトリクスのセット		
												
	//  ライトon  ライトを有効にすればデフォルト値で初期化される。											
	DXUTGetD3DDevice()->LightEnable(0,true);											
}												
												
//--------------------------------------------------------------------------------------												
// Initialize everything and go into a render loop												
//--------------------------------------------------------------------------------------												
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )												
{											
//  Enable run-time memory check for debug builds.												
#if defined(DEBUG) | defined(_DEBUG)												
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );												
#endif												
												
    //  Set the callback functions												
    DXUTSetCallbackDeviceCreated( OnCreateDevice );												
    DXUTSetCallbackDeviceReset( OnResetDevice );												
    DXUTSetCallbackDeviceLost( OnLostDevice );												
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );												
    DXUTSetCallbackMsgProc( MsgProc );												
    DXUTSetCallbackFrameRender( OnFrameRender );												
    DXUTSetCallbackFrameMove( OnFrameMove );												
   												
    //  TODO: Perform any application-level initialization here												
												
    //  Initialize DXUT and create the desired Win32 window and Direct3D device for the application												
    DXUTInit( true, true, true );           //  Parse the command line, handle the default hotkeys, and show msgboxes												
    DXUTSetCursorSettings( true, true );    //  Show the cursor and clip it when in full screen												
    DXUTCreateWindow( _T("EmptyProject") );												
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );												
												
//  フォントの作成											
D3DXCreateFont( DXUTGetD3DDevice(),												
	16,											
	0,											
	FW_NORMAL,											
	1,											
	false,											
	DEFAULT_CHARSET,											
	OUT_DEFAULT_PRECIS,											
	DEFAULT_QUALITY,											
	DEFAULT_PITCH,											
	_T(""),											
	&pFont);											
												
//  アプリケーションの初期化												
InitApp();												
												
    //  Start the render loop												
    DXUTMainLoop();												
												
    //  TODO: Perform any application-level cleanup here												
												
    return DXUTGetExitCode();												
}									
        
 

1-1-4.動作確認

緑の物体が椅子の周りを回れば、完了です。


1-1-4 動作確認

↓参考動画


▲TOP

>「1-5 キャラの向いている方向への移動(ラジコン移動)」へ続く