3Dプログラミング基本 2-5

ビルボード処理

ビルボード処理については、以下のページの冒頭辺りを参照してほしい。


http://wgld.org/d/webgl/w035.html

上記ページの説明にもある通り、爆発や煙などの特殊効果や木や岩などの自然物、

さらにはUI(ユーザインタフェース)にも利用する。

2D系の処理はこちらを利用するので、必ずマスターしてほしい。


ここで注意が必要なのが、3D系の座標と2D系の座標の考え方の違いである。

ここまでの説明でも確認した通り、3DではY軸は上方向が正で下方向が負である。

しかし、2D画像は原点が左上で、Y軸は上方向が負で下方向が正となっている。

どこかで補正する必要があり、元画像を上下反転しておくのが一番簡単。

では、必要なプログラムを見ていこう。

※ここでは、3Dモデルの表示まで終わっているものとして話を進める。

2-5-1.変数宣言

D3DXMATRIX          g_matrix;   //  ワールド行列		
LPD3DXSPRITE        pSprite;    //  スプライト管理変数		
LPDIRECT3DTEXTURE9  tex;        //  テクスチャロード変数		
        

▲TOP

2-5-2.2Dロード・表示・解放

//  2D表示のための処理							
//  ビュー行列の取得							
D3DXMATRIX matview;							
DXUTGetD3DDevice()->GetTransform(D3DTS_VIEW , &matview);							
							
//  スプライトに対し、ワールド行列とビュー行列のセットをBegin()前に実行すること							
pSprite->SetWorldViewLH(&g_matrix,&matview);							
							
//  スプライト開始 							
//引数には D3DXSPRITE_BILLBOARD を ビット演算子OR で追加指定							
pSprite->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_BILLBOARD);							
							
//  大きさの調整							
//  そのままでは大きすぎるため							
D3DXMATRIX mat_s;							
D3DXMatrixScaling( &mat_s ,0.02f,0.02f,0.02f );							
pSprite->SetTransform( &mat_s );							
							
//  描画							
pSprite->Draw( tex,NULL,NULL,NULL,D3DCOLOR_RGBA(255,255,255,255));							
pSprite->End();							
        
//  スプライトの初期化								
D3DXCreateSprite(DXUTGetD3DDevice(),&pSprite);								
								
//  画像ファイルのロード								
D3DXCreateTextureFromFile(DXUTGetD3DDevice(),L"EmptyProject.jpg",&tex);								
								
//  ワールド行列作成							
D3DXMatrixTranslation( &g_matrix , 0.0f, 0.0f, 0.0f);		
        
SAFE_RELEASE( tex );        //  テクスチャを先に解放				
SAFE_RELEASE( pSprite );    //  テクスチャ解放後に、スプライト管理変数を解放		
        
  

▲TOP

2-5-3.プログラミング

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

※EmptyProject.jpgはもとから制作フォルダに入っている画像を利用する。

//--------------------------------------------------------------------------------------													
// 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;													
													
//  3Dメッシュ変数と関連変数 												
CDXUTMesh           *g_mesh;    //  メッシュを扱うポインタ変数					
D3DXMATRIX          g_matrix;   //  ワールド行列						
LPD3DXSPRITE        pSprite;    //  スプライト管理変数						
LPDIRECT3DTEXTURE9  tex;        //  テクスチャロード変数						
													
//--------------------------------------------------------------------------------------													
// 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													
//--------------------------------------------------------------------------------------													
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )													
{													
}											
        

↓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() ) )												
    {												
	//  メッシュのレンダリング										
	g_mesh->Render( DXUTGetD3DDevice() );											
												
	//  2D表示のための処理											
	//  ビュー行列の取得											
	D3DXMATRIX matview;											
	DXUTGetD3DDevice()->GetTransform(D3DTS_VIEW , &matview);											
												
	//  スプライトに対し、ワールド行列とビュー行列のセットをBegin()前に実行すること											
	pSprite->SetWorldViewLH(&g_matrix,&matview);											
												
	//  スプライト開始 											
	//引数には D3DXSPRITE_BILLBOARD を ビット演算子OR で追加指定											
	pSprite->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_BILLBOARD);											
												
	//  大きさの調整											
	//  そのままでは大きすぎるため											
	D3DXMATRIX mat_s;											
	D3DXMatrixScaling( &mat_s ,0.02f,0.02f,0.02f );											
	pSprite->SetTransform( &mat_s );											
												
	//  描画											
	pSprite->Draw( tex,NULL,NULL,NULL,D3DCOLOR_RGBA(255,255,255,255));											
	pSprite->End();											
												
	//  文字列の準備と生成										
	TCHAR str[255];											
	RECT rect;											
												
	SetRect( &rect , 0,0,640,480);											
	_stprintf( str ,L"ビルボード処理");											
	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

//--------------------------------------------------------------------------------------												
// Release resources created in the OnCreateDevice callback here												
//--------------------------------------------------------------------------------------												
void CALLBACK OnDestroyDevice( void* pUserContext )												
{												
	//  3Dメッシュの解放										
	SAFE_DELETE( g_mesh );											
	SAFE_RELEASE( pFont );											
												
	SAFE_RELEASE( tex );											
	SAFE_RELEASE( pSprite );											
}												
												
//  アプリケーション初期化関数											
void InitApp( void )												
{												
	//  メッシュのロード										
	g_mesh = new CDXUTMesh();                           //  メッシュを実体化しポインタを取得			
	g_mesh->Create(DXUTGetD3DDevice(),L"isu.x");        //  メッシュのロード(これは描画用でない)			
	g_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);											
												
	//  スプライトの初期化											
	D3DXCreateSprite(DXUTGetD3DDevice(),&pSprite);											
												
	//  画像ファイルのロード											
	D3DXCreateTextureFromFile(DXUTGetD3DDevice(),L"EmptyProject.jpg",&tex);											
												
	//  ワールド行列作成										
	D3DXMatrixTranslation( &g_matrix , 0.0f, 0.0f, 0.0f);											
}												
												
//--------------------------------------------------------------------------------------												
// 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( L"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,											
	L"",											
	&pFont);											
												
//  アプリケーションの初期化												
InitApp();												
												
    //  Start the render loop												
    DXUTMainLoop();												
												
    //  TODO: Perform any application-level cleanup here												
												
    return DXUTGetExitCode();												
}									
        
  

2-5-4.動作確認

↓椅子の奥側に2D画像が表示されれば完了です。


2-5-4 動作確認

> 完成例の実行ファイルはここからダウンロード

▲TOP

>「2-6 レイピッキングによる当たり判定」へ続く