/////////////////////////////////////////////////////// /// /// このソースコードを引用・改変した結果如何なる /// 損害が発生しても、著者はは責任を負いません。 /// 広島大学 脳外科 橋詰顕 /// //////////////////////////////////////////////////////// #define STRICT //型チェックを厳密に行う #define WIN32_LEAN_AND_MEAN //ヘッダーからあまり使われていない関数を省く #include //timeGetTime用 #include //timeGetTime 本来windows.hに含まれているはずだが明示しないとだめみたい #pragma comment(lib,"winmm.lib") // //Direct3D9用 #include #include #pragma comment(lib,"d3d9.lib") #pragma comment(lib,"d3dx9.lib") #pragma comment(lib,"dxguid.lib") //prototype void hnsDeleteWindowMessage(); LPDIRECT3DDEVICE9 hnsMakeDirect3D9Device(LPDIRECT3D9 lpDirect3D9,HWND hWindow,D3DPRESENT_PARAMETERS Direct3DPresentParameter); LPDIRECT3D9 hnsMakeDirect3D9Interfacet(); D3DPRESENT_PARAMETERS hnsMakeDirect3DPresentParameters(LPDIRECT3D9 lpDirect3D9,DWORD WindowWidth,DWORD WindowHeight); void hnsSetFullScreenVGA(HWND hWindow); void hnsTaskLoop(HWND hWindow); LRESULT CALLBACK WindowProcedure(HWND hWindow,UINT message,WPARAM wParameter,LPARAM lParameter); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { //WNDCLASSの設計 WNDCLASS WindowClass; WindowClass.style=CS_HREDRAW | CS_VREDRAW; WindowClass.lpfnWndProc=WindowProcedure; WindowClass.cbClsExtra=0; WindowClass.cbWndExtra=0; WindowClass.hInstance=hInstance; WindowClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); WindowClass.hCursor=LoadCursor(NULL,IDC_ARROW); WindowClass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); WindowClass.lpszMenuName=NULL; WindowClass.lpszClassName="WindowClassName"; //設計したWNDCLASSの登録 if(!RegisterClass(&WindowClass)) { MessageBox(NULL,"設計したWNDCLASSの設計に失敗しました","Error!",MB_ICONERROR); return 0; } //Windowの作成 HWND hWindow=CreateWindow( "WindowClassName", //window class name "Let's make MEG task", //title WS_OVERLAPPEDWINDOW | WS_VISIBLE, //Window Style //WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, //top left CW_USEDEFAULT,CW_USEDEFAULT, //width,height NULL, //parent window handle (HMENU)NULL, //window menu handle hInstance, //application handle NULL); //creation parameter ShowWindow(hWindow,SW_SHOW); MSG message; //無限ループです。 while(GetMessage(&message,NULL,0,0)) { TranslateMessage(&message); DispatchMessage(&message); } return 0; } void hnsDeleteWindowMessage() { //Window Messageを取り除く MSG message; int flag=1; while (1) { flag=::PeekMessage(&message,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE ); if(flag==0){break;} } } D3DPRESENT_PARAMETERS hnsMakeDirect3DPresentParameters(LPDIRECT3D9 lpDirect3D9,DWORD WindowWidth,DWORD WindowHeight) { HRESULT hResult; int adapter=0;//通常は1画面でしょ //displayの設定 D3DPRESENT_PARAMETERS Direct3DPresentParameter; D3DDISPLAYMODE Direct3DDisplayMode; ZeroMemory(&Direct3DPresentParameter,sizeof(D3DPRESENT_PARAMETERS)); hResult=lpDirect3D9->GetAdapterDisplayMode(adapter,&Direct3DDisplayMode); if(FAILED(hResult)) { MessageBox(NULL,"display modeの取得に失敗しました","",MB_ICONERROR); return Direct3DPresentParameter; } //back buffer Direct3DPresentParameter.BackBufferFormat=D3DFMT_X8R8G8B8;//32bit color fullscreen //Direct3DPresentParameter.BackBufferFormat=D3DFMT_D16; Direct3DPresentParameter.BackBufferWidth=(UINT)WindowWidth; Direct3DPresentParameter.BackBufferHeight=(UINT)WindowHeight; Direct3DPresentParameter.SwapEffect=D3DSWAPEFFECT_FLIP; //z buffer Direct3DPresentParameter.EnableAutoDepthStencil=1; Direct3DPresentParameter.AutoDepthStencilFormat=D3DFMT_D16;//16bitです return Direct3DPresentParameter; } LPDIRECT3DDEVICE9 hnsMakeDirect3D9Device(LPDIRECT3D9 lpDirect3D9,HWND hWindow,D3DPRESENT_PARAMETERS Direct3DPresentParameter) { int adapter=0; HRESULT hResult; //Direct3D9 deviceの作成 LPDIRECT3DDEVICE9 lpDirect3D9Device; hResult=lpDirect3D9->CreateDevice( adapter, D3DDEVTYPE_HAL, //hardwareによるtransform lighting hWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,//hardwareによる頂点変換 &Direct3DPresentParameter, &lpDirect3D9Device); if(!FAILED(hResult)){return lpDirect3D9Device;} hResult=lpDirect3D9->CreateDevice( adapter, D3DDEVTYPE_HAL, //hardwareによるtransform lighting hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING,//softwareによる頂点変換 &Direct3DPresentParameter, &lpDirect3D9Device); if(!FAILED(hResult)){return lpDirect3D9Device;} hResult=lpDirect3D9->CreateDevice( adapter, D3DDEVTYPE_REF, //softwareによるtransform lighting hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING,//softwareによる頂点変換 &Direct3DPresentParameter, &lpDirect3D9Device); if(!FAILED(hResult)){return lpDirect3D9Device;} //失敗理由 switch(hResult) { case D3DERR_DEVICELOST: MessageBox(NULL,"Deviceがありません","",MB_OK);break; case D3DERR_INVALIDCALL: MessageBox(NULL,"methodの呼び出しが無効です","",MB_OK);break; case D3DERR_NOTAVAILABLE: MessageBox(NULL,"このdeviceは問い合わせたテクニックをサポートしません","",MB_OK);break; case D3DERR_OUTOFVIDEOMEMORY:MessageBox(NULL,"Direct3Dが処理を行うのに十分なdisplay memoryがありません","",MB_OK);break; } return NULL; } LPDIRECT3D9 hnsMakeDirect3D9Interface() { LPDIRECT3D9 lpDirect3D9=Direct3DCreate9(D3D_SDK_VERSION); if(!lpDirect3D9) { MessageBox(NULL,"Direct3D9の作成に失敗しました","",MB_ICONERROR); return NULL; } return lpDirect3D9; } void hnsSetFullScreenVGA(HWND hWindow) { static int WindowWidth=640; static int WindowHeight=480; LONG lResult; //画面を640x480に変更できたかどうか //画面を640x480にする DEVMODE DeviceMode; DeviceMode.dmSize =sizeof(DEVMODE); DeviceMode.dmFields =DM_PELSWIDTH | DM_PELSHEIGHT; DeviceMode.dmPelsWidth =WindowWidth; DeviceMode.dmPelsHeight =WindowHeight; //画面を元に戻す if(hWindow==NULL){ ChangeDisplaySettings(&DeviceMode,NULL); return; } lResult=ChangeDisplaySettings(&DeviceMode,CDS_FULLSCREEN); if(lResult!=DISP_CHANGE_SUCCESSFUL) { MessageBox(hWindow,"full screenの変換は失敗しました","",MB_ICONERROR); return; } SetWindowPos(hWindow,HWND_TOPMOST,0,0,WindowWidth,WindowHeight,0); } void hnsTaskLoop(HWND hWindow) { static DWORD WindowWidth=640; static DWORD WindowHeight=480; LPDIRECT3D9 pDirect3D9=hnsMakeDirect3D9Interface(); if(pDirect3D9==NULL){return;} D3DPRESENT_PARAMETERS PresentParameter=hnsMakeDirect3DPresentParameters(pDirect3D9,WindowWidth,WindowHeight); if(PresentParameter.BackBufferWidth==0) { pDirect3D9->Release(); return; } LPDIRECT3DDEVICE9 pDevice=hnsMakeDirect3D9Device(pDirect3D9,hWindow,PresentParameter); if(pDevice==NULL) { pDirect3D9->Release(); return; } //textureの作成 LPDIRECT3DTEXTURE9 pTexture; HRESULT hResult=D3DXCreateTextureFromFileEx( pDevice, "image1.bmp", 256, //UINT Width 50, //UINT Height, 0, //UINT MipLevels 0は完全なmipmap levelを作成 0, //DWORD Usage D3DFMT_UNKNOWN, //D3DFORMAT D3DPOOL_DEFAULT,//Pool D3DX_FILTER_NONE,//Image filter D3DX_DEFAULT, //Mip Filter 0xff000000, //ColorKey 透明となる色 常に32bit ARGB NULL, //pSrcInfo 入力イメージファイル内のデータ記述 NULL, //pPalette &pTexture); if(FAILED(hResult)) { pDevice->Release(); pDirect3D9->Release(); } //spriteの作成 LPD3DXSPRITE pSprite; hResult=D3DXCreateSprite(pDevice,&pSprite); if(FAILED(hResult)) { pTexture->Release(); pDevice->Release(); pDirect3D9->Release(); } hnsDeleteWindowMessage(); //バックバッファとZバッファをクリア pDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0); pDevice->BeginScene();//描画開始 D3DXVECTOR3 vec3Center(128,25,0); D3DXVECTOR3 vec3Position(320,240,0); pSprite->Begin(D3DXSPRITE_ALPHABLEND); pSprite->Draw( pTexture, //スプライトテクスチャのポインタ NULL, //pSrcRect 描画範囲 NULLはソースイメージ全体 &vec3Center, //スプライトの中心 &vec3Position, //スプライトの位置 0xffffffff); //Color カラーチャネルとアルファチャンネルを乗じる。 pSprite->End(); Sleep(1000); pDevice->EndScene();//描画終了 //back bufferをprimary bufferにcopy if(FAILED(pDevice->Present(NULL,NULL,NULL,NULL))) { pDevice->Reset(&PresentParameter); } do //御法度の無限ループ { }while((GetAsyncKeyState(VK_ESCAPE)&0x8000)==0); hnsDeleteWindowMessage(); pSprite->Release(); pTexture->Release(); pDevice->Release(); pDirect3D9->Release(); } LRESULT CALLBACK WindowProcedure(HWND hWindow,UINT message,WPARAM wParameter,LPARAM lParameter) { switch(message) { case WM_CREATE: hnsSetFullScreenVGA(hWindow); break; case WM_KEYDOWN: switch(wParameter) { //ESCAPEキーをおすとWindowを破壊するWM_DESTROYメッセージを送る case VK_ESCAPE: PostMessage(hWindow,WM_DESTROY,0,0); break; //RETURNキーをおすとタスク開始 case VK_RETURN: hnsTaskLoop(hWindow); hnsSetFullScreenVGA(hWindow); break; } break; case WM_DESTROY: //hnsSetFullScreenVGA(NULL); //ないほうがいいみたい PostQuitMessage(0); return 0; } return DefWindowProc(hWindow,message,wParameter,lParameter); }