|
40 ----------------------- Page 41----------------------- INT Count, //显示的文本字符串中字符的数量,如果为-1则 参数Format取值: 3D LPDIRECT3DDEVICE9 pDevice, //Direct3D设备 实现游戏控制 DirectInput 41 ----------------------- Page 42----------------------- 创建DirectInput对象: HINSTANCE hinst, //windows进程句柄 DWORD dwVersion, //版本通常取DIRECTINPUT_VERSION REFIID riidltf, //接口的标识,通常取 LPVOID *ppvOut, //返回的DirectInput对象指针 LPUNKNOWN punkOuter //COM对象指针,一般取NULL LPDIRECTINPUT8 m_pDInput; if (DI_OK!=DirectInput8Create(hInst,DIRECTINPUT_VERSION, IID_IDirectInput8,(LPVOID*)&m_pDInput,NULL)) { MessageBox(hWnd,"创建DInput对象失败!","ERROR",MB_OK); } 创建设备对象: REFGUID rguid, //设备标识 LPDIRECTINPUTDEVICE *lplpDirectInputDevice, //DirectInput设备对象 LPUNKNOWN pUnkOuter //COM对象 LPDIRECTINPUTDEVICE8 m_pKeyboard; //创建键盘设备 if (DI_OK!=M_PdiNPUT->cREATEdEVICE(guid_SysKeyboard,&m_pKeyboard,NULL)) { MessageBox(HWND,"创建键盘设备失败!","ERROR",MB_ICONERROR|MB_OK); } 1.设置键盘设备状态: LPCDIDATAFORMAT lpdf //数据格式 参数lpdf可选择为: c_dfDIKeyboard //标准键盘对象 //设置数据格式 { MessageBox(HWND,"创建键盘数据格式失败!","ERROR",MB_ICONERROR|MB_OK); ----------------------- Page 43----------------------- } 2.设置键盘协调层级 ( HWND hwnd; //窗口 DWORD dwFlags //设备协调层级 HRESULT ConfigureDevices( LPDICONFIGUREDEVICESCALLBACK lpdiCallback, //每次设备改变的回 调函数 LPDICONFIGUREDEVICESPARAMS lpdiCDParams, //设备参数 DWORD dwFlags, //附加标识 LPVOID pvRefData //传给回调函数的参数 //下面代码设置设备的协调层级为前台非独占模式 DISCL_NONEXCLUSIVE|DISCL_FOREGROUND; ); 3.获取键盘输入 在获取设备前必须设置好数据格式或动作映射,设备丢失时可以在窗口激活消息相应设置过程中 重新获取设备; If(WM_INACTIVE!=wParam&&m_pKeyboard) { //窗口激活后获取设备控制权 } Break; 4.读取键盘数据 (1)键盘立即数据 DWORD cbData, //数据大小 LPVOID lpvData //数据 DirectInput常见键码见课本P335; (2)键盘缓冲数据 设置缓冲区大小 REFGUID rguidProp, //设置缓冲区大小,取值 LPCDIPROPHEADER pdiph // ); 读取键盘缓冲数据 43 ----------------------- Page 44----------------------- HRESULT IDirectInputDevice8::GetDeviceData( DWORD cbObjectData, // LPDIDEVICEOBJECTDATA rgdod, // LPDWORD pdwInOut, // DWORD dwFlags // ); 4.释放设备 释放设备的访问权 如果需要重新使用设备则需要调用: 5.释放对象 SAFE_RELEASE(m_pKeyboard); SAFE_RELEASE(m_pDInput); ================================================================= DirectInput 1初始化 if (DI_OK!=DirectInput8Create(hInst,DIRECTINPUT_VERSION, IID_IDirectInput8,(LPVOID*)&m_pDInput,NULL)) { MessageBox(hWnd,"创建DInput对象失败!","ERROR",MB_OK); } if (DI_OK!=m_pDInput->CreateDevice(GUID_SysMouse,&m_pDinputMouse,NULL)) { MessageBox(HWND,"创建鼠标设备失败!","ERROR",MB_ICONERROR|MB_OK); } 2设置数据格式 P338 3设置鼠标协调层级 DISCL_EXCLUSIVE :使用该模式后光标会消失,无法点击窗口以外的其他窗口内容 DISCL_NONEXCLUSIVE :可以移动到该窗口外的点击其它任意窗口,原应用程序失去控制 权 DISCL_FOREGROUND :只有在前台模式下获取鼠标输入 DISCL_BACKgROUND :指定在前台和后台模式下都可以获取鼠标输入 4获取鼠标控制权 5获取鼠标数据 使用鼠标的坐标系统 44 ----------------------- Page 45----------------------- REFGUID rguidProp, LPCDIPROPHEADER pdiph ); rguidProp=DIPROP_AXISMODE; 定义有智能的鼠标 立即数据 LONG lX; //鼠标移动量 LONG lZ; BYTE rgbButtons[4]; //按键状态,最高为1表示按下,0表示松开 缓冲数据 DWORD dwOfs; //表示的是哪个设备对象的事件 DWORD dwData; //相当于rgbButtons[4]中dwofs指明 的哪个 DWORD dwSequence; UINT_PTR uAppData; } DIDEVICEOBJECTDATA, *LPDIDEVICEOBJECTDATA; typedef const DIDEVICEOBJECTDATA *LPCDIDEVICEOBJECTDATA; 第一个参数dwOfs可取值为 DIMOFS_X DIMOFS_Y DIMOFS_Z 6处理鼠标丢失 使用Acquire函数重新获取设备 7释放设备 SAFE_RELEASE(m_pDInputMouse); SAFE_RELEASE(m_pDInput); ================================================================= 鼠标拣选 1 2计算拾取射线 下面代码片断就是通过单击屏幕上的一个点来计算出拾取射线 Ray CalculateRay() 45 ----------------------- Page 46----------------------- { floatpx = 0.0f; floatpy = 0.0f; //获取视口大小 D3DVIEWPORT9vp; m_pDevice->GetViewport(&vp); D3DXMATRIXproj; m_pDevice->GetTransform(D3DTS_PROJECTION,&proj); //计算拾取射线 px =(((2.0f*x)/vp.Width)-1.0f)/proj._11; py =(((-2.0f*y)/vp.Height)+1.0f)/proj._22; Ray ray; ray._origin= (0,0,0); ray._dirction= (px,py,1); returnray; } 3射线转换 下面的代码片断将拾取射线转换到世界空间中 Ray TransformRay(Rayray,D3DXMATRIX*T) { ray transRay; //转换射线的起点 D3DXVec3TransformCoord(&transRay._origin,&ray._origin,T); //转换射线的方向 D3DXVec3TransformNormal(&transRay._dirction,&ray._dirction,T); D3DXVec3Normalize(&transRay._dirction,&transRay._dirction); returntransRay; } |