DX9 DirectX键盘控制程序 代码

// @time: 2012.3.26
// @author: jadeshu
// des: DirectX键盘控制程序
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <atlstr.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

#define ReleaseD3D(x)   if (x!=NULL){x->Release();x=NULL;}
#pragma comment(lib,"winmm.lib")

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"dinput8.lib")
#pragma comment(lib, "dxguid.lib")


//全局变量
TCHAR g_szWindowName[]=_T("DirectX键盘控制程序");
BOOL bActive = TRUE;
char g_pKeyStateBuffer[256]={0};
//定义设备接口
IDirect3DDevice9 * g_pd3dDevice=NULL;

LPDIRECTINPUT8 g_pDirectInput=NULL;  //DirectInput接口
LPDIRECTINPUTDEVICE8 g_pKeyboardDevice=NULL;  //键盘输入接口
LPD3DXMESH g_pMeshTeapot=NULL;  //茶壶网格对象

//回调函数声明
LRESULT CALLBACK WinProc(HWND hwnd,
						 UINT uMsg,
						 WPARAM wParam,
						 LPARAM lParam
							);
//初始化Direct3D函数声明
HRESULT Init3D(HWND hwnd,HINSTANCE hinstance);
//渲染声明
VOID Render();
//清除对象声明
VOID Cleanup();

//读取设备的输入数据
BOOL ReadDevice(IDirectInputDevice8 *pDIDevice,void *pBuffer,long ISize);

//主函数
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow
				   )
{
	//定义窗口类结构
	TCHAR szAppName[]=TEXT("ClassN");
	WNDCLASSEX wc;
	HWND hwnd;
	MSG msg;
	ZeroMemory(&msg,sizeof(msg));
	wc.cbClsExtra=0;
	wc.cbSize=sizeof(WNDCLASSEX);
	wc.cbWndExtra=0;
	wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.hCursor=LoadCursor(hInstance,IDC_ARROW);
	wc.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
	wc.hIconSm=NULL;
	wc.hInstance=hInstance;
	wc.lpfnWndProc=WinProc;
	wc.lpszClassName=szAppName;
	wc.lpszMenuName=NULL;
	wc.style=CS_HREDRAW|CS_VREDRAW;
	//注册窗口
	RegisterClassEx(&wc);
	//创建窗口	
	hwnd=CreateWindow(szAppName,g_szWindowName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
		NULL,NULL,hInstance,0);
	//加载3D初始化
	if (FAILED(Init3D(hwnd,hInstance)))
	{
		return FALSE;
	}
	//显示和更新窗口
	ShowWindow(hwnd,nCmdShow);
	UpdateWindow(hwnd);

	//消息循环
	while (WM_QUIT!=msg.message)
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			//转换消息
			TranslateMessage(&msg);
			//投递消息
			DispatchMessage(&msg);
		}
		else if(bActive)
		{
			//渲染
			Render();
		}
		else
		{
			if(!WaitMessage())
				return -1;
		}
	}
	//删除注册窗口
	UnregisterClass(szAppName,hInstance);
	return msg.wParam;

}

//回调函数
LRESULT CALLBACK WinProc(HWND hwnd,
						 UINT uMsg,
						 WPARAM wParam,
						 LPARAM lParam
							)
{
	switch (uMsg)
	{
	case WM_PAINT:
		Render();                        //渲染
		ValidateRect(hwnd,NULL);		 //更新窗口
		return 0;
	case WM_ACTIVATEAPP:
		bActive = (BOOL)wParam;
		break;
	case WM_DESTROY:
		Cleanup();						 //清除对象
		PostQuitMessage(0);				 //退出消息循环
		return 0;
	}
	return DefWindowProc(hwnd,uMsg,wParam,lParam);    //返回默认消息
}

//Direct3D初始化
HRESULT Init3D(HWND hwnd,HINSTANCE hinstance)
{
	IDirect3D9 *pD3D=NULL;                         //定义对象接口
	pD3D=Direct3DCreate9(D3D_SDK_VERSION);         //创建对象接口
	if (NULL==pD3D)
	{
		return E_FAIL;
	}
	D3DCAPS9 caps;								   //获取硬件设备信息
	int vp=0;
	pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps);
	if (caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)
	{
		vp=D3DCREATE_HARDWARE_VERTEXPROCESSING;
	}
	else
	{
		vp=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	}

	//创建Direct3D设备接口
	D3DPRESENT_PARAMETERS d3dpp;
	d3dpp.AutoDepthStencilFormat=D3DFMT_D24S8;
	d3dpp.BackBufferCount=1;
	d3dpp.BackBufferFormat=D3DFMT_A8R8G8B8;
	d3dpp.BackBufferHeight=640;
	d3dpp.BackBufferWidth=480;
	d3dpp.EnableAutoDepthStencil=FALSE;
	d3dpp.Flags=0;
	d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
	d3dpp.hDeviceWindow=hwnd;
	d3dpp.MultiSampleQuality=0;
	d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
	d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;
	d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed=TRUE;

	if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&g_pd3dDevice)))
	{
		return E_FAIL;
	}
	D3DXCreateTeapot(g_pd3dDevice,&g_pMeshTeapot,0);  //创建茶壶集合体

	//创建DirectInput设备
	DirectInput8Create(hinstance,0x0800,IID_IDirectInput8,(void **)&g_pDirectInput,NULL);
	//创建键盘设备
	g_pDirectInput->CreateDevice(GUID_SysKeyboard,&g_pKeyboardDevice,NULL);
	//设置数据格式和协作级别
	g_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
	g_pKeyboardDevice->SetCooperativeLevel(hwnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
	//获取设备
	g_pKeyboardDevice->Acquire();

	////世界变换矩阵
	//D3DXMATRIX matWorld,Rx,Ry,Rz;
	//D3DXMatrixIdentity(&matWorld);
	//D3DXMatrixRotationX(&Rx,/*::timeGetTime()/1000*/1.0f);
	//D3DXMatrixRotationY(&Ry,/*::timeGetTime()/1000*//*1.0f*/::timeGetTime()/1000.0f);
	//D3DXMatrixRotationZ(&Rz,/*::timeGetTime()/1000.0f*//*::timeGetTime()/1000*/1.0f);
	//matWorld=Rx*Ry*Rz*matWorld;
	//g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);

	//取景变换矩阵
	D3DXMATRIX matView;
	D3DXVECTOR3 vEye(0.0f,0.0f,-10.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,1.0f,1.0f,1000.0f);
	g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
	pD3D->Release();
	return S_OK;
}

//渲染图形
VOID Render()
{
	g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
	g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(150,150,255),1.0f,0);   //清除后台缓冲区
	g_pd3dDevice->BeginScene();		//开始绘制
	
	::ZeroMemory(g_pKeyStateBuffer,sizeof(g_pKeyStateBuffer));
	ReadDevice(g_pKeyboardDevice,g_pKeyStateBuffer,sizeof(g_pKeyStateBuffer));
	////平移物体
	static FLOAT fPosX=0.0f,fPosY=0.0f;
	if(g_pKeyStateBuffer[DIK_A]&0x80) fPosX-=0.01f;
	if(g_pKeyStateBuffer[DIK_D]&0x80) fPosX+=0.01f;
	if(g_pKeyStateBuffer[DIK_W]&0x80) fPosY+=0.01f;
	if(g_pKeyStateBuffer[DIK_S]&0x80) fPosY-=0.01f;
	D3DXMATRIX matWorld;
	D3DXMatrixTranslation(&matWorld,fPosX,fPosY,0.0f);

	//旋转物体
	static float fAngleX=0.0f,fAngleY=0.0f,fAngleZ=0.0f;
	if(g_pKeyStateBuffer[DIK_UP]&0x80) fAngleX-=0.01f;
	if(g_pKeyStateBuffer[DIK_DOWN]&0x80) fAngleX+=0.01f;
	if(g_pKeyStateBuffer[DIK_LEFT]&0x80) fAngleY+=0.01f;
	if(g_pKeyStateBuffer[DIK_RIGHT]&0x80) fAngleY-=0.01f;
	
	D3DXMATRIX Rx,Ry;
	D3DXMatrixRotationX(&Rx,fAngleX);
	D3DXMatrixRotationY(&Ry,fAngleY);


	matWorld=Rx*Ry*matWorld;
	g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);

	//绘制茶壶
	g_pMeshTeapot->DrawSubset(0);
	g_pd3dDevice->EndScene();		//结束绘制
	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);  //从后台缓冲区复制到前台----翻转
}

//清除对象,内存
VOID Cleanup()
{
	g_pKeyboardDevice->Unacquire();
	ReleaseD3D(g_pMeshTeapot);
	ReleaseD3D(g_pKeyboardDevice);
	ReleaseD3D(g_pDirectInput);
	ReleaseD3D(g_pd3dDevice);
	
	//if (g_pMeshTeapot!=NULL)
	//{
	//	g_pMeshTeapot->Release();
	//	g_pMeshTeapot=NULL;
	//}
	//if (g_pKeyboardDevice!=NULL)
	//{
	//	g_pKeyboardDevice->Release();
	//	g_pKeyboardDevice=NULL;
	//}
	//if (g_pDirectInput!=NULL)
	//{
	//	g_pDirectInput->Release();
	//	g_pDirectInput=NULL;
	//}
	//if (g_pd3dDevice!=NULL)
	//{
	//	g_pd3dDevice->Release();
	//	g_pd3dDevice=NULL;
	//}

}

BOOL ReadDevice(IDirectInputDevice8 *pDIDevice,void *pBuffer,long ISize)
{
	HRESULT hr;
	while(true)
	{
		/*pDIDevice->Poll();*/
		pDIDevice->Acquire();
		if (SUCCEEDED(hr=pDIDevice->GetDeviceState(ISize,pBuffer))) break;
		if (hr!=DIERR_INPUTLOST||hr!=DIERR_NOTACQUIRED) return FALSE;
		/*if (FAILED(pDIDevice->Acquire())) return FALSE	*/;
	}
	return TRUE;
}

 

posted @ 2019-01-01 05:59  jadeshu  阅读(452)  评论(0编辑  收藏  举报