⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyboard.cpp

📁 是《3D游戏编程》的代码 买了这本书
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// 名称: 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

#define KEYDOWN(name, key) (name[key] & 0x80)

LPDIRECTINPUT8       g_pDI       = NULL;         
LPDIRECTINPUTDEVICE8 g_pKeyboard = NULL;     


//-----------------------------------------------------------------------------
// 名称: FreeDirectInput()
// 功能: 释放键盘设备。
//       
//-----------------------------------------------------------------------------
VOID KeyboardFree()
{
    // 释放设备
    if( g_pKeyboard ) 
        g_pKeyboard->Unacquire();
    
    // 释放所有的DirectInput资源
    SAFE_RELEASE( g_pKeyboard );
    SAFE_RELEASE( g_pDI );
}


//-----------------------------------------------------------------------------
// 名称: KeyboardCreate()
// 功能: 创建键盘设备。
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT KeyboardCreate( HWND hWnd )
{
    HRESULT hr;      
	DIPROPDWORD dipdw;

    // 创建DirectInput对象
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                                         IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
        return hr;
    
    // 创建DirectInput设备对象
    if( FAILED( hr = g_pDI->CreateDevice( GUID_SysKeyboard, &g_pKeyboard, NULL ) ) )
        return hr;
    
    // 设置键盘数据为通用键盘数据格式,使用256字节的数组保存按键状态
    if( FAILED( hr = g_pKeyboard->SetDataFormat( &c_dfDIKeyboard ) ) )
        return hr;
   
	// 设置键盘的协作水平为非独占方式和前台操作方式
	hr = g_pKeyboard->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );

    if( hr == DIERR_UNSUPPORTED )
    {
        KeyboardFree();
        MessageBox( hWnd, _T("SetCooperativeLevel() 不支持的协作模式\n"), 
						  _T("Keyboard"), MB_OK );
        return S_OK;
    }

    if( FAILED(hr) )
        return hr;


    // 对于立即数据,需要把输入数据的缓冲区大小设置为0,任何输入数据直接读取,
	// 不需要存放在缓冲区中
	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = SAMPLE_BUFFER_SIZE; 

    if( FAILED( hr = g_pKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
		return hr;

	// 获取创建的键盘设备,在读取设备输入数据之前,这是必须的操作步骤
    g_pKeyboard->Acquire();

    return S_OK;
}


//-----------------------------------------------------------------------------
// 名称: KeyboardRead()
// 功能: 读取键盘设备的输入数据。
//       
//-----------------------------------------------------------------------------
HRESULT KeyboardRead()
{
	char     buffer[256]; 
	HRESULT  hr; 
		
	hr = g_pKeyboard->GetDeviceState(sizeof(buffer),(LPVOID)&buffer); 
	if FAILED(hr) 
	{ 
        hr = g_pKeyboard->Acquire();
        while( hr == DIERR_INPUTLOST ) 
            hr = g_pKeyboard->Acquire();

        return S_OK; 
	} 

	// 从buffer 数组中取按键值进行处理
	// 判断输入的方向键
	// 右方向键按下的处理 
	if (KEYDOWN(buffer, DIK_RIGHT))
	{
		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(KEYDOWN(buffer, DIK_LEFT))
	{
		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 (KEYDOWN(buffer, DIK_UP)) 
	{
	    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 (KEYDOWN(buffer, DIK_DOWN))
	{
		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
    // 3. 使用前面创建的窗口用于目标表面的显示,参数hWnd
	// 4. 指定设备的对于顶点的处理能力为软件处理顶点,这是为了能够让所有
	//    的显卡支持,参数D3DCREATE_SOFTWARE_VERTEXPROCESSING
    if( FAILED( g_pMyD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pMyd3dDevice ) ) )
    {
        return E_FAIL;
    }

    g_pMyd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    g_pMyd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

	// 定义一个保存顶点缓冲区内存地址的指针
    VOID* pVertices;

	// 创建顶点缓冲区
    if( FAILED( g_pMyd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pMyVxBufferRec ) ) )
    {
        return E_FAIL;
    } 

	// 获得顶点缓冲区的内存指针,并锁定顶点缓冲区
    if( FAILED( g_pMyVxBufferRec->Lock( 0, sizeof(g_Vertices), (BYTE**)&pVertices, 0 ) ) )
	{
        return E_FAIL;
	}

	// 复制顶点数据到顶点缓冲区中
    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -