/* ティーポットを描画する 前田 稔 */ #define NAME "Teapot" #include #include #pragma once #pragma comment(lib, "user32.lib") #pragma comment(lib, "gdi32.lib") #pragma comment(lib,"dxguid.lib") #pragma comment(lib,"d3d9.lib") #pragma comment(lib,"d3dx9.lib") #pragma comment(lib,"winmm.lib") #define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } } #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } #define EMSG(x) MessageBox(NULL,x,"DirectX D3D",MB_OK); //Global Area HWND g_hWnd; LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pDEV = NULL; LPD3DXMESH g_pMesh = NULL; D3DMATERIAL9 material; D3DLIGHT9 light; D3DXVECTOR3 ViewForm(0.0f,0.0f,-5.0f); //Function Prototype LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam); //デバイス/モード等の初期化 HRESULT Init3DDev(HWND hwnd,LPDIRECT3D9 *D3D, LPDIRECT3DDEVICE9 *D3DDV) { D3DPRESENT_PARAMETERS d3dpp; D3DDISPLAYMODE dmode; //Direct3Dオブジェクトの取得 *D3D = Direct3DCreate9(D3D_SDK_VERSION); if(*D3D == NULL) return E_FAIL; //現在のディスプレイモードを得る if(FAILED((*D3D)->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&dmode))) return E_FAIL; //バックサーフェースのフォーマットをコピーして使用する ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS)); d3dpp.Windowed = TRUE; //ウィンドウモード d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //垂直同期でフリップ d3dpp.BackBufferFormat = dmode.Format; d3dpp.BackBufferCount = 1; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //デバイスの作成 if (FAILED((*D3D)->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,D3DDV))) { if( FAILED((*D3D)->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,D3DDV))) { if (FAILED((*D3D)->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,D3DDV))) { EMSG("Create Device Error"); return E_FAIL; } } } return S_OK; } //デバイス/モード等の初期化 HRESULT InitDevices(void) { if (FAILED(Init3DDev(g_hWnd,&g_pD3D,&g_pDEV))) return E_FAIL; //ティーポットの生成 D3DXCreateTeapot(g_pDEV,&g_pMesh,NULL); //初期マテリアルの設定 material.Diffuse.r= material.Diffuse.g= 1.0f; material.Diffuse.b= 0.0f; material.Ambient.r= material.Ambient.g= material.Ambient.b= 0.5f; material.Specular.r= material.Specular.g= material.Specular.b= 0.0f; material.Emissive.r= material.Emissive.g= material.Emissive.b= 0.0f; material.Power= 0; //光源の作成 ZeroMemory(&light,sizeof(D3DLIGHT9)); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r= light.Diffuse.g= light.Diffuse.b= 1.0f; light.Specular.r= light.Specular.g= light.Specular.b= 0.2f; light.Ambient.r= light.Ambient.g= light.Ambient.b= 0.5f; light.Direction = D3DXVECTOR3(1,-2,1); return S_OK; } //描画環境の設定 void SetupMatrices(void) { RECT rect; D3DXMATRIX matWorld; D3DXMATRIX matView; D3DXMATRIX matProj; GetClientRect(g_hWnd,&rect); //World 座標をY軸を中心に自動回転 D3DXMatrixRotationY(&matWorld,timeGetTime()/1000.0f); g_pDEV->SetTransform(D3DTS_WORLD,&matWorld); //View 座標の設定 D3DXMatrixLookAtLH(&matView,&ViewForm, &D3DXVECTOR3(0.0f,0.0f,0.0f),&D3DXVECTOR3(0.0f,1.0f,0.0f)); g_pDEV->SetTransform(D3DTS_VIEW,&matView); //透視変換の設定 D3DXMatrixPerspectiveFovLH(&matProj,D3DXToRadian(45.0f),(float)rect.right/(float)rect.bottom,1,50); g_pDEV->SetTransform(D3DTS_PROJECTION,&matProj); g_pDEV->SetRenderState(D3DRS_AMBIENT,0x00080808); g_pDEV->SetLight(0,&light); g_pDEV->LightEnable(0,TRUE); g_pDEV->SetMaterial(&material); } //描画処理 void Draw(void) { //黒で塗りつぶして消去 g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0); if (SUCCEEDED(g_pDEV->BeginScene())) { //描画環境の設定 SetupMatrices(); g_pMesh->DrawSubset(0); g_pDEV->EndScene(); } g_pDEV->Present(NULL,NULL,NULL,NULL); } //オブジェクトの開放 void Cleanup(void) { SAFE_RELEASE(g_pMesh); SAFE_RELEASE(g_pDEV); SAFE_RELEASE(g_pD3D); } //CALLBACK Procedure LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam) { switch(msg) { case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); return 0L; } return DefWindowProc(hWnd,msg,wParam,lParam); } //★Win Main int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int) { MSG msg; WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,WndProc,0L,0L,hInst, NULL,NULL,NULL,NULL,NAME,NULL }; if (RegisterClassEx(&wc)==0) return FALSE; g_hWnd = CreateWindowEx(0,NAME,NAME,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInst,NULL); if (FAILED(InitDevices())) return FALSE; ShowWindow(g_hWnd,SW_SHOWDEFAULT); UpdateWindow(g_hWnd); ZeroMemory(&msg,sizeof(msg)); while(msg.message!=WM_QUIT) { if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else Draw(); } Cleanup(); UnregisterClass(NAME,wc.hInstance); return 0; }