在directx中使用c ++第一人称相机

时间:2011-11-08 11:30:07

标签: c++ camera directx frame-rate

ma初学者程序员和我正在创建一个项目,允许我通过第一人称相机走动房间到目前为止我有建筑物绘制等但现在我卡住,不知道如何制作第一人称相机允许我走动可以有人指向我可以使用的相机类或一些有用的代码吗?提前谢谢

下面是我的一个建筑物的代码,但不是我的完整项目,它的旋转,所以我可以看到我画的是什么。 我希望能够使用箭头键向左和向右移动前进和后退:)

#include <stdio.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <dinput.h>
#include <math.h>

const char TITLE[] = "game experimenting";



#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

//*****Direct 3D Initialization*****
LPDIRECT3D9             g_pD3D       = NULL; 
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; 

// Buffer to hold vertices
LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL; 

//Direct Input References
LPDIRECTINPUT8 m_pDIObject = NULL;//DirectInput object
LPDIRECTINPUTDEVICE8 m_pDIKeyboardDevice = NULL;//keyboard device
LPDIRECTINPUTDEVICE8 m_pDIMouseDevice = NULL;//mouse device
LPDIRECTINPUTDEVICE8 m_pDIJoystickDevice = NULL;//joystick device

//D3DXMATRIX Transformation Matrices
D3DXMATRIX g_matProj;
D3DXMATRIX g_matView;
D3DXMATRIX g_matWorld;
//**********************

//****** Vertex Buffer Definition and Setting ***

struct CUSTOMVERTEX
{
    FLOAT x, y, z; // The position for the vertex
    DWORD color;        // The vertex color
};


int numberOfTriangles = 34;
int numberOfVertecies = 3*numberOfTriangles;
float scale = 1.0f;
float doorHeight = 1.0f;
float doorWidth = 0.25f;

CUSTOMVERTEX g_Vertices[] =
{
    // Y +Axis 
    //Top Side Outer Wall
    { 1.0f, 1.0f,-1.0f, 0xffffffff, }, 
    { 1.0f, 1.0f,1.0f,  0xffffffff, }, 
    { -1.0f,1.0f, -1.0f, 0xffffffff,}, //Triangle 
    { -1.0f,1.0f, 1.0f, 0xffffffff,}, 
    { 1.0f, 1.0f, 1.0f, 0xffffffff, }, 
    { -1.0f,1.0f, -1.0f, 0xffffffff,}, //Triangle 
    //Top Side Inner Wall
    { 0.9f, 0.9f,-0.9f, 0x00ff0000, }, 
    { 0.9f, 0.9f,0.9f,  0x00ff0000, }, 
    { -0.9f,0.9f, -0.9f, 0x00ff0000,}, //Triangle 
    { -0.9f,0.9f, 0.9f, 0x00ff0000,}, 
    { 0.9f, 0.9f, 0.9f, 0x00ff0000, }, 
    { -0.9f,0.9f, -0.9f, 0x00ff0000,}, //Triangle 

    // X +Axis 
    //Right Side Outer Wall
    { 1.0f, 1.0f,-1.0f, 0xffffffff, }, 
    { 1.0f, 1.0f,1.0f,  0xffffffff, }, 
    { 1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle 
    { 1.0f,-1.0f, 1.0f, 0xffffffff,}, 
    { 1.0f, 1.0f, 1.0f, 0xffffffff, }, 
    { 1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle 

    //Right Side Inner Wall
    { 0.9f, 0.9f,-0.9f, 0xff0000ff, }, 
    { 0.9f, 0.9f,0.9f,  0xff0000ff, }, 
    { 0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle 
    { 0.9f,-1.0f, 0.9f, 0xff0000ff,}, 
    { 0.9f, 0.9f, 0.9f, 0xff0000ff, }, 
    { 0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle 

    // X -Axis 
    //Left Side Outer Wall
    {-1.0f, 1.0f,-1.0f, 0xffffffff, }, 
    {-1.0f, 1.0f,1.0f,  0xffffffff, }, 
    {-1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle 
    {-1.0f,-1.0f, 1.0f, 0xffffffff,}, 
    {-1.0f, 1.0f, 1.0f, 0xffffffff, }, 
    {-1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle 

    //Left Side Inner Wall
    {-0.9f, 0.9f,-0.9f, 0xff0000ff, }, 
    {-0.9f, 0.9f,0.9f,  0xff0000ff, }, 
    {-0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle 
    {-0.9f,-1.0f, 0.9f, 0xff0000ff,}, 
    {-0.9f, 0.9f, 0.9f, 0xff0000ff, }, 
    {-0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle 

    // Z +Axis  
    //Back Outer Wall
    { 1.0f,-1.0f, 1.0f, 0xffffffff, }, 
    { 1.0f, 1.0f, 1.0f, 0xffffffff, }, 
    { -1.0f,-1.0f, 1.0f, 0xffffffff,}, /////Triangle 
    { -1.0f,1.0f, 1.0f, 0xffffffff,}, 
    { 1.0f, 1.0f, 1.0f, 0xffffffff, }, 
    { -1.0f,-1.0f, 1.0f, 0xffffffff,}, /////Triangle 

    //Back Inner Wall
    { 0.9f,-1.0f, 0.9f, 0xff0000ff, }, 
    { 0.9f, 0.9f, 0.9f, 0xff0000ff, }, 
    { -0.9f,-1.0f, 0.9f, 0xff0000ff,}, /////Triangle 
    { -0.9f,0.9f, 0.9f, 0xff0000ff,}, 
    { 0.9f, 0.9f, 0.9f, 0xff0000ff, }, 
    { -0.9f,-1.0f, 0.9f, 0xff0000ff,}, /////Triangle 

    // Z Negative Axis 
    //Front Outer Wall Top1
    { 1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff, }, 
    { 1.0f, 1.0f, -1.0f, 0xffffffff, }, 
    { -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle 
    //Front Outer Wall Top2
    { -1.0f, 1.0f, -1.0f, 0xffffffff, }, 
    { 1.0f, 1.0f, -1.0f, 0xffffffff, }, 
    { -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle 
    //Front Outer Wall Left1
    { -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, 
    { -1.0f,-1.0f, -1.0f, 0xffffffff,}, 
    { -1.0f+(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,}, /////Triangle
    //Front Outer Wall Left2
    { -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, 
    { -1.0f+(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,}, 
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle
    //Front Outer Wall Right1
    { 1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, 
    { 1.0f,-1.0f, -1.0f, 0xffffffff,}, 
    { 1.0f-(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,}, /////Triangle
    //Front Outer Wall Right2
    { 1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, 
    { 1.0f-(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,}, 
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle

    //Door Inner Edges Right of door 1
    { 1.0f-(scale-doorWidth),-1.0f, -1.0f, 0xffff0099,}, 
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,}, 
    { 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
    //Door Inner Edges Right of door 2
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,}, 
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,}, 
    { 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
    //Door Inner Edges Left of door 1
    { -1.0f+(scale-doorWidth),-1.0f, -1.0f, 0xffff0099,}, 
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,}, 
    { -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
    //Door Inner Edges Left of door 2
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,}, 
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,},
    { -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
    //Door Inner Edges Top Of Door 1
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,}, 
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,}, /////Triangle
    //Door Inner Edges Top Of Door 2
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,}, 
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,}, /////Triangle

    //FRONT Inner Wall Top1
    { 0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff, }, 
    { 0.9f, 1.0f, -0.9f, 0xff0000ff, }, 
    { -0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,}, /////Triangle 
    //FRONT Inner Wall Top2
    { -0.9f, 1.0f, -0.9f, 0xff0000ff, }, 
    { 0.9f, 1.0f, -0.9f, 0xff0000ff, }, 
    { -0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,}, /////Triangle 
    //FRONT Inner Wall Left1
    { -0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,}, 
    { -0.9f,-1.0f, -0.9f, 0xff0000ff,}, 
    { -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xff0000ff,}, /////Triangle
    //FRONT Inner Wall Left2
    { -0.9f,-1.0f+doorHeight, -0.9f, 0xff0ff0ff,}, 
    { -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xff0ff0ff,}, 
    { -1.0f+(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xff0ff0ff,}, /////Triangle  
    //FRONT Inner Wall Right1
    { 0.9f,-1.0f+doorHeight, -0.9f, 0xff0ff0ff,}, 
    { 0.9f,-1.0f, -0.9f, 0xff0ff0ff,}, 
    { 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xff0ff0ff,}, /////Triangle
    //FRONT Inner Wall Right2
    { 0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,}, 
    { 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xff0000ff,}, 
    { 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xff0000ff,}, /////Triangle

    };

//*******************************************************************
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform matrices.
//-------------------------------------------------------------------
void SetupMatrices()
{
    static float time = 0.0f;
    time += 10.0f;

    D3DXMatrixIdentity( &g_matWorld );
    D3DXMatrixRotationYawPitchRoll( &g_matWorld,
        time/1000.0f,
        time/700.0f,
        time/850.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld );

    D3DXMatrixLookAtLH( &g_matView, &D3DXVECTOR3( 0.0f, 0.0f,-5.0f ),
        &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
        &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView );

    D3DXMatrixPerspectiveLH(&g_matProj, 2.0f, 2.0f/1.5f,
        1.0f, 10000.0f);
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj );
}

void TestForMouse()
{
    DIMOUSESTATE mouseState;
    m_pDIMouseDevice->GetDeviceState(sizeof(mouseState),
        (LPVOID)&mouseState);
    if(mouseState.rgbButtons[0] & 0x80) // left mouse button down
    {
    }
}

//************************ MESSAGE HANDLER **************************

LRESULT CALLBACK WindowProc(HWND hwnd, 
    UINT msg, 
    WPARAM wparam, 
    LPARAM lparam)
{
    // this is the main message handler of the system
    PAINTSTRUCT     ps; // used in WM_PAINT
    HDC             hdc;    // handle to a device context

    // what is the message 
    switch(msg)
    {   
    case WM_CREATE: 
        {
            // do initialization stuff here
            return(0);
        } 

    case WM_PAINT: 
        {
            // validate the window
            hdc = BeginPaint(hwnd,&ps);  
            EndPaint(hwnd,&ps);
            return(0);
        } 

    case WM_KEYDOWN:
        {
            // Handle any non-accelerated key commands
            switch (wparam)
            {
            case VK_ESCAPE:
            case VK_F12:
                PostMessage(hwnd, WM_CLOSE, 0, 0);
                return (0);
            default:
                char message[15];
                sprintf_s(message, "Key Pressed: %c", (char)wparam);
                MessageBox(NULL, message, "Key Pressed", MB_OK);
            }
            break;
        }

    case WM_DESTROY: 
        {
            // kill the application         
            PostQuitMessage(0);

            return(0);
        }

    default:
        break;

    } // end switch

    // process any messages that wasn't taken care of
    return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc


//********************* END OF MESSAGE HANDLER ***********************

void InitializeDX(HWND hwnd)
{ 
    if(!( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        MessageBox(hwnd,"Direct3d Create problem", NULL, NULL);

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    if(FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dpp, &g_pd3dDevice ) ) )
        MessageBox(hwnd,"CreateDevice problem", NULL, NULL);

    //InitializeCircleArray();
    //InitializeSquareArray();

    //*************************** Create Vertex Buffer ****************************
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( numberOfVertecies*sizeof(CUSTOMVERTEX),
        0 /* Usage */, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_MANAGED, &g_pVB, NULL ) ) )
        MessageBox(hwnd,"Vertex Buffer problem",NULL,NULL);

    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ) ) )
        MessageBox(hwnd,"Vertex Lock Problem",NULL,NULL);

    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );

    g_pVB->Unlock();

    g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer
}
void InitializeDI(HWND hwnd)
{
    if(FAILED(DirectInput8Create(GetModuleHandle(NULL),
        DIRECTINPUT_VERSION,
        IID_IDirectInput8,
        (void**)&m_pDIObject,
        NULL)))
        MessageBox(hwnd,"DirectInput8Create() failed!",NULL,NULL);
    // Setup Mouse Input
    if(FAILED(m_pDIObject->CreateDevice(GUID_SysMouse,
        &m_pDIMouseDevice,
        NULL)))
        MessageBox(hwnd,"CreateDevice() failed!",NULL,NULL);
    if(FAILED(m_pDIMouseDevice->SetDataFormat(&c_dfDIMouse)))
        MessageBox(hwnd,"SetDataFormat() failed!",NULL,NULL);
    if(FAILED(m_pDIMouseDevice->SetCooperativeLevel(hwnd,
        DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
        MessageBox(hwnd,"SetCooperativeLevel() failed!",NULL,NULL);
    if(FAILED(m_pDIMouseDevice->Acquire()))
        MessageBox(hwnd,"Acquire() failed!",NULL,NULL);
}

//**************************Render and display the scene***********************
void Render()
{
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );

    // Turn off D3D lighting,
    // providing our own vertex colours
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

    // Turn off culling
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        SetupMatrices();
        // Rendering of scene objects can happen here
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        //g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 179 ); // 179 triangles from 181 vertices
        //g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0,  numberOfTriangles ); //1 triangle
        // End the scene
        g_pd3dDevice->EndScene();
    }

    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//************************ WIN MAIN***********************

int WINAPI WinMain( HINSTANCE hinstance,
    HINSTANCE hprevinstance,
    LPSTR lpcmdline,
    int ncmdshow)
{
    WNDCLASS    winclass;   // this will hold the class
    HWND        hwnd;       // generic window handle
    MSG         msg;        // generic message

    // first fill in the window class stucture
    winclass.style          = CS_HREDRAW | CS_VREDRAW;                  
    winclass.lpfnWndProc    = WindowProc;
    winclass.cbClsExtra     = 0;
    winclass.cbWndExtra     = 0;
    winclass.hInstance      = hinstance;
    winclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
    //  winclass.hbrBackground  = (HBRUSH)GetStockObject(BLACK_BRUSH);
    //  winclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    winclass.hbrBackground  = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
    winclass.lpszMenuName   = NULL;
    winclass.lpszClassName  = "DX9WinClass";

    // register the window class
    if (!RegisterClass(&winclass))
        return(0);

    // create the window
    if (!(hwnd = CreateWindow( "DX9WinClass", // class
        TITLE,       // title
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0,
        0,
        //Set the size of the window to the size of the screen 
        600,
        400,
        //GetSystemMetrics(SM_CXSCREEN),
        //GetSystemMetrics(SM_CYSCREEN),
        NULL,      // handle to parent 
        NULL,      // handle to menu
        hinstance,  // instance
        NULL))) // creation parms
        return(0);

    InitializeDX(hwnd);
    InitializeDI(hwnd);

    // enter main event loop
    bool quit = false;
    while(!quit)
    {
        TestForMouse();
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        { 
            // test if this is a quit
            if (msg.message == WM_QUIT) quit = true;

            // translate any accelerator keys
            TranslateMessage(&msg);
            // send the message to the window proc
            DispatchMessage(&msg);
        } // end if
        else {
            Render();
        }

    } // end while

    //Set Mouse Free Run Away Mouse
    m_pDIMouseDevice->Release();
    // return to Windows like this
    return(msg.wParam);

} // end WinMain


//************************ END OF WIN MAIN *******************

1 个答案:

答案 0 :(得分:2)

通常您使用外部程序(例如Blender 3D)创建模型,然后将模型读入您的程序。也许在你的情况下,最好看看现有的免费游戏引擎,以更好地了解它是如何工作的,人们喜欢使用免费的是quake3 engine,虽然有点过时了让您更好地理解,也许可以作为您自己的引擎的灵感。另一个推荐的,更简单的图形引擎是Ogre3D