MinGW32 で DirectX プログラミングしてみる
最近全然やってないことに気付いて書いてみた。
あと、MinGW32 でもコンパイルできるようにしてみた。
MinGW32 には、 d3dx9.h が無い代わりに、direct.h ってヘッダーファイルがあるってのを知った。*1
なので、d3d9.h しかインクルードしてない。
// dir01.cpp #include <windows.h> #include <tchar.h> #include <d3d9.h> #if !defined(_MINGW) # pragma comment(lib, "d3d9.lib") # pragma comment(lib, "d3dx9.lib") #endif /* !defined(_MINGW) */ IDirect3D9* directx_graphics = NULL; IDirect3DDevice9* graphic_device = NULL; static const _TCHAR* application_title = _T("見習い魔法使いでもよく分かるかもしれないDirectX"); LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM); HRESULT init_DirectX_Graphics(HWND); void onRender(); #define WS_GAMESCREEN WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hUnused, LPSTR szCommandLine, INT nCommandCount) { HWND window_handle = NULL; MSG msg; WNDCLASSEX wx; wx.cbSize = sizeof(WNDCLASSEX); wx.style = CS_HREDRAW | CS_VREDRAW; wx.lpfnWndProc = wndProc; wx.cbClsExtra = 0; wx.cbWndExtra = 0; wx.hInstance = hInstance; wx.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wx.hCursor = LoadCursor( NULL, IDC_ARROW ); wx.hbrBackground = reinterpret_cast<HBRUSH>( GetStockObject( BLACK_BRUSH ) ); wx.lpszMenuName = NULL; wx.lpszClassName = application_title; wx.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); RegisterClassEx( &wx ); RECT rc = { 0, 0, 640, 400 }; AdjustWindowRect( &rc, WS_GAMESCREEN, false ); window_handle = CreateWindow( application_title, application_title, WS_GAMESCREEN, 300, 300, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL ); ShowWindow( window_handle, SW_SHOW ); UpdateWindow( window_handle ); HRESULT hr; if ( FAILED( hr = init_DirectX_Graphics( window_handle ) ) ) { return hr; } ZeroMemory( &msg, sizeof(MSG) ); while ( msg.message != WM_QUIT ) { if ( PeekMessage( &msg, NULL, 0u, 0u, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { onRender(); } } graphic_device->Release(); directx_graphics->Release(); return static_cast<int>(msg.wParam); } LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch ( msg ) { case WM_DESTROY: PostQuitMessage( 0 ); break; } return DefWindowProc( hWnd, msg, wp, lp ); } HRESULT init_DirectX_Graphics(HWND hWnd) { if ( NULL == ( directx_graphics = Direct3DCreate9( D3D_SDK_VERSION ) ) ) { MessageBox( NULL, _T("Direct3D 作成に失敗したよ!"), _T("もうだめぽ"), MB_OK ); return E_FAIL; } D3DPRESENT_PARAMETERS present_box; ZeroMemory( &present_box, sizeof(D3DPRESENT_PARAMETERS) ); present_box.BackBufferFormat = D3DFMT_UNKNOWN; present_box.BackBufferCount = 1; present_box.SwapEffect = D3DSWAPEFFECT_DISCARD; present_box.Windowed = true; present_box.EnableAutoDepthStencil = true; present_box.AutoDepthStencilFormat = D3DFMT_D16; if ( FAILED( directx_graphics->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_box, &graphic_device ) ) ) { if ( FAILED( directx_graphics->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_box, &graphic_device ) ) ) { MessageBox( NULL, _T("HAL モードで directx3d デバイスを作成できなかったよ!。\nREFモードで再試行するからねっ☆。"), _T("ちょっとヤバイ"), MB_OK ); if ( FAILED( directx_graphics->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_box, &graphic_device ) ) ) { if ( FAILED( directx_graphics->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_box, &graphic_device ) ) ) { MessageBox( NULL, _T("direct3d デバイスの作成に失敗したよ!\n他のゲームも多分できないっぽいから、あきらめたほうがいいよ!!"), _T("ヤバイってもんじゃない"), MB_OK ); return E_FAIL; } } } } return S_OK; } void onRender() { graphic_device->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0x33, 0x66, 0x99), 1.0f, 0 ); if ( SUCCEEDED( graphic_device->BeginScene() ) ) { // // ここに何か描画する処理を書く。 // graphic_device->EndScene(); } graphic_device->Present( NULL, NULL, NULL, NULL ); }
エラーメッセージがあれなのはユーモアなので、サラッと流して欲しい。
さて、難しいのはここからで、オブジェクトファイルのリンクがよく分からないんだよね。
今回は、比較的すんなりいったのでよかった。
以下に makefile も晒しておく:
cc = g++ cflags = -O2 -Wall -W ld = g++ lflags = -gdi32 -mwindows libs = -ld3d9 -ldxguid outdir = ./Debug target = $(outdir)/dir01.exe src0 = dir01.cpp obj0 = $(outdir)/dir01.o objs = $(obj0) $(obj1) all: $(target) $(target): $(objs) $(ld) $(lflags) -o $@ $^ $(libs) $(obj0): $(src0) $(cc) $(cflags) -c $< -o $@ clean: rm $(target) $(objs)