D3DUtil.h
#pragma once#ifndef HR#define HR(x) { hr = x; if( FAILED(hr) ) { return hr; } } //自定义一个HR宏,方便执行错误的返回#endif#ifndef SAFE_DELETE #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } //自定义一个SAFE_RELEASE()宏,便于指针资源的释放#endif #ifndef SAFE_RELEASE #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } //自定义一个SAFE_RELEASE()宏,便于COM资源的释放#endif
DirectInputClass.h
#pragma once#include "D3DUtil.h"#define DIRECTINPUT_VERSION 0x0800#include <dinput.h>class DInputClass{private: IDirectInput8 * m_pDirectInput; IDirectInputDevice8 * m_KeyboardDevice; char m_keyBuffer[256]; IDirectInputDevice8 *m_MouseDevice; DIMOUSESTATE m_MouseState; public: HRESULT Init( HWND hWnd,HINSTANCE hInstance,DWORD keyboardCoopFlags, DWORD mouseCoopFlags ); void GetInput(); bool IsKeyDown(int iKey); bool IsMouseButtonDown(int button); float MouseDX(); float MouseDY(); float MouseDZ(); public: DInputClass(void); ~DInputClass(void); };
DirectInputClass.cpp
#include "DirectInputClass.h"DInputClass::DInputClass(){ m_pDirectInput = NULL; m_KeyboardDevice = NULL; ZeroMemory(m_keyBuffer,sizeof(char)*256); m_MouseDevice= NULL; ZeroMemory(&m_MouseState, sizeof(m_MouseState));}HRESULT DInputClass::Init( HWND hWnd,HINSTANCE hInstance,DWORD keyboardCoopFlags, DWORD mouseCoopFlags ){ HRESULT hr; HR(DirectInput8Create( hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_pDirectInput, NULL )); HR( m_pDirectInput->CreateDevice( GUID_SysKeyboard, &m_KeyboardDevice, NULL )); HR( m_KeyboardDevice->SetCooperativeLevel( hWnd, keyboardCoopFlags)); HR( m_KeyboardDevice->SetDataFormat( &c_dfDIKeyboard )); HR( m_KeyboardDevice->Acquire( )); HR( m_KeyboardDevice->Poll( )); HR( m_pDirectInput->CreateDevice( GUID_SysMouse, &m_MouseDevice, NULL )); HR( m_MouseDevice->SetCooperativeLevel( hWnd, mouseCoopFlags)); HR( m_MouseDevice->SetDataFormat( &c_dfDIMouse )); HR( m_MouseDevice->Acquire( )); HR( m_KeyboardDevice->Poll( )); return S_OK;}void DInputClass::GetInput(){ HRESULT hr = m_KeyboardDevice->GetDeviceState(sizeof(m_keyBuffer), (void**)&m_keyBuffer); if(hr) { m_KeyboardDevice->Acquire(); m_KeyboardDevice->GetDeviceState( sizeof(m_keyBuffer), (LPVOID)m_keyBuffer ); } hr = m_MouseDevice->GetDeviceState(sizeof(DIMOUSESTATE), (void**)&m_MouseState); if(hr) { m_MouseDevice->Acquire(); m_MouseDevice->GetDeviceState( sizeof(DIMOUSESTATE), (void**)&m_MouseState); }}bool DInputClass::IsKeyDown(int iKey){ if(m_keyBuffer[iKey] & 0x80) return true; else return false;}bool DInputClass::IsMouseButtonDown(int button){ return (m_MouseState.rgbButtons[button] & 0x80) != 0;}float DInputClass::MouseDX(){ return (float)m_MouseState.lX;}float DInputClass::MouseDY(){ return (float)m_MouseState.lY;}float DInputClass::MouseDZ(){ return (float)m_MouseState.lZ;}DInputClass::~DInputClass(void){ if(m_KeyboardDevice != NULL) m_KeyboardDevice->Unacquire(); if(m_MouseDevice != NULL) m_MouseDevice->Unacquire(); SAFE_RELEASE(m_KeyboardDevice); SAFE_RELEASE(m_MouseDevice); SAFE_RELEASE(m_pDirectInput);}
main.cpp
#define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 #define WINDOW_TITLE _T("【致我们永不熄灭的游戏开发梦想】对DirectInput的封装 示例程序") #include <d3d9.h>#include <d3dx9.h>#include <tchar.h>#include <time.h> #include "DirectInputClass.h"#pragma comment(lib,"d3d9.lib")#pragma comment(lib,"d3dx9.lib")#pragma comment(lib, "dinput8.lib") #pragma comment(lib,"dxguid.lib")#pragma comment(lib, "winmm.lib") LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; LPD3DXFONT g_pTextFPS = NULL; LPD3DXFONT g_pTextAdaperName = NULL; LPD3DXFONT g_pTextHelper = NULL; LPD3DXFONT g_pTextInfor = NULL; float g_FPS = 0.0f; wchar_t g_strFPS[50]={0}; wchar_t g_strAdapterName[60]={0}; D3DXMATRIX g_matWorld; DInputClass* g_pDInput = NULL; LPD3DXMESH g_pMesh = NULL; D3DMATERIAL9* g_pMaterials = NULL; LPDIRECT3DTEXTURE9* g_pTextures = NULL; DWORD g_dwNumMtrls = 0; LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );HRESULT Direct3D_Init(HWND hwnd,HINSTANCE hInstance);HRESULT Objects_Init();void Direct3D_Render( HWND hwnd);void Direct3D_Update( HWND hwnd);void Direct3D_CleanUp( );float Get_FPS();void Matrix_Set();int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd){ WNDCLASSEX wndClass = { 0 }; wndClass.cbSize = sizeof( WNDCLASSEX ) ; wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInstance; wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE); wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = L"ForTheDreamOfGameDevelop"; if( !RegisterClassEx( &wndClass ) ) return -1; HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL ); if (!(S_OK==Direct3D_Init (hwnd,hInstance))) { MessageBox(hwnd, _T("Direct3D初始化失败~!"), _T("浅墨的消息窗口"), 0); } MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true); ShowWindow( hwnd, nShowCmd ); UpdateWindow(hwnd); g_pDInput = new DInputClass(); g_pDInput->Init(hwnd, hInstance, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); PlaySound(L"偽りの饗宴.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP); MSG msg = { 0 }; while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { Direct3D_Update(hwnd); Direct3D_Render(hwnd); } } UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); return 0; }LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { case WM_PAINT: Direct3D_Render(hwnd); ValidateRect(hwnd, NULL); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) DestroyWindow(hwnd); break; case WM_DESTROY: Direct3D_CleanUp(); PostQuitMessage( 0 ); break; default: return DefWindowProc( hwnd, message, wParam, lParam ); } return 0; }HRESULT Direct3D_Init(HWND hwnd,HINSTANCE hInstance){ LPDIRECT3D9 pD3D = NULL; if( NULL == ( pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; D3DCAPS9 caps; int vp = 0; if( FAILED( pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps ) ) ) { return E_FAIL; } if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.BackBufferWidth = WINDOW_WIDTH; d3dpp.BackBufferHeight = WINDOW_HEIGHT; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; d3dpp.BackBufferCount = 2; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; d3dpp.Windowed = true; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; d3dpp.Flags = 0; d3dpp.FullScreen_RefreshRateInHz = 0; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, vp, &d3dpp, &g_pd3dDevice))) return E_FAIL; wchar_t TempName[60]=L"当前显卡型号:"; D3DADAPTER_IDENTIFIER9 Adapter; pD3D->GetAdapterIdentifier(0,0,&Adapter); int len = MultiByteToWideChar(CP_ACP,0, Adapter.Description, -1, NULL, 0); MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, g_strAdapterName, len); wcscat_s(TempName, g_strAdapterName); wcscpy_s(g_strAdapterName, TempName); if(!(S_OK==Objects_Init())) return E_FAIL; SAFE_RELEASE(pD3D) return S_OK;}HRESULT Objects_Init(){ D3DXCreateFont(g_pd3dDevice, 36, 0, 0, 1000, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("Calibri"), &g_pTextFPS); D3DXCreateFont(g_pd3dDevice, 20, 0, 1000, 0, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"华文中宋", &g_pTextAdaperName); D3DXCreateFont(g_pd3dDevice, 23, 0, 1000, 0, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"微软雅黑", &g_pTextHelper); D3DXCreateFont(g_pd3dDevice, 26, 0, 1000, 0, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"黑体", &g_pTextInfor); LPD3DXBUFFER pAdjBuffer = NULL; LPD3DXBUFFER pMtrlBuffer = NULL; D3DXLoadMeshFromX(L"Optimus.x", D3DXMESH_MANAGED, g_pd3dDevice, &pAdjBuffer, &pMtrlBuffer, NULL, &g_dwNumMtrls, &g_pMesh); D3DXMATERIAL *pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer(); g_pMaterials = new D3DMATERIAL9[g_dwNumMtrls]; g_pTextures = new LPDIRECT3DTEXTURE9[g_dwNumMtrls]; for (DWORD i=0; i<g_dwNumMtrls; i++) { g_pMaterials[i] = pMtrls[i].MatD3D; g_pMaterials[i].Ambient = g_pMaterials[i].Diffuse; g_pTextures[i] = NULL; D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_pTextures[i]); } pAdjBuffer->Release(); pMtrlBuffer->Release(); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)); Matrix_Set(); return S_OK;}void Matrix_Set(){ D3DXMATRIX matView; D3DXVECTOR3 vEye(0.0f, 0.0f, -1300.0f); D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp); g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView); D3DXMATRIX matProj; D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f, (float)((double)WINDOW_WIDTH/WINDOW_HEIGHT), 1.0f, 10000.0f); g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj); D3DVIEWPORT9 vp; vp.X = 0; vp.Y = 0; vp.Width = WINDOW_WIDTH; vp.Height = WINDOW_HEIGHT; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; g_pd3dDevice->SetViewport(&vp); }void Direct3D_Update( HWND hwnd){ g_pDInput->GetInput(); static FLOAT fPosX = 0.0f, fPosY = 0.0f, fPosZ = 0.0f; if (g_pDInput->IsMouseButtonDown(0)) { fPosX += (g_pDInput->MouseDX()) * 0.08f; fPosY += (g_pDInput->MouseDY()) * -0.08f; } fPosZ += (g_pDInput->MouseDZ())* 0.02f; if (g_pDInput->IsKeyDown(DIK_A)) fPosX -= 0.005f; if (g_pDInput->IsKeyDown(DIK_D)) fPosX += 0.005f; if (g_pDInput->IsKeyDown(DIK_W)) fPosY += 0.005f; if (g_pDInput->IsKeyDown(DIK_S)) fPosY -= 0.005f; D3DXMatrixTranslation(&g_matWorld, fPosX, fPosY, fPosZ); static float fAngleX = 0.0f, fAngleY =0.0f; if (g_pDInput->IsMouseButtonDown(1)) { fAngleX += (g_pDInput->MouseDY())* -0.01f; fAngleY += (g_pDInput->MouseDX()) * -0.01f; } if (g_pDInput->IsKeyDown(DIK_UP)) fAngleX += 0.005f; if (g_pDInput->IsKeyDown(DIK_DOWN)) fAngleX -= 0.005f; if (g_pDInput->IsKeyDown(DIK_LEFT)) fAngleY -= 0.005f; if (g_pDInput->IsKeyDown(DIK_RIGHT)) fAngleY += 0.005f; D3DXMATRIX Rx, Ry; D3DXMatrixRotationX(&Rx, fAngleX); D3DXMatrixRotationY(&Ry, fAngleY); g_matWorld = Rx * Ry * g_matWorld; g_pd3dDevice->SetTransform(D3DTS_WORLD, &g_matWorld);}void Direct3D_Render(HWND hwnd){ g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(100, 100, 100), 1.0f, 0); RECT formatRect; GetClientRect(hwnd, &formatRect); g_pd3dDevice->BeginScene(); for (DWORD i = 0; i < g_dwNumMtrls; i++) { g_pd3dDevice->SetMaterial(&g_pMaterials[i]); g_pd3dDevice->SetTexture(0, g_pTextures[i]); g_pMesh->DrawSubset(i); } int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() ); g_pTextFPS->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_RGBA(0,239,136,255)); g_pTextAdaperName->DrawText(NULL, g_strAdapterName, -1, &formatRect, DT_TOP | DT_LEFT, D3DXCOLOR(1.0f, 0.5f, 0.0f, 1.0f)); formatRect.top = 30; static wchar_t strInfo[256] = {0}; swprintf_s(strInfo,-1, L"模型坐标: (%.2f, %.2f, %.2f)", g_matWorld._41, g_matWorld._42, g_matWorld._43); g_pTextHelper->DrawText(NULL, strInfo, -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(135,239,136,255)); formatRect.left = 0,formatRect.top = 380; g_pTextInfor->DrawText(NULL, L"控制说明:", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(235,123,230,255)); formatRect.top += 35; g_pTextHelper->DrawText(NULL, L" 按住鼠标左键并拖动:平移模型", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255)); formatRect.top += 25; g_pTextHelper->DrawText(NULL, L" 按住鼠标右键并拖动:旋转模型", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255)); formatRect.top += 25; g_pTextHelper->DrawText(NULL, L" 滑动鼠标滚轮:拉伸模型", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255)); formatRect.top += 25; g_pTextHelper->DrawText(NULL, L" W、S、A、D键:平移模型 ", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255)); formatRect.top += 25; g_pTextHelper->DrawText(NULL, L" 上、下、左、右方向键:旋转模型 ", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255)); formatRect.top += 25; g_pTextHelper->DrawText(NULL, L" ESC键 : 退出程序", -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255)); g_pd3dDevice->EndScene(); g_pd3dDevice->Present(NULL, NULL, NULL, NULL); }float Get_FPS(){ static float fps = 0; static int frameCount = 0; static float currentTime =0.0f; static float lastTime = 0.0f; frameCount++; currentTime = timeGetTime()*0.001f; if(currentTime - lastTime > 1.0f) { fps = (float)frameCount /(currentTime - lastTime); lastTime = currentTime; frameCount = 0; } return fps;}void Direct3D_CleanUp(){ SAFE_RELEASE(g_pTextAdaperName) SAFE_RELEASE(g_pTextHelper) SAFE_RELEASE(g_pTextInfor) SAFE_RELEASE(g_pTextFPS) SAFE_RELEASE(g_pd3dDevice)}