今回は複数画像を描画します 複数画像を描画するためには DirectX講座7回の画像描画部分を DirectX講座8回、DirectX講座9回の知識を踏まえてクラス化してみます Direct3Dの初期化を行うDirect3Dクラスと 画像データを読み込むTextureクラスと 板ポリゴンを描画するSpriteクラスを作成します 今回使うファイルは次のようになってます。どぞー(-ω-)つ旦 ・&ref(spriteclass.cpp); ・&ref(car.bmp); zipでほしい人はこちら ・&ref(spriteclass.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; } 今回の実行結果は次のようになります &ref(spriteclass.jpg); 前:DirectX講座9回 次:DirectX講座11回 #vote( (^ω^)おっおっおっ[143],まだまだだね[6],わしの波動球は108式まであるぞ[19]) | (^ω^)おっおっおっ|143| |まだまだだね|6| |わしの波動球は108式まであるぞ|19|