📄 joystick.cpp
字号:
//-----------------------------------------------------------------------------
// 名称: RenderSene.cpp
//
// 功能: 进行3D场景的渲染——使用显示内存的顶点缓冲区。
//
//-----------------------------------------------------------------------------
#include <tchar.h>
#include <windows.h>
#include <basetsd.h>
// 包含Direct3D头文件
#include <d3d8.h>
#include <d3dx8.h>
#include <dinput.h>
// Windows类的名称宏定义
#define MY_WINCLASS_NAME "Direct3D"
struct PLAYER
{
D3DXVECTOR3 LookAt[3];
};
// 定义个表示顶点的结构
struct CUSTOMVERTEX
{
FLOAT x, y, z; // x,y,z表示点的三维坐标值,
DWORD color; // 顶点颜色
};
// 自定义的顶点格式
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
// 定义全局变量
LPDIRECT3D8 g_pMyD3D = NULL; // 定义Direct3D对象的指针
LPDIRECT3DDEVICE8 g_pMyd3dDevice = NULL; // 定义Direct3D设备指针
LPDIRECT3DVERTEXBUFFER8 g_pMyVxBufferRec = NULL; // 定义顶点缓冲区对象指针
LPDIRECT3DVERTEXBUFFER8 g_pMyVxBufferLine = NULL;
PLAYER g_Player;
float g_Angle = 0;
#define LINE_VECTOR_NUM 20
// 定义包含4个顶点的顶点数组
CUSTOMVERTEX g_Vertices[] =
{
{ -1.5f, 0.0f, 0.0f, 0xffff0000, },
{ -1.5f, 2.0f, 0.0f, 0xffff0000, },
{ 1.5f, 0.0f, 0.0f, 0xffff0000, },
{ 1.5f, 2.0f, 0.0f, 0xffff0000, },
};
#define GRID_WIDTH 20.0f
#define NUM_GRID 20
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define SAMPLE_BUFFER_SIZE 8
#define TIME2FRAME 15
LPDIRECTINPUT8 g_pDirectInput = NULL;
LPDIRECTINPUTDEVICE8 g_pJoystick = NULL;
//-----------------------------------------------------------------------------
// 名称: JoystickFree()
// 功能: 释放游戏杆设备设备。
// 输入:
// 返回:
//-----------------------------------------------------------------------------
VOID JoystickFree()
{
// 释放设备
if( g_pJoystick )
g_pJoystick->Unacquire();
// 释放所有的DirectInput资源
SAFE_RELEASE( g_pJoystick );
SAFE_RELEASE( g_pDirectInput );
}
//-----------------------------------------------------------------------------
// 名称: JoystickAxesEnumCallback()
// 功能: 枚举游戏杆坐标系统时的回调函数。
// 输入: 设备对象句柄和传入的指定参数
// 返回: 函数返回DIENUM_STOP表示停止枚举操作,
// 返回DIENUM_CONTINUE表示需要继续枚举游戏杆设备。
//-----------------------------------------------------------------------------
BOOL CALLBACK JoystickAxesEnumCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
{
HWND hDlg = (HWND)pContext;
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
diprg.lMin = -1000;
diprg.lMax = +1000;
// 设置坐标的取值范围
if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
return DIENUM_STOP;
return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// 名称: JoysticksEnumCallback()
// 功能: 创建游戏杆设备时的回调函数。
// 输入: 设备句柄和传入的指定参数
// 返回: 函数返回DIENUM_STOP表示停止枚举操作,
// 返回DIENUM_CONTINUE表示需要继续枚举游戏杆设备。
//-----------------------------------------------------------------------------
BOOL CALLBACK JoysticksEnumCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext )
{
HRESULT hr;
// 根据得到的枚举设备创建DirectInput设备
hr = g_pDirectInput->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL );
// 创建失败,需要继续枚举
if( FAILED(hr) )
return DIENUM_CONTINUE;
// 使用系统中的第一个可用的游戏杆设备,停止枚举操作
return DIENUM_STOP;
}
//-----------------------------------------------------------------------------
// 名称: JoystickCreate()
// 功能: 创建游戏杆设备
// 输入: 窗口句柄
// 返回: 成功返回S_OK,
// 失败返回错误代码
//-----------------------------------------------------------------------------
HRESULT JoystickCreate( HWND hWnd )
{
HRESULT hr;
// 创建DirectInput对象
if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&g_pDirectInput, NULL ) ) )
return hr;
// 枚举游戏杆设备,并且在回调函数中创建DirectInput设备对象
if( FAILED( hr = g_pDirectInput->EnumDevices( DI8DEVCLASS_GAMECTRL,
JoysticksEnumCallback,
NULL, DIEDFL_ATTACHEDONLY ) ) )
return hr;
// 如果没有创建成功游戏杆设备,显示提示对话框
if(g_pJoystick == NULL)
{
MessageBox( NULL, "游戏杆没有找到",
"使用游戏杆设备例子程序",
MB_ICONERROR | MB_OK );
return S_OK;
}
// 设置键盘数据为通用鼠标数据格式
if( FAILED( hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick ) ) )
return hr;
// 设置鼠标的协作水平为独占方式和前台操作方式
hr = g_pJoystick->SetCooperativeLevel( hWnd, DISCL_EXCLUSIVE|DISCL_FOREGROUND );
if( hr == DIERR_UNSUPPORTED )
{
JoystickFree();
MessageBox( hWnd, _T("SetCooperativeLevel() 不支持的协作模式\n"),
_T("Mouse"), MB_OK );
return S_OK;
}
if( FAILED(hr) )
return hr;
// 枚举设备的坐标系统对象,并在回调函数中进行坐标范围的设置
if ( FAILED( hr = g_pJoystick->EnumObjects( JoystickAxesEnumCallback,
(VOID*)hWnd, DIDFT_AXIS ) ) )
return hr;
// 获取创建的键盘设备,在读取设备输入数据之前,这是必须的操作步骤
g_pJoystick->Acquire();
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: JoystickRead()
// 功能: 读取鼠标设备的输入数据。
// 输入:
// 返回: 成功返回S_OK,失败返回错误代码
//-----------------------------------------------------------------------------
HRESULT JoystickRead()
{
// 定义游戏杆数据格式
DIJOYSTATE joystick;
HRESULT hr;
ZeroMemory( &joystick, sizeof(DIJOYSTATE) );
// 在读取游戏杆设备的输入数据之前,必须轮询游戏杆设备
hr = g_pJoystick->Poll();
if FAILED(hr)
{
hr = g_pJoystick->Acquire();
while( hr == DIERR_INPUTLOST )
hr = g_pJoystick->Acquire();
return S_OK;
}
// 读取游戏杆的输入状态
if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &joystick ) ) )
return hr;
// 判断输入的方向
// 游戏杆向右方向移动的处理
if (joystick.lX > 0)
{
g_Angle+=0.01f;
g_Player.LookAt[1].x = g_Player.LookAt[0].x+sinf(g_Angle);
g_Player.LookAt[1].z = g_Player.LookAt[0].z+cosf(g_Angle);
}
// 游戏杆向左方向移动的处理
else if(joystick.lX < 0)
{
g_Angle-=0.01f;
g_Player.LookAt[1].x = g_Player.LookAt[0].x+sinf(g_Angle);
g_Player.LookAt[1].z = g_Player.LookAt[0].z+cosf(g_Angle);
}
// 游戏杆向后移动的处理
if (joystick.lY < 0)
{
g_Player.LookAt[0].x = g_Player.LookAt[0].x+sinf(g_Angle)/20;
g_Player.LookAt[0].z = g_Player.LookAt[0].z+cosf(g_Angle)/20;
g_Player.LookAt[1].x = g_Player.LookAt[1].x+sinf(g_Angle)/20;
g_Player.LookAt[1].z = g_Player.LookAt[1].z+cosf(g_Angle)/20;
}
// 游戏杆向前移动的处理
else if (joystick.lY > 0)
{
g_Player.LookAt[0].x = g_Player.LookAt[0].x-sinf(g_Angle)/20;
g_Player.LookAt[0].z = g_Player.LookAt[0].z-cosf(g_Angle)/20;
g_Player.LookAt[1].x = g_Player.LookAt[1].x-sinf(g_Angle)/20;
g_Player.LookAt[1].z = g_Player.LookAt[1].z-cosf(g_Angle)/20;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: InitD3D()
// 功能: 初始化3D环境的函数,函数中创建了Direct3D对象和Direct3D设备。
// 函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT InitMy3D( HWND hWnd )
{
// 创建Direct3D对象,是使用Direct3D的第一步操作
if( NULL == ( g_pMyD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
return E_FAIL;
// 获取当前Windows桌面的显示模式,保存到定义的d3ddm结构中
D3DDISPLAYMODE d3ddm;
if( FAILED( g_pMyD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
return E_FAIL;
// 定义Present结构
D3DPRESENT_PARAMETERS d3dpp;
// 把结构清零,创建设备时,结构中成员值为0表示使用缺省值
ZeroMemory( &d3dpp, sizeof(d3dpp) );
// 指定创建的Direct3D是支持窗口的设备
d3dpp.Windowed = TRUE;
// 指定交换效果为D3DSWAPEFFECT_DISCARD,即把后台表面显示到前台表面以后,
// 原来的后台表面包含的信息自动丢失
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// 后台缓冲区的的点格式与当前显示模式的点格式一致
d3dpp.BackBufferFormat = d3ddm.Format;
// 创建Direct3D设备:
// 1. 使用主显卡创建设备,参数D3DADAPTER_DEFAULT
// 2. 设备类型为硬件抽象设备,使用硬件加速功能,参数D3DDEVTYPE_HAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -