DirectXを使ったアニメーションについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
NONT

DirectXを使ったアニメーションについて

#1

投稿記事 by NONT » 9年前

コード:

//*********************************//
//*                               *//
//*   ポリゴン処理[polygon.cpp]    *//
//*                               *//
//*********************************//

//**********************//
//*   ヘッダファイル   *//
//**********************//
#include "main.h"
#include "polygon.h"

//******************//
//*   マクロ定義   *//
//******************//
#define POLYGON_TEXTURENAME "data/TEXTURE/number.png"

// ポリゴン表示位置X
#define POLYGON_POS_X ( 300 )
// ポリゴン表示位置Y
#define POLYGON_POS_Y ( 80 )
// ポリゴン幅
#define POLYGON_WIDTH ( 243 )
// ポリゴン高さ
#define POLYGON_HEIGHT ( 432 )

//************************//
//*   プロトタイプ宣言   *//
//************************//
HRESULT MakeVertexPolygon ( LPDIRECT3DDEVICE9 pDevice );          // 頂点の作成

//**********************//
//*   グローバル変数   *//
//**********************//
VERTEX_2D g_aVertex [ NUM_VERTEX ];
LPDIRECT3DTEXTURE9 g_pTexturePolygon = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVtxBufferPolygon = NULL;
float g_fOffset = 0.0f;

//******************//
//*   初期化処理   *//
//******************//
void InitPolygon ( void )
{
	LPDIRECT3DDEVICE9 pDevice = GetDevice();

	MakeVertexPolygon ( pDevice );

	// テクスチャの設定
	D3DXCreateTextureFromFile ( pDevice , POLYGON_TEXTURENAME , &g_pTexturePolygon );

	if ( FAILED ( D3DXCreateTextureFromFile ( pDevice , POLYGON_TEXTURENAME , &g_pTexturePolygon ) ) )
	{
		// エラーだったら
		MessageBox ( NULL , "テクスチャファイル読み込み失敗" , "ERROR" , MB_OK );
	}

	pDevice -> SetTexture ( 0 , g_pTexturePolygon );
	
	if ( FAILED ( pDevice -> SetTexture ( 0 , g_pTexturePolygon ) ) )
	{
		// エラーだったら
		MessageBox ( NULL , "ポリゴンへのテクスチャ設定失敗" , "ERROR" , MB_OK );
	}
}

//****************//
//*   終了処理   *//
//****************//
void UninitPolygon ( void )
{
	if ( g_pTexturePolygon != NULL )
	{
		// テクスチャポリゴンの解放
		g_pTexturePolygon -> Release ();
		g_pTexturePolygon = NULL;
	}
}

//****************//
//*   更新処理   *//
//****************//
void UpdatePolygon ( void )
{
	VERTEX_2D* pVtx;

	//バッファをロックし仮想アドレスを取得する
	g_pVtxBufferPolygon -> Lock( 
		                        0 , 
								0 , 
								( void** )&pVtx , 
								0 );

	// テクスチャ座標の設定
	pVtx [ 0 ].tex = D3DXVECTOR2 ( g_fOffset , 0.0f );
	pVtx [ 1 ].tex = D3DXVECTOR2 ( 0.2f + g_fOffset , 0.0f );
	pVtx [ 2 ].tex = D3DXVECTOR2 ( g_fOffset , 0.5f  );
	pVtx [ 3 ].tex = D3DXVECTOR2 ( 0.2f + g_fOffset , 0.5f  );

	g_fOffset += 0.01f;

	g_pVtxBufferPolygon -> Unlock();
}

//****************//
//*   描画処理   *//
//****************//
void DrawPolygon ( void )
{
	LPDIRECT3DDEVICE9 pDevice = GetDevice();

	// ストリームを通す
	pDevice -> SetStreamSource ( 0 , 
		                         g_pVtxBufferPolygon ,
		                         0 ,
		                         sizeof ( VERTEX_2D )		                       );

	// 頂点フォーマットの設定
	pDevice -> SetFVF ( FVF_VERTEX_2D );

	// ポリゴン描画
	pDevice -> DrawPrimitive ( D3DPT_TRIANGLESTRIP ,
		                      0 ,
							  NUM_POLYGON
							 );
}

//********************//
//*                  *//
//*   頂点作成関数   *//
//*                  *//
//********************//
HRESULT MakeVertexPolygon ( LPDIRECT3DDEVICE9 pDevice )
{
	// 頂点バッファの生成
	pDevice -> CreateVertexBuffer ( sizeof ( VERTEX_2D ) * NUM_VERTEX ,
		                            D3DUSAGE_WRITEONLY ,
									FVF_VERTEX_2D ,
									D3DPOOL_MANAGED ,
									&g_pVtxBufferPolygon , 
									NULL
		                           );
	
	// エラーチェック
	if ( FAILED ( pDevice -> CreateVertexBuffer ( sizeof ( VERTEX_2D ) * NUM_VERTEX , D3DUSAGE_WRITEONLY , FVF_VERTEX_2D , D3DPOOL_MANAGED , &g_pVtxBufferPolygon , NULL ) ) )
	{
		return E_FAIL;
	}

	// 構造体のポインタ宣言
	VERTEX_2D* pVtx;

	// バッファをロックし、仮想アドレスを取得
	g_pVtxBufferPolygon -> Lock ( 0 ,
		                          0 ,
								  ( void** )&pVtx ,
								  0 );

	// 頂点座標の設定(x,y,z座標)
	pVtx [ 0 ].pos = D3DXVECTOR3 ( POLYGON_POS_X , POLYGON_POS_Y , 0.0f );
	pVtx [ 1 ].pos = D3DXVECTOR3 ( POLYGON_POS_X + POLYGON_WIDTH , POLYGON_POS_Y , 0.0f );
	pVtx [ 2 ].pos = D3DXVECTOR3 ( POLYGON_POS_X , POLYGON_POS_Y + POLYGON_HEIGHT , 0.0f );
	pVtx [ 3 ].pos = D3DXVECTOR3 ( POLYGON_POS_X + POLYGON_WIDTH , POLYGON_POS_Y + POLYGON_HEIGHT , 0.0f );

	pVtx [ 0 ].rhw = 1.0f;
	pVtx [ 1 ].rhw = 1.0f;
	pVtx [ 2 ].rhw = 1.0f;
	pVtx [ 3 ].rhw = 1.0f;

	// 頂点色の設定
	pVtx [ 0 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );
	pVtx [ 1 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );
	pVtx [ 2 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );
	pVtx [ 3 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );

	// テクスチャ座標の設定
	pVtx [ 0 ].tex = D3DXVECTOR2 ( 0.0f , 0.0f );
	pVtx [ 1 ].tex = D3DXVECTOR2 ( 0.5f , 0.0f );
	pVtx [ 2 ].tex = D3DXVECTOR2 ( 0.0f , 0.5f );
	pVtx [ 3 ].tex = D3DXVECTOR2 ( 0.5f , 0.5f );

	g_pVtxBufferPolygon -> Unlock();

	return S_OK;
}

///////////////   EOF   ///////////////
[hr]
以下、main.cppです。

コード:

//**********************//
//*                    *//
//*   ヘッダファイル   *//
//*                    *//
//**********************//
#include "main.h"
#include "polygon.h"

//************************//
//*                      *//
//*   プロトタイプ宣言   *//
//*                      *//
//************************//
LRESULT CALLBACK WndProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
HRESULT Init ( HINSTANCE hInstance , HWND hWnd , BOOL bWindow );                        // 初期化処理
void Uninit ( void );             // 終了処理
void Update ( void );             // 更新処理
void Draw ( void );               // 描画処理

//**********************//
//*                    *//
//*   グローバル変数   *//
//*                    *//
//**********************//
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;

//******************//
//*                *//
//*   メイン処理   *//
//*                *//
//******************//
int APIENTRY WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nCmdShow )
{
	UNREFERENCED_PARAMETER ( hPrevInstance );
	UNREFERENCED_PARAMETER ( lpCmdLine );

	WNDCLASSEX wcex =
	{
		sizeof ( WNDCLASSEX ) ,
		CS_CLASSDC ,
		WndProc ,
		0 ,
		0 ,
		hInstance ,
		NULL ,
		LoadCursor ( NULL , IDC_ARROW ) ,
		( HBRUSH ) ( COLOR_WINDOW + 1 ) ,
		NULL ,
		CLASS_NAME ,
		NULL
	};

	// ウィンドウクラスの登録
	RegisterClassEx ( &wcex );

    static HWND hWnd;              //  ウィンドウハンドル
	static MSG msg;

	// ウィンドウスタイル定義
	const int wstyle = WS_OVERLAPPEDWINDOW &~ WS_MINIMIZEBOX &~ WS_MAXIMIZEBOX &~ WS_THICKFRAME;

	// 構造体定義
	RECT cr = { 0 , 0 , SCREEN_WIDTH , SCREEN_HEIGHT };
    AdjustWindowRect ( &cr , wstyle , FALSE );

	int ww = cr.right - cr.left;     // 画面(ウィンドウ表示)幅
	int wh = cr.bottom - cr.top;     // 画面(ウィンドウ表示)高

	// 初期ウィンドウ位置を真ん中に設定
	RECT dr;
    GetWindowRect ( GetDesktopWindow() , &dr );
    int dw = dr.right - dr.right;
    int dh = dr.bottom - dr.top;
    int wx = ww > dw ? 0: ( dw - ww ) / 2;
    int wy = wh > dh ? 0: ( dh - wh ) / 2;

    // ウィンドウを作成
	hWnd = CreateWindowEx ( 0 ,
		                    CLASS_NAME ,
							WINDOW_NAME ,
							wstyle ,
							wx ,
							wy ,
		                    ww ,
						    wh ,
							NULL ,
							NULL ,
							hInstance ,
							NULL
							);

	// ウィンドウの表示
	ShowWindow ( hWnd , nCmdShow );

	UpdateWindow ( hWnd );

	Init ( hInstance , hWnd , TRUE );                      // 初期化
	InitPolygon();                                         // ポリゴンの初期化

	// ゲームループ
	while ( GetMessage ( &msg , NULL , 0 , 0 ) )
	{
		for ( ;; )
		{
			if ( PeekMessage ( &msg , NULL , 0 , 0 , PM_REMOVE ) != 0 )
			{
				// Windowsの処理
				if ( msg.message == WM_QUIT )
				{
					break;
				}
				else
				{
					// メッセージの翻訳と送出
		            TranslateMessage ( &msg );
		            DispatchMessage ( &msg );
					break;
		  		}
			}
			else
			{
				    // DirectXの処理
				    Update ();          // 更新処理
				    Draw ();            // 描画処理
				}
			}
		}
	}

	timeEndPeriod ( 1 );
	Uninit ();                          // 終了処理

	return ( int ) msg.wParam;
}

LRESULT CALLBACK WndProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
	static HDC hDC;

	switch ( uMsg )
	{			  
		case WM_KEYDOWN:
		               if( wParam == VK_ESCAPE )
		               {
		                  UINT nID = MessageBox ( NULL , "ウィンドウを閉じますか?" , "Message" , MB_YESNO );

		                  if ( nID == IDYES )
		                  {
		                      DestroyWindow ( hWnd );
		                  } 
		               }

		               break;

	    case WM_DESTROY:
					   
			           PostQuitMessage ( 0 );

	    			   break;
	}

	return DefWindowProc ( hWnd , uMsg , wParam , lParam );
}

//******************//
//*                *//
//*   初期化関数   *//
//*                *//
//******************//
HRESULT Init ( HINSTANCE hInstance , HWND hWnd , BOOL bWindow )
{
	D3DPRESENT_PARAMETERS d3dpp;
	D3DDISPLAYMODE d3ddm;

	// D3D9インターフェースの取得
	g_pD3D = Direct3DCreate9 ( D3D_SDK_VERSION );

	if ( g_pD3D == NULL )
	{
		return E_FAIL;
	}

	// 現在のディスプレイモードの取得
	if ( FAILED ( g_pD3D -> GetAdapterDisplayMode ( D3DADAPTER_DEFAULT , &d3ddm ) ) )
	{
		return E_FAIL;
	}

	// デバイスのプレゼンテーションパラメータの設定
	ZeroMemory ( &d3dpp , sizeof ( d3dpp ) );

	d3dpp.BackBufferWidth = SCREEN_WIDTH;
	d3dpp.BackBufferHeight = SCREEN_HEIGHT;
	d3dpp.BackBufferFormat = d3ddm.Format;
	d3dpp.BackBufferCount = 1;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.Windowed = bWindow;	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;         
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

	// Direct3Dデバイスの作成
	if ( FAILED ( g_pD3D -> CreateDevice ( D3DADAPTER_DEFAULT ,
		                                   D3DDEVTYPE_HAL ,
						   hWnd ,										    
                                                   D3DCREATE_HARDWARE_VERTEXPROCESSING ,
						   &d3dpp ,
				                   &g_pD3DDevice ) ) )
	{
		if ( FAILED ( g_pD3D -> CreateDevice ( D3DADAPTER_DEFAULT ,
		                                   D3DDEVTYPE_HAL ,
                                                   hWnd ,
						   D3DCREATE_SOFTWARE_VERTEXPROCESSING ,										           &d3dpp ,
						   &g_pD3DDevice ) ) )
	    {
			if ( FAILED ( g_pD3D -> CreateDevice ( D3DADAPTER_DEFAULT ,
		                                   D3DDEVTYPE_REF ,
						   hWnd ,
		 				   D3DCREATE_SOFTWARE_VERTEXPROCESSING ,
	    				           &d3dpp ,
                                                   &g_pD3DDevice ) ) )
	        {
				return E_FAIL;
			}
		}
	}

	// レンダーステートの設定
	g_pD3DDevice -> SetRenderState ( D3DRS_CULLMODE , D3DCULL_CCW );

	// 半透明の設定(αブレンド)
	g_pD3DDevice -> SetRenderState ( D3DRS_ALPHABLENDENABLE , TRUE );
	g_pD3DDevice -> SetRenderState ( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
	g_pD3DDevice -> SetRenderState ( D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA );

	// サンプラーステートの設定
	g_pD3DDevice -> SetSamplerState ( 0 , D3DSAMP_MINFILTER , D3DTEXF_LINEAR );
	g_pD3DDevice -> SetSamplerState ( 0 , D3DSAMP_MAGFILTER , D3DTEXF_LINEAR );

	return S_OK;
}

//****************//
//*              *//
//*   終了処理   *//
//*              *//
//****************//
void Uninit ( void )
{
	if ( g_pD3DDevice != NULL )
	{
		// Direct3Dデバイスの解放
		g_pD3DDevice -> Release ();
		g_pD3DDevice = NULL;
	}
	
	if ( g_pD3D != NULL )
	{
		// Direct3Dインタフェースの解放
		g_pD3D -> Release ();
		g_pD3D = NULL;
	}
}

//****************//
//*              *//
//*   更新処理   *//
//*              *//
//****************//
void Update ( void )
{
	UpdatePolygon ();
}

//****************//
//*              *//
//*   描画関数   *//
//*              *//
//****************//
void Draw ( void )
{
	// バックバッファとZバッファのクリア
	g_pD3DDevice -> Clear ( 0 , 
		                    NULL , 
		                    D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER ,
		                    D3DCOLOR_RGBA ( 255 , 255 , 255 , 0 ) ,
		                    1.0f ,
		                    0
							);
	// 描画の開始
	if ( SUCCEEDED ( g_pD3DDevice -> BeginScene () ) )
	{
		// ポリゴン描画
		DrawPolygon();

		// 描画終了
		g_pD3DDevice -> EndScene ();
	}

	g_pD3DDevice -> Present ( NULL , NULL , NULL , NULL );
}

LPDIRECT3DDEVICE9 GetDevice ( void )
{
	return g_pD3DDevice;
}

///////////////   EOF   ///////////////

今、画像を使ってアニメーション処理をしようとしています。
画像は1枚で、0~9の数字が、
01234
56789
の2段のような構成になっています。
0~4までをアニメーション表示することはできたのですが、これをカウントダウンみたいな処理にしたいのです。
どうやればよいのか教えてください。

NONT

Re: DirectXを使ったアニメーションについて

#2

投稿記事 by NONT » 9年前

配列と%演算子を使って何とかなりました。
お騒がせしました。

閉鎖

“C言語何でも質問掲示板” へ戻る