Direct3D轮回:构建基于DirectInput机制的鼠标输入设备

键盘、鼠标、游戏杆是最为常用的游戏输入设备。

Xna直接向客户提供了对于以上输入设备的支持。例如,我们可以直接使用

MouseState mouseState = Mouse.GetState();

获取鼠标输入设备的当前状态,从而进一步检测各个键位的当前状态。Keyboard、GamePad用法与Mouse类似,在此不再赘述。

回到Direct3D环境中。因为工程本身基于Win32App,所以我们可以获得窗口消息的支持,从而检测鼠标和键盘的当前状态。不过,处于效率考虑,这里推荐大家使用更加高效的机制——DirectInput。

下面我们构建基于DirectInput机制的鼠标输入设备。

1.在前篇工程基础上新建CD3DInput类;

/-------------------------------------



代码清单:D3DInput.h

来自:
http://www.cnblogs.com/kenkao



-------------------------------------
/



#include
"D3DInit.h"

#include
<dinput.h>

#pragmacomment(lib, "dinput8.lib")



#defineBUTTONSTATE_PRESSED 0x01

#defineBUTTONSTATE_RELEASED 0x00



#pragmaonce



classCMouseInput

{

public:

CMouseInput();

~CMouseInput();

HRESULT Initialize(HINSTANCE hInst,HWND hWnd);
//初始化输入设备

voidGetState();//获取设备状态

DWORD LeftButton();//鼠标左键状态

DWORD MiddleButton();//鼠标滚轮状态

DWORD RightButton();//鼠标右键状态

voidRelease();//释放输入设备

longMouseMoveX();//鼠标X方向偏移

longMouseMoveY();//鼠标Y方向偏移

voidSetPosition(POINT point);//设置鼠标位置

voidGetPosition(POINT&point);//获取鼠标位置

LONG GetWheelLenth();//获取滚轮滚动的距离

private:

HWND m_hWnd;
//设备所属的窗口句柄

LPDIRECTINPUT8 m_pIDirectInput;//IDirectInput接口对象

LPDIRECTINPUTDEVICE8 m_pIDirectInputDevice;//IDirectInput设备对象

DIMOUSESTATE m_mouseState;//鼠标状态结构体

};

Direct3D轮回:构建基于DirectInput机制的鼠标输入设备Direct3D轮回:构建基于DirectInput机制的鼠标输入设备D3DInput.cpp/-------------------------------------



代码清单:D3DInput.cpp

来自:
http://www.cnblogs.com/kenkao



-------------------------------------
/





#include
"StdAfx.h"

#include
"D3DInput.h"



CMouseInput::CMouseInput() : m_pIDirectInput(NULL),

m_pIDirectInputDevice(NULL)

{



}



CMouseInput::
~CMouseInput()

{



}



HRESULT CMouseInput::Initialize(HINSTANCE hInst,HWND hWnd)

{

m_hWnd
=hWnd;

HRESULT hr;

//创建IDirectInput接口对象

hr=DirectInput8Create(hInst,DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&m_pIDirectInput,NULL);

if(FAILED(hr)){

returnhr;

}

//初始化鼠标输入设备

hr=m_pIDirectInput->CreateDevice(GUID_SysMouse,&m_pIDirectInputDevice,NULL);//GUID_SysMouse代表初始化设备为鼠标设备

if(FAILED(hr)){

ReleaseCOM(m_pIDirectInput);

returnhr;

}

//设置鼠标设备的数据格式

hr=m_pIDirectInputDevice->SetDataFormat(&c_dfDIMouse);

if(FAILED(hr)){

ReleaseCOM(m_pIDirectInputDevice);

ReleaseCOM(m_pIDirectInput);

returnhr;

}

//设置鼠标设备的协调级别

hr=m_pIDirectInputDevice->SetCooperativeLevel(hWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);

if(FAILED(hr)){

ReleaseCOM(m_pIDirectInputDevice);

ReleaseCOM(m_pIDirectInput);

returnhr;

}

//获取鼠标设备访问权限

hr=m_pIDirectInputDevice->Acquire();

returnS_OK;

}



voidCMouseInput::GetState()

{

HRESULT hr;

DWORD dwReadNum
=1;

hr
=m_pIDirectInputDevice->GetDeviceState(sizeof(m_mouseState),(LPVOID)&m_mouseState);

if(FAILED(hr)){

hr
=m_pIDirectInputDevice->Acquire();

}

}



DWORD CMouseInput::LeftButton()

{

if(m_mouseState.rgbButtons[0]&0x80)

{

returnBUTTONSTATE_PRESSED;

}

else

returnBUTTONSTATE_RELEASED;

}



DWORD CMouseInput::MiddleButton()

{

if(m_mouseState.rgbButtons[2]&0x80)

{

returnBUTTONSTATE_PRESSED;

}

else

returnBUTTONSTATE_RELEASED;

}



DWORD CMouseInput::RightButton()

{

if(m_mouseState.rgbButtons[1]&0x80)

{

returnBUTTONSTATE_PRESSED;

}

else

returnBUTTONSTATE_RELEASED;

}



voidCMouseInput::Release()

{

//释放鼠标设备访问权限

m_pIDirectInputDevice->Unacquire();

ReleaseCOM(m_pIDirectInputDevice);

ReleaseCOM(m_pIDirectInput);

}



voidCMouseInput::SetPosition(POINT point)

{

ScreenToClient(m_hWnd,
&point);

SetCursorPos(point.x,point.y);

}



voidCMouseInput::GetPosition(POINT&point)

{

GetCursorPos(
&point);

ScreenToClient(m_hWnd,
&point);

}



LONG CMouseInput::GetWheelLenth()

{

returnm_mouseState.lZ;

}

虽然构建的类名为CD3DInput,不过我实际写入的类名是CMouseInput,后续可能会把键盘和游戏杆输入设备的构建也放到这两个文件里,引用起来比较方便。

默认情况下,DirectInput设备以立即模式获取输入信息,意味着数据读取的前一刻,输入信息不会被DirectInput记录。

与立即模式相对的是缓冲模式,输入信息将被放在一个缓冲区内,供DirectInput设备读取。

这里我们运用立即模式构建鼠标输入设备。

通过GetDeviceState函数,我们将当前的鼠标设备状态获取到名为DIMOUSESTATE的结构体中。关于这个结构体的定义,大家可以看下SDK的说明文档,很好理解~

完成各个键位的检测之后,便可在前篇工程的代码基础上加入鼠标输入设备的单元测试代码。

2.丰富D3DGame.cpp的代码内容;
Direct3D轮回:构建基于DirectInput机制的鼠标输入设备Direct3D轮回:构建基于DirectInput机制的鼠标输入设备D3DGame.cpp/-------------------------------------



代码清单:D3DGame.cpp

来自:
http://www.cnblogs.com/kenkao



-------------------------------------
/



#include
"StdAfx.h"

#include
"D3DGame.h"

#include
<stdio.h>



HINSTANCE g_hInst;

HWND g_hWnd;

IDirect3D9
g_pD3D=NULL;

IDirect3DDevice9
g_pD3DDevice=NULL;

CMouseInput
*g_pMouseInput=NULL;



//鼠标输入单元测试函数

voidTestMouseInput();



voidInitialize(HINSTANCE hInst, HWND hWnd)

{

g_hInst
=hInst;

g_hWnd
=hWnd;

InitD3D(
&g_pD3D,&g_pD3DDevice, hWnd);

g_pMouseInput
=newCMouseInput;

g_pMouseInput
->Initialize(hInst,hWnd);

}



voidLoadContent()

{



}



voidUpdate()

{

TestMouseInput();

}



voidDraw()

{

g_pD3DDevice
->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(100,149,237,255),1.0f,0);

if(SUCCEEDED(g_pD3DDevice->BeginScene()))

{

g_pD3DDevice
->EndScene();

}

g_pD3DDevice
->Present(NULL, NULL, NULL, NULL);

}



voidUnloadContent()

{



}



voidDispose()

{

ReleaseCOM(g_pMouseInput);

ReleaseCOM(g_pD3DDevice);

ReleaseCOM(g_pD3D);

}



voidTestMouseInput()

{

POINT point;

g_pMouseInput
->GetState();

g_pMouseInput
->GetPosition(point);

TCHAR tmpText[
50];

if(g_pMouseInput->LeftButton()==BUTTONSTATE_PRESSED)

{

sprintf(tmpText,
"鼠标左键已按下,X-Y坐标为(%d,%d)",point.x,point.y);

MessageBox(NULL,tmpText,
"提示",MB_OK|MB_ICONINFORMATION);

}

elseif(g_pMouseInput->MiddleButton()==BUTTONSTATE_PRESSED)

{

sprintf(tmpText,
"鼠标滚轮已按下,X-Y坐标为(%d,%d)",point.x,point.y);

MessageBox(NULL,tmpText,
"提示",MB_OK|MB_ICONINFORMATION);

}

elseif(g_pMouseInput->RightButton()==BUTTONSTATE_PRESSED)

{

sprintf(tmpText,
"鼠标右键已按下,X-Y坐标为(%d,%d)",point.x,point.y);

MessageBox(NULL,tmpText,
"提示",MB_OK|MB_ICONINFORMATION);

}

}

我们为Initialize新增一个HINSTANCE hInst参数,这个参数在初始化鼠标输入设备时要用到,之后,通过

g_pMouseInput = new CMouseInput;

g_pMouseInput->Initialize(hInst,hWnd);

来完成鼠标输入设备的声明及初始化。

我们在Update函数中调用鼠标输入单元检测函数TestMouseInput。该函数中,首先要通过

g_pMouseInput->GetState();

获取当前的设备状态,其实也就是输入信息的读取。之后便可对鼠标各个键位状态进行检测。

当然,最后不要忘记在Dispose函数中调用

ReleaseCOM(g_pMouseInput);//联动调用CMouseInput::Release()函数

将我们构建的鼠标输入设备释放掉~ 这是C++环境,GC的工作只能我们自己完成咯 ^ ^

如下为效果图:

Direct3D轮回:构建基于DirectInput机制的鼠标输入设备

回到最初,我们之所以认为DirectInput是一种更加高效的机制,是因其基于硬件驱动实现。

感兴趣的朋友不妨做个实验:

在 开始--->控制面板--->鼠标 中更换左右键功能,DirectInput设备不受影响,因为控制面板里的设置是基于软件实现的~

Good Luck~

原文链接: https://www.cnblogs.com/kenkao/archive/2011/06/22/2087111.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/27526

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午5:08
下一篇 2023年2月8日 上午5:08

相关推荐