#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インタフェース IDirect3DVertexDeclaration9 *g_VertexDec = NULL; //頂点宣言A(頂点座標、頂点色、ポイントサイズ) IDirect3DVertexDeclaration9 *g_VertexDec2 = NULL; //頂点宣言B(頂点座標、頂点色) LPDIRECT3DVERTEXBUFFER9 g_PositionBuf = NULL; //頂点バッファ LPDIRECT3DVERTEXBUFFER9 g_PointSizeBuf = NULL; //ポイントサイズバッファ #define VERTEX_POSITION_FVF (D3DFVF_XYZ | D3DFVF_DIFFUSE) struct VERTEX_POSITION{ float px, py, pz; DWORD color; }; struct VERTEX_POINTSIZE{ float psize; }; //----------------------------------------------------------------------------- // 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->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); //ビュー行列作成 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_VertexDec); SAFE_RELEASE(g_VertexDec2); //バッファを開放 SAFE_RELEASE(g_PositionBuf); SAFE_RELEASE(g_PointSizeBuf); //デバイスなどを開放 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; D3DXMatrixIdentity(&mat); g_pD3DDevice->SetTransform(D3DTS_WORLD, &mat); //頂点座標 & 頂点色のバッファ作成 VERTEX_POSITION* vp; g_pD3DDevice->CreateVertexBuffer( 4*sizeof(VERTEX_POSITION), D3DUSAGE_WRITEONLY, VERTEX_POSITION_FVF, D3DPOOL_MANAGED, &g_PositionBuf, NULL); g_PositionBuf->Lock( 0, 0, (void**)&vp, 0); vp[0].px = 0; vp[0].py = 2; vp[0].pz = 0; vp[0].color = 0xffff0000; vp[1].px = 2; vp[1].py = 2; vp[1].pz = 0; vp[1].color = 0xff00ff00; vp[2].px = 0; vp[2].py = 0; vp[2].pz = 0; vp[2].color = 0xff0000ff; vp[3].px = 2; vp[3].py = 0; vp[3].pz = 0; vp[3].color = 0xffffffff; g_PositionBuf->Unlock(); //ポイントサイズのバッファ作成 VERTEX_POINTSIZE* vps; g_pD3DDevice->CreateVertexBuffer( 4*sizeof(VERTEX_POINTSIZE), D3DUSAGE_WRITEONLY, D3DFVF_PSIZE, D3DPOOL_MANAGED, &g_PointSizeBuf, NULL); g_PointSizeBuf->Lock( 0, 0, (void**)&vps, 0); vps[0].psize = 5.0f; vps[1].psize = 5.0f; vps[2].psize = 5.0f; vps[3].psize = 5.0f; g_PointSizeBuf->Unlock(); //頂点宣言A(頂点座標、頂点色、ポイントサイズ) 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_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE , 0 }, // ポイントサイズ D3DDECL_END() }; //頂点宣言B(頂点座標、頂点色) D3DVERTEXELEMENT9 vertexElem2[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // 頂点座標 { 0, sizeof(float)*3, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR , 0 }, // ディフューズ D3DDECL_END() }; g_pD3DDevice->CreateVertexDeclaration( vertexElem, &g_VertexDec ); //g_VertexDec←頂点宣言A g_pD3DDevice->CreateVertexDeclaration( vertexElem2, &g_VertexDec2 );//g_VertexDec2←頂点宣言B g_pD3DDevice->SetStreamSource( 1, g_PointSizeBuf, 0, sizeof( VERTEX_POINTSIZE ) ); g_pD3DDevice->SetStreamSource( 0, g_PositionBuf, 0, sizeof( VERTEX_POSITION ) ); // 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(); if(GetKeyState(VK_RIGHT) < 0 ){ //↓この処理を行わなかった場合、←を押した後に→を押すと壊れる。(NULLにアクセスすることになる為。) g_pD3DDevice->SetStreamSource( 1, g_PointSizeBuf, 0, sizeof( VERTEX_POINTSIZE ) ); g_pD3DDevice->SetVertexDeclaration(g_VertexDec);//頂点宣言Aをセットする g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); //ポリゴン表示 g_pD3DDevice->DrawPrimitive(D3DPT_POINTLIST, 0, 4); //頂点表示 }else if(GetKeyState(VK_LEFT) < 0){ g_pD3DDevice->SetStreamSource( 1, NULL, 0, 0 );//ポイントサイズのデータ転送をやめる。 g_pD3DDevice->SetVertexDeclaration(g_VertexDec2);//頂点宣言Bをセットする g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); } g_pD3DDevice->EndScene(); g_pD3DDevice->Present( NULL, NULL, NULL, NULL ); Sleep(1); } } } Uninitialize(); UnregisterClass( L"D3D Tutorial", g_hInstance ); return 0; }