ずいぶんと日が空いてしまいましたがFPS講座はじまります. 夜猫子 :というわけで前回の続きで今回は描画部分を ねここ :前回の総会でバレバレだったらしいのですよー 夜猫子 :まさかいきなりばれているとは思いませんでした. ショータ:難易度でばれたって結構だめなんじゃない? ねここ :こんな文章じゃきっと誰もわからないのですよー ショータ:それって難易度以前の問題だよね ねここ :ついに×評価ももらってしまいましたしねー 夜猫子 :O...TL そこまで言わなくてもいいじゃんかよぅ. ねここ :逃げてるだけじゃないでしょうね 夜猫子 :半分ぐらい. でも半分は本気ですのでご安心ください. ねここ :まぁそういうことにしておくですよ 夜猫子 :では早速名前改め夜猫子のFPS講座IIIの始まり始まり〜 ねここ :とりあえず移動とかはできるみたいです ショータ:基本中の基本だね 夜猫子 :では早速クラスとは何かから進めます. ねここ :たとえば? 夜猫子 :たとえば何か模型をたくさん作りたかったとします. ショータ:わかりやすいような… わかりにくいような…. 夜猫子 :まぁ使っているうちにだんだんわかってくると思いますので ねここ :・・・ 夜猫子 :さて,下のコードは前回書いたコードの一部です. #pragma comment(lib, "d3dxof.lib") #pragma comment(lib, "dxguid.lib") #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "winmm.lib") #ifdef _DEBUG #pragma comment(lib, "d3dx9d.lib") #else #pragma comment(lib, "d3dx9.lib") #endif #define _CRT_SECURE_NO_WARNINGS #include <windows.h> #include <d3dx9.h> IDirect3D9 *pD3D = NULL; IDirect3DDevice9 *pD3DDevice = NULL; LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg){ case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { const int dispx = 800; const int dispy = 600; MSG msg; ZeroMemory(&msg, sizeof(msg)); WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_CLASSDC; wc.lpfnWndProc = MsgProc; wc.hInstance = hInstance; wc.lpszClassName = CLASSNAME; wc.hCursor = LoadCursor(NULL , IDC_ARROW); if (RegisterClassEx(&wc)==NULL) PostQuitMessage(0); HWND hWnd = CreateWindow(CLASSNAME, APPNAME, WS_OVERLAPPEDWINDOW, 0, 0, dispx, dispy, NULL, NULL, wc.hInstance, NULL); if (hWnd==NULL) PostQuitMessage(0); //ウィンドウサイズ微調整 RECT Rect; GetClientRect(hWnd, &Rect); MoveWindow(hWnd, NULL, NULL, dispx+(dispx-Rect.right), dispy+(dispy-Rect.bottom),false); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); pD3D = Direct3DCreate9(D3D_SDK_VERSION); d3dpp.BackBufferCount = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.Windowed = true; d3dpp.BackBufferHeight = dispy; d3dpp.BackBufferWidth = dispx; d3dpp.hDeviceWindow = hWnd; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDevice); // Show the window ShowWindow(hWnd, SW_SHOWDEFAULT); UpdateWindow(hWnd); // Enter the message loop while( msg.message!=WM_QUIT ){ if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){ TranslateMessage( &msg ); DispatchMessage( &msg ); }else{ pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 190, 255 ), 1.0f, 0 ); pD3DDevice->BeginScene(); pD3DDevice->EndScene(); pD3DDevice->Present( NULL, NULL, NULL, NULL ); } } pD3DDevice->Release(); pD3D->Release(); UnregisterClass(CLASSNAME, hInstance); return (int)msg.wParam; } 夜猫子 :ウェブ連載っていいね. 紙面の都合なんて考えず ねここ :うーん...一番上の //ライブラリのインクルード #pragma comment(lib, "d3dxof.lib") #pragma comment(lib, "dxguid.lib") #pragma comment(lib, "d3d9.lib") #ifdef _DEBUG #pragma comment(lib, "d3dx9d.lib") #else #pragma comment(lib, "d3dx9.lib") #endif #include <d3dx9.h> IDirect3D9 *pD3D = NULL; IDirect3DDevice9 *pD3DDevice = NULL; と、中盤の D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); pD3D = Direct3DCreate9(D3D_SDK_VERSION); d3dpp.BackBufferCount = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.Windowed = true; d3dpp.BackBufferHeight = dispy; d3dpp.BackBufferWidth = dispx; d3dpp.hDeviceWindow = hWnd; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDevice); それから pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 190, 255 ), 1.0f, 0 ); pD3DDevice->BeginScene(); pD3DDevice->EndScene(); pD3DDevice->Present( NULL, NULL, NULL, NULL ); そして,最後にある pD3DDevice->Release(); pD3D->Release(); がそうっぽいのですよ. ショータ:本当にd3dがつく文を抜き出しただけだけどね 夜猫子 :うん.そんな感じ.実はあと #pragma comment(lib, "winmm.lib")もあげてくれたら ねここ :いきなり弱気になったのですよ 夜猫子 :だってどっちが使いやすいかは人によるし. 夜猫子 :とりあえず,図解で説明します. 今回は描画をメインで扱いたいので ねここ :また単純な… 夜猫子 :ではこんな感じでクリックしたり入力したりしてみてくださいー.
ねここ :なんだか #pragma once class Graphics { public: Graphics(void); virtual ~Graphics(void); }; こんなのがでたのですよ 夜猫子 :とりあえずこれで何もしないクラスが完成したのでこれに書き足していきましょう. D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); pD3D = Direct3DCreate9(D3D_SDK_VERSION); d3dpp.BackBufferCount = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.Windowed = true; d3dpp.BackBufferHeight = dispy; d3dpp.BackBufferWidth = dispx; d3dpp.hDeviceWindow = hWnd; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDevice); この部分ですね.ただし,dispx, dispy, hWndはいろいろ変わりますので 次の塊は pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 190, 255 ), 1.0f, 0 ); pD3DDevice->BeginScene(); pD3DDevice->EndScene(); pD3DDevice->Present( NULL, NULL, NULL, NULL ); この部分です.これは描画をしている部分になるのでDraw()という関数を追加して, pD3DDevice->Release(); pD3D->Release(); ねここ :そういえば最初の //ライブラリのインクルード #pragma comment(lib, "d3dxof.lib") #pragma comment(lib, "dxguid.lib") #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "winmm.lib") #ifdef _DEBUG #pragma comment(lib, "d3dx9d.lib") #else #pragma comment(lib, "d3dx9.lib") #endif #include <d3dx9.h> IDirect3D9 *pD3D = NULL; IDirect3DDevice9 *pD3DDevice = NULL; これはどうするですか? 夜猫子 :これもヘッダに書いてしまいましょう.どこに書くかというと変数は大概下の方に書きます. #pragma once //ライブラリのインクルード #pragma comment(lib, "d3dxof.lib") #pragma comment(lib, "dxguid.lib") #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "winmm.lib") #ifdef _DEBUG #pragma comment(lib, "d3dx9d.lib") #else #pragma comment(lib, "d3dx9.lib") #endif #include <d3dx9.h> class Graphics { public: Graphics(HWND hWnd, int dispx, int dispy); //ウィンドウハンドル,高さ,幅は外からもらう void Draw(); //描画したいときに呼び出す virtual ~Graphics(void); //役目を終えたときに自動で呼び出される private: IDirect3D9 *pD3D; IDirect3DDevice9 *pD3DDevice; }; ショータ:=NULLが消えてるけどいいの? それからprivateって? ねここ :そういえばpublicというのも気になるのですよ. 夜猫子 :実はクラス宣言の中では変数の初期化が出来ない決まりなのです. ねここ :むむむ…ややこしくなってきたのですよ 夜猫子 :まぁC++について詳しくなろう!じゃなくてDirectXを使ってみよう!が目的ですので #include "Graphics.h" Graphics::Graphics(void) { } Graphics::~Graphics(void) { } ねここ :ショーちゃん大変なのですよ さっきDraw()を追加したはずなのにDraw()がないのですよ ショータ:ほんとだ。 そういえばGraphics()の中もvoidになってる 夜猫子 :Drawはさっき私たちが追加したので自分で追加しないとだめだったり. #include "Graphics.h" Graphics::Graphics(HWND hWnd, int dispx, int dispy) { } void Graphics::Draw() { } Graphics::~Graphics(void) { } 夜猫子 :あとはコピペでさっきピックアップした部分を ねここ :とりあえずコピペしてみたのですよ. #include "Graphics.h" Graphics::Graphics(HWND hWnd, int dispx, int dispy) { D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); pD3D = Direct3DCreate9(D3D_SDK_VERSION); d3dpp.BackBufferCount = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.Windowed = true; d3dpp.BackBufferHeight = dispy; d3dpp.BackBufferWidth = dispx; d3dpp.hDeviceWindow = hWnd; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDevice); } void Graphics::Draw() { pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 190, 255 ), 1.0f, 0 ); pD3DDevice->BeginScene(); pD3DDevice->EndScene(); pD3DDevice->Present( NULL, NULL, NULL, NULL ); } Graphics::~Graphics(void) { pD3DDevice->Release(); pD3D->Release(); } 夜猫子 :はい.よくできましたー. ねここ :がらあきになったのですよ 夜猫子 :そしたら一番上でGraphics.hをインクルードして //ウィンドウサイズ微調整 RECT Rect; GetClientRect(hWnd, &Rect); MoveWindow(hWnd, NULL, NULL, dispx+(dispx-Rect.right), dispy+(dispy-Rect.bottom),false); の直後に ねここ :「できます」って 夜猫子 :つぎに // Enter the message loop while( msg.message!=WM_QUIT ){ if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){ TranslateMessage( &msg ); DispatchMessage( &msg ); }else{ } } のelseのブロック内に graphics.Draw(); ねここ :実行はCtrl+F5でいけるのですよー ショーちゃんもやってみるです ショータ:なんか一個前と変わらない画面がでたよ. 夜猫子 :まぁ一個前のプログラムをクラスでまとめただけなので ショータ:確かにこれならDirectXの細かい部分を毎回いじらなくても 夜猫子 :では今回はここで終了.お疲れ様でした. 今回のプロジェクトファイルのダウンロードはこちらから. |