#include #include #include #include #include #pragma warning( disable : 4996 ) // 無駄な警告を出さなくする #include #pragma warning( default : 4996 ) //メモリリークを調べるために必要。 #if _DEBUG #include #define new ::new( _NORMAL_BLOCK, __FILE__, __LINE__ ) #endif #define WINDOW_WIDTH (640) // ウィンドウの幅 #define WINDOW_HEIGHT (480) // ウィンドウの高さ #define WINDOW_X ((WINDOW_WIDTH + GetSystemMetrics( SM_CXSIZEFRAME )*2)) #define WINDOW_Y ((WINDOW_HEIGHT + GetSystemMetrics( SM_CYSIZEFRAME )*2 + GetSystemMetrics( SM_CYCAPTION ))) #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } HINSTANCE g_hInstance = NULL; // インスタンス・ハンドル HWND g_hWindow = NULL; // ウインドウ・ハンドル LPDIRECT3D9 g_pD3D = NULL; // Direct3Dインタフェース LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; // Direct3DDeviceインタフェース LPDIRECT3DVERTEXDECLARATION9 g_VertexDec = NULL; //頂点宣言(頂点・頂点色・重み・行列番号) LPDIRECT3DVERTEXBUFFER9 g_PositionBuf = NULL; //頂点バッファ LPDIRECT3DVERTEXBUFFER9 g_WeightBuf = NULL; //ウェイトバッファ LPDIRECT3DVERTEXBUFFER9 g_IndexBuf = NULL; //行列インデックスバッファ LPDIRECT3DINDEXBUFFER9 g_ib = NULL; //インデックスバッファ //頂点と頂点色 struct MY_POSITION{ D3DXVECTOR3 p; DWORD color; }; //重み struct MY_WEIGHT{ float weight1; float weight2; float weight3; }; //使用する行列の番号 struct MY_BONE_INDEX{ DWORD matrixIndices; }; //----------------------------------------------------------------------------- // Name: MsgProc() // Desc: The window's message handler //----------------------------------------------------------------------------- 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 ); } //----------------------------------------------------------------------------- // Name: InitApp() // Desc: Initialize Window //----------------------------------------------------------------------------- HRESULT InitApp(HINSTANCE hInstance) { g_hInstance = hInstance; WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, MsgProc, 0, 0, g_hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), NULL, L"D3D Tutorial", NULL}; if( !RegisterClassEx( &wcex )){ return DXTRACE_ERR(L"InitApp", GetLastError()); } // Create the application's window g_hWindow = CreateWindow( L"D3D Tutorial", L"ゲームプログラミング", WS_OVERLAPPEDWINDOW ^WS_THICKFRAME ^ WS_MAXIMIZEBOX ^ WS_MINIMIZEBOX, 100, 100, WINDOW_X, WINDOW_Y, NULL, NULL, wcex.hInstance, NULL ); if (g_hWindow == NULL) return DXTRACE_ERR(L"InitApp", GetLastError()); return S_OK; } //----------------------------------------------------------------------------- // Name: InitDirectX() // Desc: Initialize DirectX //----------------------------------------------------------------------------- HRESULT InitDirectX(void){ g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if(g_pD3D == NULL){ DXTRACE_MSG(L"DirectXDeviceの初期化に失敗しました"); return E_FAIL; } D3DDISPLAYMODE d3ddm; if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) { DXTRACE_MSG(L"DirectX3DDeviceの初期化に失敗しました"); return E_FAIL; } D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; HRESULT hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pD3DDevice); if(FAILED(hr)) { hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,g_hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pD3DDevice); if(FAILED(hr)) { hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,g_hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pD3DDevice); if(FAILED(hr)){ DXTRACE_MSG(L"DirectX3DDeviceの初期化に失敗しました"); return E_FAIL; } } } //セットアップ レンダーステート g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); g_pD3DDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE ); g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); g_pD3DDevice->SetRenderState( D3DRS_AMBIENT, 0x33333333 ); g_pD3DDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE ); g_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); g_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); //インデックスブレンディング有効 g_pD3DDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE ); //3つの重みを使用する g_pD3DDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS ); //ビュー行列作成 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-4.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pD3DDevice->SetTransform( D3DTS_VIEW, &matView ); //射影行列作成 D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian(90.0f), (float)640/480, 1.0f, 100.0f ); g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj ); return S_OK; } //----------------------------------------------------------------------------- // Name: Uninitialize() // Desc: UnInitialize DirectX //----------------------------------------------------------------------------- void Uninitialize(void) { //デバイスなどを開放 SAFE_RELEASE(g_ib); SAFE_RELEASE(g_PositionBuf); SAFE_RELEASE(g_WeightBuf); SAFE_RELEASE(g_IndexBuf); SAFE_RELEASE(g_VertexDec); SAFE_RELEASE(g_pD3DDevice); SAFE_RELEASE(g_pD3D); } //----------------------------------------------------------------------------- // Name: WinMain() // Desc: The application's entry point //----------------------------------------------------------------------------- int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { #ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif HRESULT hr; if(FAILED(hr = InitApp(hInstance))) { return(0); } // Initialize Direct3D if( SUCCEEDED(hr = InitDirectX()) ) { MSG msg; ZeroMemory( &msg, sizeof(msg) ); ShowWindow(g_hWindow, SW_SHOWDEFAULT); UpdateWindow(g_hWindow); D3DXMATRIX mat[4]; D3DXMatrixIdentity(&mat[0]); D3DXMatrixIdentity(&mat[1]); D3DXMatrixIdentity(&mat[2]); D3DXMatrixIdentity(&mat[3]); MY_POSITION* vp; g_pD3DDevice->CreateVertexBuffer( 4*sizeof(MY_POSITION), D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &g_PositionBuf, NULL); g_PositionBuf->Lock( 0, 0, (void**)&vp, 0); vp[0].p.x = -1; vp[0].p.y = 1; vp[0].p.z = 0; vp[0].color = 0xffff0000; vp[1].p.x = 1; vp[1].p.y = 1; vp[1].p.z = 0; vp[1].color = 0xff00ff00; vp[2].p.x = -1; vp[2].p.y = -1; vp[2].p.z = 0; vp[2].color = 0xff0000ff; vp[3].p.x = 1; vp[3].p.y = -1; vp[3].p.z = 0; vp[3].color = 0xffffffff; g_PositionBuf->Unlock(); MY_WEIGHT* vw; g_pD3DDevice->CreateVertexBuffer( 4*sizeof(MY_WEIGHT), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &g_WeightBuf, NULL); g_WeightBuf->Lock( 0, 0, (void**)&vw, 0); vw[0].weight1 = 1.0f; vw[0].weight2 = 0.0f; vw[0].weight3 = 0.0f; vw[1].weight1 = 0.0f; vw[1].weight2 = 1.0f; vw[1].weight3 = 0.0f; vw[2].weight1 = 0.0f; vw[2].weight2 = 0.0f; vw[2].weight3 = 1.0f; vw[3].weight1 = 0.0f; vw[3].weight2 = 0.0f; vw[3].weight3 = 0.0f; g_WeightBuf->Unlock(); MY_BONE_INDEX* vb; g_pD3DDevice->CreateVertexBuffer( 4*sizeof(MY_BONE_INDEX), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &g_IndexBuf, NULL); g_IndexBuf->Lock( 0, 0, (void**)&vb, 0); vb[0].matrixIndices = 0x03020100; vb[1].matrixIndices = 0x03020100; vb[2].matrixIndices = 0x03020100; vb[3].matrixIndices = 0x03020100; g_IndexBuf->Unlock(); WORD *i; g_pD3DDevice->CreateIndexBuffer( 16*sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_ib, NULL); g_ib->Lock( 0, 0, (void**)&i, 0); i[0] = 0; i[1] = 1; i[2] = 2; i[3] = 3; g_ib->Unlock(); D3DVERTEXELEMENT9 vertexElem[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // 頂点座標 { 0, sizeof(float)*3, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR , 0 }, // 頂点色 { 1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT ,0 }, // ウェイト { 2, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES ,0 }, //行列番号 D3DDECL_END() }; //頂点宣言を作成 g_pD3DDevice->CreateVertexDeclaration( vertexElem, &g_VertexDec ); //頂点宣言をセット g_pD3DDevice->SetVertexDeclaration(g_VertexDec); //インデックスをセット g_pD3DDevice->SetIndices(g_ib); //バッファをセット g_pD3DDevice->SetStreamSource( 0, g_PositionBuf, 0, sizeof( MY_POSITION ) ); g_pD3DDevice->SetStreamSource( 1, g_WeightBuf, 0, sizeof( MY_WEIGHT ) ); g_pD3DDevice->SetStreamSource( 2, g_IndexBuf, 0, sizeof( MY_BONE_INDEX ) ); // Enter the message loop while( msg.message!=WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }else{ g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,60), 1.0f, 0 ); g_pD3DDevice->BeginScene(); static int n = 0; static float value = 0; n = (n + 1)%2000; value = (float)n/1000; mat[0]._42 = value; mat[1]._41 = value; mat[2]._41 = -value; mat[3]._42 = -value; g_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0),&mat[0]); g_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(1),&mat[1]); g_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(2),&mat[2]); g_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(3),&mat[3]); if(GetKeyState(VK_RIGHT) < 0){ g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 1); }else{ g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 2); } g_pD3DDevice->EndScene(); g_pD3DDevice->Present( NULL, NULL, NULL, NULL ); Sleep(1); } } } Uninitialize(); UnregisterClass( L"D3D Tutorial", g_hInstance ); return 0; }