今回は複数画像を描画します

複数画像を描画するためには
DirectX講座7回の画像描画部分を
DirectX講座8回DirectX講座9回の知識を踏まえてクラス化してみます

Direct3Dの初期化を行うDirect3Dクラスと
画像データを読み込むTextureクラスと
板ポリゴンを描画するSpriteクラスを作成します

今回使うファイルは次のようになってます。どぞー(-ω-)つ旦
filespriteclass.cpp
filecar.bmp
zipでほしい人はこちら
filespriteclass.zip

// Direct3Dに必要なヘッダーとライブラリ 

#define D3D_DEBUG_INFO	// Direct3Dデバックフラグ

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "d3dxof.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "winmm.lib")
#include <comdef.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <mmsystem.h>

#include <Windows.h>
#include <tchar.h>

//////////////////////////////////////////////////////////////////////

// Direct3Dクラス
class Direct3D
{
public:
	IDirect3D9*			pD3D9;			// Direct3Dデバイス生成用オブジェクト
	IDirect3DDevice9*		pDevice3D;		// Direct3Dのデバイス

	// コンストラクタ
	Direct3D();
	// デストラクタ
	~Direct3D();

	// デバイス作成
	bool Create(HWND hWnd,int Width,int Height);
};

// コンストラクタ
Direct3D::Direct3D(){
	pD3D9 = NULL;		
	pDevice3D = NULL;		
}
// デストラクタ
Direct3D::~Direct3D(){
	// DirectXの変数は必ず後処理をすること
	if(pDevice3D != NULL)
		pDevice3D->Release();
	if(pD3D9 != NULL)
		pD3D9->Release();
}

// デバイス作成
bool Direct3D::Create(HWND hWnd,int Width,int Height){
	
	// Direct3D9オブジェクトの作成	
	pD3D9 = Direct3DCreate9(D3D_SDK_VERSION);	
	// ディスプレイ情報取得
	D3DDISPLAYMODE Display;
	pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &Display);

	D3DPRESENT_PARAMETERS	D3DParam = {			// スワップチェイン設定
		Width,Height,Display.Format,1,D3DMULTISAMPLE_NONE,0,
		D3DSWAPEFFECT_DISCARD,hWnd,TRUE,TRUE,D3DFMT_D24S8,0,0,D3DPRESENT_INTERVAL_DEFAULT
	};			
	
	// HALモードで3Dデバイス作成
	if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, D3DParam.hDeviceWindow,
		D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
	if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DParam.hDeviceWindow, 
		D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
	// REFモードで3Dデバイス作成
	if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, D3DParam.hDeviceWindow, 
		D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
	if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, D3DParam.hDeviceWindow, 
		D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
	{
		// 3Dデバイス作成失敗(このグラフィックボードではDirectXが使えない)
		pD3D9->Release();
		return false;
	}

	return true;
}

///////////////////////////////////////////////////////////////////

// テクスチャクラス
class Texture
{
public:
	IDirect3DTexture9* pTexture;
	// コンストラクタ
	Texture();
	// デストラクタ
	~Texture();
	// 画像データ読み込み
	bool Load(IDirect3DDevice9* pDevice3D,TCHAR* FileName);
};

Texture::Texture(){
	pTexture = NULL;
}
Texture::~Texture()
{
	// 読み込まれていたら破棄
	if(pTexture != NULL)
		pTexture->Release();
}
bool Texture::Load(IDirect3DDevice9* pDevice3D,TCHAR* FileName)
{
	// 画像読み込み
	// DirextXやWindowsAPIの関数はHRESULTを結果に返す関数が多い
	// FAILEDマクロで関数が失敗したかわかる
	// SUCEEDEDマクロで関数が成功したかわかる
	if(FAILED(D3DXCreateTextureFromFile(pDevice3D,FileName,&pTexture)))
		return false;	// 画像読み込み失敗(ファイルがない可能性あり)

	// 画像読み込み成功
	return true;
}

//////////////////////////////////////////////////////////////////////

// スプライトクラス(2D板ポリゴン)
class Sprite
{
public:
	// 板ポリゴン頂点情報
	struct Vertex{
		float x,y,z;// 3次元座標
		float rhw;	// 2D変換済みフラグ
		float u,v;	// UV座標
	};
	// FVF(柔軟な頂点構造体宣言)フラグ
	static const DWORD SPRITE_FVF = D3DFVF_XYZRHW | D3DFVF_TEX1;
	
	// スプライト位置
	D3DXVECTOR2 pos;
	// スプライトサイズ
	int width;
	int height;

	// コンストラクタ
	Sprite();
	// デストラクタ
	~Sprite();

	void SetPos(float x,float y);
	void SetWidth(int Width,int Height);
	void Draw(IDirect3DDevice9* pDevice3D,IDirect3DTexture9* pTexture);

};

// コンストラクタ
Sprite::Sprite()
{
	pos.x = pos.y = 0.0f;
	width = 0;
	height = 0;
}
// デストラクタ
Sprite::~Sprite(){}

void Sprite::SetPos(float x,float y)
{
	pos.x = x;
	pos.y = y;
}
void Sprite::SetWidth(int Width,int Height)
{
	width = Width;
	height = Height;
}

void Sprite::Draw(IDirect3DDevice9* pDevice3D,IDirect3DTexture9* pTexture)
{
	// 頂点情報セット
	Vertex vtx[4]={
		{ pos.x + width/2, pos.y - height/2, 0.0f, 1.0f, 1.0f, 0.0f},
		{ pos.x + width/2, pos.y + height/2, 0.0f, 1.0f, 1.0f, 1.0f}, 
		{ pos.x - width/2, pos.y - height/2, 0.0f, 1.0f, 0.0f, 0.0f}, 
		{ pos.x - width/2, pos.y + height/2, 0.0f, 1.0f, 0.0f, 1.0f} 
	};

	// テクスチャセット
	pDevice3D->SetTexture(0,pTexture);
	// 頂点構造体宣言セット
	pDevice3D->SetFVF(SPRITE_FVF);
	// スプライト描画
	pDevice3D->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtx,sizeof(Vertex));
}

//////////////////////////////////////////////////////////////////////

// ウィンドウプロシージャ、ウィンドウに対するメッセージ処理を行う
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	
	switch(msg){
		// ウィンドウが破棄されたとき
	case WM_DESTROY:
		PostQuitMessage(0);	// WM_QUITメッセージをメッセージキューに送る
		return 0;
	}
	// デフォルトのメッセージ処理を行う
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

// WinMain関数(アプリケーションの開始関数)
// コンソールアプリケーションと違い、コンソールを開かない
int _stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	const TCHAR* WC_BASIC = _T("BASIC_WINDOW");
	// シンプルウィンドウクラス設定
	WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,WndProc, 0,0,hInstance,
		(HICON)LoadImage(NULL,MAKEINTRESOURCE(IDI_APPLICATION),IMAGE_ICON,0,0,LR_DEFAULTSIZE | LR_SHARED),
		(HCURSOR)LoadImage(NULL,MAKEINTRESOURCE(IDC_ARROW),IMAGE_CURSOR,0,0,LR_DEFAULTSIZE | LR_SHARED), 
		(HBRUSH)GetStockObject(WHITE_BRUSH), NULL, WC_BASIC , NULL};

	// シンプルウィンドウクラス作成
	if(!RegisterClassEx(&wcex)) 
		return false;

	// ウィンドウ幅、高さはディスプレイに依存する。普通は4:3
	const int WINDOW_WIDTH = 640;
	const int WINDOW_HEIGHT = 480;
	// ウィンドウの作成
	HWND hWnd = CreateWindowEx(0,WC_BASIC,
		_T("Application"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE,
		CW_USEDEFAULT,CW_USEDEFAULT,WINDOW_WIDTH,WINDOW_HEIGHT,NULL,NULL,hInstance,NULL);

///////////////////////////////////////////////////////////////////////////////////////////////

	////////////////////////////////////
	//	Direct3Dの初期化
	////////////////////////////////////
	Direct3D direct3d;
	direct3d.Create(hWnd,WINDOW_WIDTH,WINDOW_HEIGHT);

	////////////////////////////////
	// テクスチャ作成
	////////////////////////////////
	Texture cartex;
	cartex.Load(direct3d.pDevice3D,_T("car.bmp"));

	////////////////////////////////
	// スプライト作成
	////////////////////////////////
	Sprite sprite[2];

	sprite[0].SetPos(100,100);
	sprite[0].SetWidth(128,128);
	sprite[1].SetPos(300,300);
	sprite[1].SetWidth(128,128);
	
///////////////////////////////////////////////////////////////////////////////////////////////
		
	// メッセージループ
	MSG msg = {}; 
	while(msg.message != WM_QUIT) {
		// アプリケーションに送られてくるメッセージをメッセージキューから取得する
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
			DispatchMessage(&msg);	// アプリケーションの各ウィンドウプロシージャにメッセージを転送する
		}
		// メッセージ処理をしていないとき
		else{
			//(ここにDirectXの処理を書く)

///////////////////////////////////////////////////////////////////////////////////////////////

			// 描画開始
			if(SUCCEEDED(direct3d.pDevice3D->BeginScene()))
			{
				DWORD ClearColor = 0xff808080;	// 背景クリア色
				// 背景クリア
				direct3d.pDevice3D->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, ClearColor, 1.0f, 0 );

				
				// スプライト描画
				for(int i = 0;i < 2;++i){
					sprite[i].Draw(direct3d.pDevice3D,cartex.pTexture);
				}

				// 描画終了
				direct3d.pDevice3D->EndScene();
			}
			// 描画反映
			direct3d.pDevice3D->Present( NULL, NULL, NULL, NULL );

///////////////////////////////////////////////////////////////////////////////////////////////
		}
	}
	
	return 0;
}

今回の実行結果は次のようになります
spriteclass.jpg

前:DirectX講座9回
次:DirectX講座11回

選択肢 投票
(^ω^)おっおっおっ 8  
まだまだだね 4  
わしの波動球は108式まであるぞ 17  

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS