• 44.输入检测响应


    初始化DirectInput系统,这仅需调用DirectInput8Create()函数即可.

    HRESULT WINAPI DirectInput8Create(
    HINSTANCE hinst,
    // 实例句柄
    DWORD dwVersion, // 版本标识符
    REFIID riidltf, // 输入系统的唯一标识符
    LPVOID * ppvOut, // 指向正在创建的输入系统对象指针
    LPUNKNOWN punkOuter // IUnKnown相关接口指针
    );

      

     如果调用成功,DirectInput8Create()函数将返回DI_OK。只要已经准备好输入系统,就可以调用LPDIRECTINPUT8输入系统的CreateDevice()成员函数创建输入设备。该函数的参数包括正在试图创建的设备的引用、正在创建的设备对象(为LPDIRECTINPUTDEVICE8类型)以及对象的可以设为NULL(空)的IUnKnown地址。对创建键盘设备而言,该设备引用可以是GUID_SysKeyboard;对创建鼠标设备而言,可以是GUID_SysMouse。

    HRESULT CreateDevice(
    REFGUID rguid,
    // 正在试图创建的设备的引用
    LPDIRECTINPUTDEVICE * lplpDirectInputDevice, // 正在创建的设备对象
    LPUNKNOWN pUnkOuter // IUnKnown相关接口指针
    );

      创建完设备后,在实际可以获取要使用的设备之前,必须先调用设备的成员函数SetDataFormat()。该函数以描述设备返回的数据格式的机构地址为参数,其值可以是c_dfDIKeyboard、c_dfDIMouse、c_dfDIMouse2、c_dfDIJoystick或c_dfDIJoystick2,这取决于正在创建的设备的类型。

    HRESULT SetDataFormat(LPCDIDATAFORMAT lpdf);

       设置完数据格式之后,就可以调用SetCooperativeLevel()函数设置设备的合作等级。SetCooperativeLevel()函数指定设备与其他设备实例以及与系统自身之间的交互方式。该函数以程序窗口句柄和指定设备合作等级的标识符为参数。如果想要获取无窗口设备,可以将该标识符设为DISCL_BACKGROUND;如果想要系统独占该设备,可以将其设为DISCL_EXCLUSIVE;如果程序在后台运行时不想获取该设备,可以将其设为DISCL_FOREGROUND;如果不想独占该设备,想和其他程序一起使用该设备,可以将其设为DISCL_NONEXCLUSIVE;如果想禁用Windows键,可以将其设为DISCL_NOWINKEY。

    HRESULT SetCooperativeLevel(
    HWND hwnd,
    // 窗口句柄
    DWORD dwFlags // 指定设备合作等级
    );

      在开始检测设备输入之前,最后一个要调用的函数是Acquire()。该函数没有任何参数,用于获取输入设备。如果设备获取成功,将返回DI_OK,否则返回其他任意值。

    HRESULT Acquire(VOID);

         为了检测来自设备的输入,就必须获取设备的当前状态。调用GetDeviceState()函数即可完成该工作。GetDeviceState()函数的参数包括用于存储设备状态的结构的大小以及存储状态的对象。每个设备都有一套可以发送给该函数的不同值。例如,为了得到键盘状态,可以只发送一个大小为256的字符数组,因为键盘上只有256个键。如果该函数运行失败,就尝试重新获取设备,调用该函数重试。如果第二次还不成功,那么该设置一定存在一些问题。

    HRESULT GetDeviceState(
    DWORD cbData,
    // 用于存储设备状态的结构的大小
    LPVOID lpvData // 存储状态的对象
    );

      因为有了GetDeviceState()函数,所以现在可以知道设备状态。这意味着可以使用一个简单的if语句判断某个按钮是否被按下。对键盘和鼠标也确实如此。关闭系统时,在释放设备之前,必须放弃设备。这通过调用Unacquire()函数即可完成。

    HRESULT Unacquire(VOID);

      游戏控制器设备

    访问键盘和鼠标设备非常简单。使用DirectInput,只要调用几个函数就可以控制该设备。另一方面,当谈及游戏控制器时,有大量工作要做。要注意的是,令初学者感到迷惑不解的并非是要做很多的工作,而是一些事情要以某种方式处理。令事情更糟糕的是,很难在DirectInput中找到对游戏控制器主题很有帮助的信息。

     创建游戏控制器时,必须使用回调函数,自己不能直接创建设备。游戏控制器设备是枚举的,而不是通过遍历所有与机器相连的可用设备人工创建的。这通过调用EnumDevices()函数即可完成。该函数的参数包括限制搜索某一类型的设备筛选类型、创建设备而被调用的回调函数的地址以及想要传给该回调函数的数值和指定设备枚举方式的标识符。指定设备枚举方式的标识符可以是DIEDFL_ALLDEVICES(枚举所有安装在机器上的设备)、DIEDFL_ATTACHEDONLY(只枚举已连接和安装的设备)、DIEDFL_FORCEFEEDBACK(枚举具有作用力反馈的设备)、DIEDFL_INCLUDEHIDDEN(枚举系统中隐藏的设备)和DIEDFL_INCLUDEPHANTOMS(枚举包含占位符的设备)。

    HRESULT EnumDevices(

      DWORD dwDevType,   // 限制搜索某一类型的设备筛选类型

      LPDIENUMDEVICESCALLBACK lpCallback,   // 创建设备而被调用的回调函数的地址

      LPVOID pvRef,      // 想要传给该回调函数的数值

      DWORD dwFlags      // 指定设备枚举方式的标识符

    );

     EnumDevices()函数负责创建设备。回调函数主要处理创建设备时需要的各项内容。留给游戏控制器唯一要做的工作是得到设备上按钮的数目。游戏控制器可以包含不同数量的按钮。一个控制器有4个按钮,而另一个可以有10个按钮,这都取决于控制器类型以及生产控制器的制造商。调用GetCapabilities()函数可以得到设备上按钮的数目。GetCapabilities()函数以用于在dwButton变量中存储设备上按钮数目的DIDEVCAPS成员变量为参数。

    HRESULT GetCapabilities(
        LPDIDEVCAPS lpDIDevCaps      // 存储设备上按钮数目
        );
        
    演示程序:
    CDirectInput.h
    #ifndef _UGP_DIRECTINPUT_H_
    #define _UGP_DIRECTINPUT_H_

    #define LEFT_BUTTON 0
    #define RIGHT_BUTTON 1

    #define KEYS_SIZE 256

    #include
    <dinput.h>


    class CDirectInputSystem
    {
    public:
    CDirectInputSystem();
    ~CDirectInputSystem();

    public:
    bool Initialize(HWND hwnd, HINSTANCE hInstance, bool mouseExclusive = false);
    bool UpdateDevices();

    // Used to create the game controllers.
    BOOL EnumDeviceCallBack(const DIDEVICEINSTANCE *inst, void* pData);

    // Keyboard functions.
    int KeyUp(unsigned int key);
    int KeyDown(unsigned int key);

    // Mouse functions.
    int MouseButtonUp(unsigned int button);
    int MouseButtonDown(unsigned int button);

    // Get mouse position (x, y) and mouse wheel data (z).
    POINT GetMousePos();
    long GetMouseWheelPos();

    // Game controller functions.
    int ControllerButtonUp(unsigned int button);
    int ControllerButtonDown(unsigned int button);

    // Get controller main (left) and right stick position.
    POINT GetLeftStickPos();
    POINT GetRightStickPos();

    void Shutdown();

    protected:
    LPDIRECTINPUT8 m_InputSystem;

    // Keyboard device.
    LPDIRECTINPUTDEVICE8 m_Keyboard;
    char m_Keys[KEYS_SIZE];
    char m_oldKeys[KEYS_SIZE];

    // Mouse device.
    LPDIRECTINPUTDEVICE8 m_Mouse;
    DIMOUSESTATE m_Mouse_State;
    DIMOUSESTATE m_oldMouse_State;

    // Mouse x, y, and wheel position.
    long m_xMPos;
    long m_yMPos;
    long m_zMPos;

    // Game controller device.
    LPDIRECTINPUTDEVICE8 m_GameControl;
    DIJOYSTATE2 m_GC_State;
    DIJOYSTATE2 m_oldGC_State;
    char m_name[256];
    bool m_controllerFound;
    unsigned
    long m_numButtons;

    // Left and right stick x and y positions.
    long m_xGCPos;
    long m_yGCPos;
    long m_xGCPos2;
    long m_yGCPos2;

    // Window handled (needed for game controllers).
    HWND m_hwnd;
    };

    #endif

      CDirectInput.cpp

    #include"CDirectInput.h"


    CDirectInputSystem
    *gThis = NULL;


    BOOL gJSEnumDeviceCallBack(
    const DIDEVICEINSTANCE *inst, void* pData)
    {
    return gThis->EnumDeviceCallBack(inst, pData);
    }


    CDirectInputSystem::CDirectInputSystem()
    {
    // Initialize objects...
    m_Keyboard = NULL;
    m_Mouse
    = NULL;
    m_GameControl
    = NULL;
    m_controllerFound
    = false;

    memset(m_name,
    0, sizeof(char) * 256);
    memset(
    &m_Mouse_State, 0, sizeof(m_Mouse_State));
    memset(
    &m_oldMouse_State, 0, sizeof(m_oldMouse_State));
    memset(m_Keys,
    0, sizeof(m_Keys));
    memset(
    &m_oldKeys, 0, sizeof(m_oldKeys));
    memset(
    &m_GC_State, 0, sizeof(m_GC_State));
    memset(
    &m_oldGC_State, 0, sizeof(m_oldGC_State));

    m_numButtons
    = 0;
    m_hwnd
    = 0;
    m_xMPos
    = 0;
    m_yMPos
    = 0;
    m_zMPos
    = 0;
    m_xGCPos
    = 0;
    m_yGCPos
    = 0;
    m_xGCPos2
    = 0;
    m_yGCPos2
    = 0;
    }


    CDirectInputSystem::
    ~CDirectInputSystem()
    {
    // Shut everything down.
    Shutdown();
    }


    bool CDirectInputSystem::Initialize(HWND hwnd, HINSTANCE hInstance, bool mouseExclusive)
    {
    // Save copies.
    m_hwnd = hwnd;
    gThis
    = this;

    // Create input system.
    if(FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8,
    (
    void **)&m_InputSystem, NULL))) return false;

    // Initialize the keyboard.
    if(FAILED(m_InputSystem->CreateDevice(GUID_SysKeyboard, &m_Keyboard, NULL)))
    return false;

    if(FAILED(m_Keyboard->SetDataFormat(&c_dfDIKeyboard))) return false;
    if(FAILED(m_Keyboard->SetCooperativeLevel(m_hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
    return false;
    if(FAILED(m_Keyboard->Acquire())) return false;

    // Clear keys will clear out the array of keys we have.
    memset(m_Keys, 0, sizeof(m_Keys));


    // Initialize the Mouse.
    DWORD flags;
    if(FAILED(m_InputSystem->CreateDevice(GUID_SysMouse, &m_Mouse, NULL))) return false;
    if(FAILED(m_Mouse->SetDataFormat(&c_dfDIMouse))) return false;

    if(mouseExclusive) flags = DISCL_FOREGROUND | DISCL_EXCLUSIVE | DISCL_NOWINKEY;
    else flags = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE;

    if(FAILED(m_Mouse->SetCooperativeLevel(m_hwnd, flags))) return false;
    if(FAILED(m_Mouse->Acquire())) return false;


    // Initialize the game controller.
    DIPROPRANGE range;
    DIDEVCAPS caps;

    m_InputSystem
    ->EnumDevices(DI8DEVCLASS_GAMECTRL, (LPDIENUMDEVICESCALLBACK)gJSEnumDeviceCallBack,
    NULL, DIEDFL_ATTACHEDONLY);

    if(!m_controllerFound) return false;

    range.diph.dwSize
    = sizeof(DIPROPRANGE);
    range.diph.dwHeaderSize
    = sizeof(DIPROPHEADER);
    range.diph.dwHow
    = DIPH_BYOFFSET;
    range.lMin
    = -1000;
    range.lMax
    = 1000;
    range.diph.dwObj
    = DIJOFS_X;
    m_GameControl
    ->SetProperty(DIPROP_RANGE, &range.diph);
    range.diph.dwObj
    = DIJOFS_Y;
    m_GameControl
    ->SetProperty(DIPROP_RANGE, &range.diph);

    if(SUCCEEDED(m_GameControl->GetCapabilities(&caps))) m_numButtons = caps.dwButtons;
    else m_numButtons = 4;

    return true;
    }


    BOOL CDirectInputSystem::EnumDeviceCallBack(
    const DIDEVICEINSTANCE *inst, void* pData)
    {
    // Set to the first device found.
    if(SUCCEEDED(m_InputSystem->CreateDevice(inst->guidInstance, &m_GameControl, NULL)))
    {
    if(SUCCEEDED(m_GameControl->SetDataFormat(&c_dfDIJoystick2)))
    if(SUCCEEDED(m_GameControl->SetCooperativeLevel(m_hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
    if(SUCCEEDED(m_GameControl->Acquire()))
    {
    strcpy(m_name, (
    char*)inst->tszProductName);
    m_controllerFound
    = true;
    return DIENUM_STOP;
    }
    }

    // Return continue to try to init other connected devices.
    return DIENUM_CONTINUE;
    }


    bool CDirectInputSystem::UpdateDevices()
    {
    // Get the device state.
    if(m_Mouse)
    {
    // Save old state for input comparing.
    memcpy(&m_oldMouse_State, &m_Mouse_State, sizeof(m_Mouse_State));

    // If error getting device state, re-aquire.
    if(FAILED(m_Mouse->GetDeviceState(sizeof(DIMOUSESTATE), &m_Mouse_State)))
    {
    if(FAILED(m_Mouse->Acquire())) return false;
    if(FAILED(m_Mouse->GetDeviceState(sizeof(DIMOUSESTATE), &m_Mouse_State)))
    return false;
    }

    m_xMPos
    += m_Mouse_State.lX;
    m_yMPos
    += m_Mouse_State.lY;
    m_zMPos
    = m_Mouse_State.lZ;
    }

    if(m_Keyboard)
    {
    // Save old state for input comparing.
    memcpy(m_oldKeys, m_Keys, sizeof(m_Keys));

    // If error getting device state, re-aquire.
    if(FAILED(m_Keyboard->GetDeviceState(sizeof(m_Keys), (LPVOID)m_Keys)))
    {
    if(FAILED(m_Keyboard->Acquire())) return false;
    if(FAILED(m_Keyboard->GetDeviceState(sizeof(m_Keys), (LPVOID)m_Keys)))
    return false;
    }
    }

    if(m_GameControl)
    {
    m_GameControl
    ->Poll();

    // Save old state for input comparing.
    memcpy(&m_oldGC_State, &m_GC_State, sizeof(m_GC_State));

    // If error getting device state, re-aquire.
    if(FAILED(m_GameControl->GetDeviceState(sizeof(DIJOYSTATE2), &m_GC_State)))
    {
    if(FAILED(m_GameControl->Acquire())) return false;
    if(FAILED(m_GameControl->GetDeviceState(sizeof(DIJOYSTATE2), &m_GC_State)))
    return false;
    }

    m_xGCPos
    = m_GC_State.lX;
    m_yGCPos
    = m_GC_State.lY;

    m_xGCPos2
    = m_GC_State.lZ;
    m_yGCPos2
    = m_GC_State.lRz;
    }

    return true;
    }


    int CDirectInputSystem::KeyUp(unsigned int key)
    {
    // If the key in the variable is not pressed then return false.
    return (!(m_Keys[key] & 0x80) && m_Keys[key] != m_oldKeys[key]);
    }


    int CDirectInputSystem::KeyDown(unsigned int key)
    {
    // If the key in the variable is not pressed then return false.
    return m_Keys[key] & 0x80;
    }


    int CDirectInputSystem::MouseButtonUp(unsigned int button)
    {
    // If the button is not clicked we return false.
    return (!(m_Mouse_State.rgbButtons[button] & 0x80) &&
    m_Mouse_State.rgbButtons[button]
    != m_oldMouse_State.rgbButtons[button]);
    }


    int CDirectInputSystem::MouseButtonDown(unsigned int button)
    {
    // If the button is clicked we return true.
    return m_Mouse_State.rgbButtons[button] & 0x80;
    }


    int CDirectInputSystem::ControllerButtonUp(unsigned int button)
    {
    if(button < 0 || button >= m_numButtons) return 0;
    return (!(m_GC_State.rgbButtons[button] & 0x80) &&
    m_GC_State.rgbButtons[button]
    != m_oldGC_State.rgbButtons[button]);
    }


    int CDirectInputSystem::ControllerButtonDown(unsigned int button)
    {
    if(button < 0 || button >= m_numButtons) return 0;
    return m_GC_State.rgbButtons[button] & 0x80;
    }


    POINT CDirectInputSystem::GetMousePos()
    {
    POINT pos;

    pos.x
    = m_xMPos;
    pos.y
    = m_yMPos;
    return pos;
    }


    long CDirectInputSystem::GetMouseWheelPos()
    {
    return m_zMPos;
    }


    POINT CDirectInputSystem::GetLeftStickPos()
    {
    POINT pos;

    pos.x
    = m_xGCPos;
    pos.y
    = m_yGCPos;
    return pos;
    }


    POINT CDirectInputSystem::GetRightStickPos()
    {
    POINT pos;

    pos.x
    = m_xGCPos2;
    pos.y
    = m_yGCPos2;
    return pos;
    }


    void CDirectInputSystem::Shutdown()
    {
    // Delete each object...
    if(m_Keyboard)
    {
    m_Keyboard
    ->Unacquire();
    m_Keyboard
    ->Release();
    m_Keyboard
    = NULL;
    }

    if(m_Mouse)
    {
    m_Mouse
    ->Unacquire();
    m_Mouse
    ->Release();
    m_Mouse
    = NULL;
    }

    if(m_GameControl)
    {
    m_GameControl
    ->Unacquire();
    m_GameControl
    ->Release();
    m_GameControl
    = NULL;
    }

    if(m_InputSystem)
    {
    m_InputSystem
    ->Release();
    m_InputSystem
    = NULL;
    }
    }

      

    main.cpp

    #include<d3d9.h>
    #include
    <d3dx9.h>
    #include
    "CDirectInput.h"

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

    #define WINDOW_CLASS "UGPDX"
    #define WINDOW_NAME "Input Detection using input"
    #define WINDOW_WIDTH 640
    #define WINDOW_HEIGHT 480

    // Function Prototypes...
    bool InitializeD3D(HWND hWnd, bool fullscreen);
    bool InitializeObjects();
    void RenderScene();
    void Shutdown();


    // Used for input initialize.
    HWND g_hwnd = 0;
    HINSTANCE g_hInstance
    = 0;


    // Direct3D object and device.
    LPDIRECT3D9 g_D3D = NULL;
    LPDIRECT3DDEVICE9 g_D3DDevice
    = NULL;


    // Matrices.
    D3DXMATRIX g_projection;
    D3DXMATRIX g_worldMatrix;
    D3DXMATRIX g_ViewMatrix;


    // Defines for which object we will display.
    #define CUBE 0
    #define SPHERE 1
    #define TEAPOT 2


    // Display objects.
    LPD3DXMESH g_teapot = NULL;
    LPD3DXMESH g_cube
    = NULL;
    LPD3DXMESH g_sphere
    = NULL;


    // Scene light source and material.
    D3DLIGHT9 g_light;
    D3DMATERIAL9 g_mat;


    // These are the x and y rotations for our objects.
    float g_xRot = 0.0f;
    float g_yRot = 0.0f;

    // This will allow us to cycle through the objects for display.
    int g_object = 0;


    // Here is our input system.
    CDirectInputSystem input;


    // Position of the mouse and game controller joysticks.
    POINT g_lastPos, g_Pos;
    POINT g_leftPos, g_rightPos;


    LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    switch(msg)
    {
    case WM_DESTROY:
    case WM_CLOSE:
    PostQuitMessage(
    0);
    return 0;
    break;
    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
    }


    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
    {
    // Register the window class
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
    GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
    WINDOW_CLASS, NULL };
    RegisterClassEx(
    &wc);

    // Create the application's window
    HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
    100, 100, WINDOW_WIDTH, WINDOW_HEIGHT,
    GetDesktopWindow(), NULL, wc.hInstance, NULL);

    // Show the window
    ShowWindow(hWnd, SW_SHOWDEFAULT);
    UpdateWindow(hWnd);

    // Record for globals.
    g_hwnd = hWnd;
    g_hInstance
    = hInst;

    // Initialize Direct3D
    if(InitializeD3D(hWnd, false))
    {
    // Enter the message loop
    MSG msg;
    ZeroMemory(
    &msg, sizeof(msg));

    while(msg.message != WM_QUIT)
    {
    if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
    TranslateMessage(
    &msg);
    DispatchMessage(
    &msg);
    }
    else
    RenderScene();
    }
    }

    // Release any and all resources.
    Shutdown();

    // Unregister our window.
    UnregisterClass(WINDOW_CLASS, wc.hInstance);
    return 0;
    }


    bool InitializeD3D(HWND hWnd, bool fullscreen)
    {
    D3DDISPLAYMODE displayMode;

    // Create the D3D object.
    g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
    if(g_D3D == NULL) return false;

    // Get the desktop display mode.
    if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
    return false;

    // Set up the structure used to create the D3DDevice
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(
    &d3dpp, sizeof(d3dpp));

    if(fullscreen)
    {
    d3dpp.Windowed
    = FALSE;
    d3dpp.BackBufferWidth
    = WINDOW_WIDTH;
    d3dpp.BackBufferHeight
    = WINDOW_HEIGHT;
    }
    else
    d3dpp.Windowed
    = TRUE;
    d3dpp.SwapEffect
    = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat
    = displayMode.Format;
    d3dpp.BackBufferCount
    = 1;
    d3dpp.EnableAutoDepthStencil
    = TRUE;
    d3dpp.AutoDepthStencilFormat
    = D3DFMT_D16;


    // Create the D3DDevice
    if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
    D3DCREATE_HARDWARE_VERTEXPROCESSING
    | D3DCREATE_PUREDEVICE,
    &d3dpp, &g_D3DDevice))) return false;

    // Initialize any objects we will be displaying.
    if(!InitializeObjects()) return false;

    return true;
    }


    bool InitializeObjects()
    {
    // Initialize input.
    // if(!input.Initialize(g_hwnd, g_hInstance))
    // return false;

    input.Initialize(g_hwnd, g_hInstance);


    // Set default rendering states.
    g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    g_D3DDevice
    ->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    g_D3DDevice
    ->SetRenderState(D3DRS_ZENABLE, TRUE);
    g_D3DDevice
    ->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_COLORVALUE(0.3f, 0.3f, 0.3f, 1.0f));


    // Setup the g_light source and material.
    g_light.Type = D3DLIGHT_DIRECTIONAL;
    g_light.Direction
    = D3DXVECTOR3(0.0f, 0.0f, 1.0f);

    g_light.Diffuse.r
    = g_light.Diffuse.g = g_light.Diffuse.b = g_light.Diffuse.a = 1.0f;
    g_light.Specular.r
    = g_light.Specular.g = g_light.Specular.b = g_light.Specular.a = 1.0f;

    g_D3DDevice
    ->SetLight(0, &g_light);
    g_D3DDevice
    ->LightEnable(0, TRUE);

    ZeroMemory(
    &g_mat, sizeof(D3DMATERIAL9));
    g_mat.Diffuse.r
    = g_mat.Ambient.r = 0.6f;
    g_mat.Diffuse.g
    = g_mat.Ambient.g = 0.6f;
    g_mat.Diffuse.b
    = g_mat.Ambient.b = 0.7f;
    g_mat.Specular.r
    = g_mat.Specular.g = g_mat.Specular.b = 0.4f;
    g_mat.Power
    = 8.0f;

    // Create meshes.
    if(FAILED(D3DXCreateTeapot(g_D3DDevice, &g_teapot, NULL)))
    return false;
    if(FAILED(D3DXCreateBox(g_D3DDevice, 3, 3, 3, &g_cube, NULL)))
    return false;
    if(FAILED(D3DXCreateSphere(g_D3DDevice, 3, 25, 25, &g_sphere, NULL)))
    return false;

    // Set the projection matrix.
    D3DXMatrixPerspectiveFovLH(&g_projection, D3DX_PI / 4,
    WINDOW_WIDTH
    /WINDOW_HEIGHT, 0.1f, 1000.0f);

    g_D3DDevice
    ->SetTransform(D3DTS_PROJECTION, &g_projection);


    // Define camera information.
    D3DXVECTOR3 cameraPos(0.0f, 0.0f, -10.0f);
    D3DXVECTOR3 lookAtPos(
    0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 upDir(
    0.0f, 1.0f, 0.0f);

    // Build view matrix.
    D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos,
    &lookAtPos, &upDir);

    return true;
    }


    void GetInput()
    {
    // Update all devices.
    input.UpdateDevices();

    // Keyboard input.
    if(input.KeyDown(DIK_ESCAPE))
    PostQuitMessage(
    0);
    if(input.KeyDown(DIK_1))
    g_object
    = CUBE;
    if(input.KeyDown(DIK_2))
    g_object
    = SPHERE;
    if(input.KeyDown(DIK_3))
    g_object
    = TEAPOT;

    // Mouse.
    g_Pos = input.GetMousePos();

    if(input.MouseButtonDown(LEFT_BUTTON))
    {
    g_xRot
    += (g_Pos.x - g_lastPos.x);
    g_yRot
    += (g_Pos.y - g_lastPos.y);
    }

    // Record last mouse pos.
    g_lastPos.x = g_Pos.x;
    g_lastPos.y
    = g_Pos.y;

    // Get mouse wheel movements.
    long mouseWheel = input.GetMouseWheelPos();
    if(mouseWheel < 0)
    g_object
    --;
    else if(mouseWheel > 0)
    g_object
    ++;
    /*
    // Game controller.
    g_leftPos = input.GetLeftStickPos();
    g_rightPos = input.GetRightStickPos();

    // Rotation amount for joysticks.
    float rotAmt = 0;

    // If the left stick (or joystick) was moved
    // to the left then set the rotation amout to a neg number.
    // Depending on how far the stickw as moved will depend on
    // how fast to rotate.
    if(g_leftPos.x < -50) rotAmt = -0.5f;
    if(g_leftPos.x < -150) rotAmt = -1.5f;
    if(g_leftPos.x < -250) rotAmt = -2.5f;
    if(g_leftPos.x < -350) rotAmt = -3.5f;

    // Else if it was moved right, set it to a positive value.
    if(g_leftPos.x > 50) rotAmt = 0.5f;
    if(g_leftPos.x > 150) rotAmt = 1.5f;
    if(g_leftPos.x > 250) rotAmt = 2.5f;
    if(g_leftPos.x > 350) rotAmt = 3.5f;

    // Apply the rotation to the g_xRot and reset the rotAmt.
    g_xRot += rotAmt;
    rotAmt = 0;

    // Do the same with the y axis of the stick.
    if(g_leftPos.y < -50) rotAmt = -0.5f;
    if(g_leftPos.y < -150) rotAmt = -1.5f;
    if(g_leftPos.y < -250) rotAmt = -2.5f;
    if(g_leftPos.y < -350) rotAmt = -3.5f;

    if(g_leftPos.y > 50) rotAmt = 0.5f;
    if(g_leftPos.y > 150) rotAmt = 1.5f;
    if(g_leftPos.y > 250) rotAmt = 2.5f;
    if(g_leftPos.y > 350) rotAmt = 3.5f;

    // Apply y rotation and clear rotAmt.
    g_yRot += rotAmt;
    rotAmt = 0;

    // Do the same thing we did for the left stick
    // with the right stick assuming one exist.
    // The joysticks center is diffrent so we do
    // 32767 minus whatever amount the joystick was
    // moved to compensate.
    if(g_rightPos.x < 32767 - 500) rotAmt = -0.5f;
    if(g_rightPos.x < 32767 - 1000) rotAmt = -1.5f;
    if(g_rightPos.x < 32767 - 1500) rotAmt = -2.5f;
    if(g_rightPos.x < 32767 - 2000) rotAmt = -3.5f;

    if(g_rightPos.x > 32767 + 500) rotAmt = 0.5f;
    if(g_rightPos.x > 32767 + 1000) rotAmt = 1.5f;
    if(g_rightPos.x > 32767 + 1500) rotAmt = 2.5f;
    if(g_rightPos.x > 32767 + 2000) rotAmt = 3.5f;

    // Apply to the x rotation.
    g_xRot += rotAmt;
    rotAmt = 0;

    // Do the same thing as with the left stick rotation. The
    // only thing is that the right stick's data is different from
    // the left. With the left when it is centered the pos is 0, 0
    // but with the right the mid is 32511. When you press the stick
    // all the way up it is 0, while all the way down is 65535. I sub
    // the mid value to make the center 0, 0. I don't use exactly
    // 32511 so you can at least put your finger on the joystick
    // without the system thinking your moving it.
    if(g_rightPos.y < 32511 - 1000) rotAmt = -0.5f;
    if(g_rightPos.y < 32511 - 3000) rotAmt = -1.5f;
    if(g_rightPos.y < 32511 - 6000) rotAmt = -2.5f;
    if(g_rightPos.y < 32511 - 12000) rotAmt = -3.5f;

    if(g_rightPos.y > 32511 + 1000) rotAmt = 0.5f;
    if(g_rightPos.y > 32511 + 3000) rotAmt = 1.5f;
    if(g_rightPos.y > 32511 + 6000) rotAmt = 2.5f;
    if(g_rightPos.y > 32511 + 12000) rotAmt = 3.5f;

    // Apply rotation.
    g_yRot += rotAmt;

    // Change depending on which button was pressed. 0 is the upper left
    // (think square on PS2 controller), 1 is lower left (X), 2 is upper
    // right (triangle on PS2 controller), 3 is lower right (circle on PS2).
    // Some controllers can have more. Mine have up to 12 not including
    // the sticks or arrow pad.
    if(input.ControllerButtonDown(0)) g_object = CUBE;
    if(input.ControllerButtonDown(1)) g_object = SPHERE;
    if(input.ControllerButtonDown(2)) g_object = TEAPOT;

    */
    // Make sure we stay within the valid values.
    if(g_object >= 3) g_object = CUBE;
    if(g_object < 0) g_object = TEAPOT;

    if(g_xRot >= 360.0f)
    g_xRot
    = 0.0f;
    if(g_yRot >= 360.0f)
    g_yRot
    = 0.0f;
    }


    void RenderScene()
    {
    // Clear the backbuffer.
    g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
    D3DCOLOR_XRGB(
    0,0,0), 1.0f, 0);

    // Begin the scene. Start rendering.
    g_D3DDevice->BeginScene();

    // Apply the view (camera).
    g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);

    g_D3DDevice
    ->SetMaterial(&g_mat);

    // Get user input.
    GetInput();

    // Used to rotate by mouse/joystick/game pad.
    D3DXMATRIX rot, rotX, rotY;

    // Set the rotation value to the matrix. Convert degress to radians.
    D3DXMatrixRotationX(&rotX, g_yRot / 180.0f * 3.141592654);
    D3DXMatrixRotationY(
    &rotY, g_xRot / 180.0f * 3.141592654);

    // Set the rotation matrix.
    rot = rotX * rotY;
    g_D3DDevice
    ->SetTransform(D3DTS_WORLD, &rot);

    // Draw our object.
    switch(g_object)
    {
    case 0:
    g_cube
    ->DrawSubset(0);
    break;

    case 1:
    g_sphere
    ->DrawSubset(0);
    break;

    case 2:
    g_teapot
    ->DrawSubset(0);
    break;

    default:
    g_object
    = 0;
    break;
    }


    // End the scene. Stop rendering.
    g_D3DDevice->EndScene();

    // Display the scene.
    g_D3DDevice->Present(NULL, NULL, NULL, NULL);
    }


    void Shutdown()
    {
    if(g_D3DDevice != NULL) g_D3DDevice->Release();
    g_D3DDevice
    = NULL;

    if(g_D3D != NULL) g_D3D->Release();
    g_D3D
    = NULL;

    if(g_teapot != NULL) g_teapot->Release();
    g_teapot
    = NULL;

    if(g_cube != NULL) g_cube->Release();
    g_cube
    = NULL;

    if(g_sphere != NULL) g_sphere->Release();
    g_sphere
    = NULL;

    input.Shutdown();
    }

      


  • 相关阅读:
    C# 多态的实现
    资料整理工具篇
    轻量级ORMPetaPoco及改进
    偶然路过,所以就留点东西吧。
    Sencha Touch 提高篇 组件选择器
    Sencha Touch 数据层篇 Proxy(上)
    Sencha Touch 数据层篇 Model
    Sencha Touch 2.0 威老的自定义组件:CardPanel
    Sencha Touch 2.0 有哪些新特征? Sencha Touch 官方指南系列
    Sencha Touch 数据层篇 Store
  • 原文地址:https://www.cnblogs.com/kex1n/p/2179341.html
Copyright © 2020-2023  润新知