#include <windows.h>
#include <d3dx9.h>
#define CLASS_NAME TEXT("DirectX")
#define WINDOW_NAME TEXT("DirectX")
LPDIRECT3D9 pD3d; //Direct3Dオブジェクト
LPDIRECT3DDEVICE9 pDevice; //Direct3Dデバイスオブジェクト
LPDIRECT3DTEXTURE9 pTexture; //テクスチャオブジェクト
LPD3DXSPRITE pSprite; //スプライトオブジェクト
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT InitD3d(HWND hWnd); //Direct3Dの初期化関数
void DrawSprite(); //スプライトを描画する関数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0; //禁止用語になるので大文字で表記します
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = NULL;
wc.hIcon = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = CLASS_NAME;
if(!RegisterClass(&wc)) {
return 1;
}
HWND hWnd;
hWnd = CreateWindow(CLASS_NAME, WINDOW_NAME, WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, hInstance, NULL);
if(hWnd == NULL) {
return 1;
}
//Direct3D初期化
if(FAILED(InitD3d(hWnd))) {
return 1;
}
MSG msg;
//GetMessageの方
/*
while(GetMessage(&msg, NULL, 0, 0) > 0) {
DrawSprite();
TranslateMessage(&msg);
DispatchMessage(&msg);
}
*/
//PeekMessageの方
while(true) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if(msg.message == WM_QUIT) {
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
DrawSprite();
}
}
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//Direct3D初期化関数
HRESULT InitD3d(HWND hWnd) {
//Direct3Dオブジェクトの生成
if(NULL == (pD3d = Direct3DCreate9(D3D_SDK_VERSION))) {
MessageBox(hWnd, TEXT("Direct3Dオブジェクトの生成に失敗しました。"), TEXT("Error"), MB_OK);
return E_FAIL;
}
//Direct3Dデバイスオブジェクトの生成
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.BackBufferCount = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = true;
if(FAILED(pD3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &pDevice))) {
MessageBox(hWnd, TEXT("HALモードでDirect3Dデバイスオブジェクトの生成に失敗しました。\nREFモードで再試行します。"), TEXT("Error"), MB_OK);
if(FAILED(pD3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &pDevice))) {
MessageBox(hWnd, TEXT("Direct3Dデバイスオブジェクトの生成に失敗しました。"), TEXT("Error"), MB_OK);
return E_FAIL;
}
}
//テクスチャオブジェクトの生成
if(FAILED(D3DXCreateTextureFromFileEx(pDevice, TEXT("Sprite.bmp"), 100, 100, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0xff000000, NULL, NULL, &pTexture))) {
MessageBox(hWnd, TEXT("テクスチャオブジェクトの生成に失敗しました。"), TEXT("Error"), MB_OK);
return E_FAIL;
}
//スプライトオブジェクトの生成
if(FAILED(D3DXCreateSprite(pDevice, &pSprite))) {
MessageBox(hWnd, TEXT("スプライトオブジェクトの生成に失敗しました。"), TEXT("Error"), MB_OK);
return E_FAIL;
}
return S_OK;
}
//スプライトを描画する関数
void DrawSprite() {
pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
if(SUCCEEDED(pDevice->BeginScene())) {
RECT rect = {0, 0, 100, 100};
D3DXVECTOR3 vec3Center(0, 0, 0);
D3DXVECTOR3 vec3Position(200, 200, 0);
pSprite->Begin(D3DXSPRITE_ALPHABLEND);
pSprite->Draw(pTexture, &rect, &vec3Center, &vec3Position, 0xffffffff);
pSprite->End();
pDevice->EndScene();
}
pDevice->Present(NULL, NULL, NULL, NULL);
}
GetMessage関数を用いればwhileでループするたびに必ずDrawSprite関数が呼ばれ、PeekMessage関数を用いるとアイドル時間のみDrawSprite関数が呼ばれる違いなのでしょうか。
そして、その違いが何の違いに繋がるのでしょうか。