C ++ камера от первого лица в DirectX - PullRequest
0 голосов
/ 08 ноября 2011

Я начинающий программист, и я создаю проект, который позволяет мне ходить по комнатам с помощью камеры от первого лица. Пока я рисую здания и т.д., но теперь я застрял и не знаю, как сделать камеру от первого лица, чтобы позволить мне ходить вокруг, может ли кто-нибудь указать мне на класс камеры, который я мог бы использовать, или какой-нибудь полезный код? заранее спасибо

ниже приведен код одного из моих зданий, но не весь мой проект, его вращение, чтобы я мог видеть, что я рисовал. я хочу иметь возможность двигаться вперед и назад с помощью клавиш со стрелками, а также влево и вправо:)

#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 Ответ

2 голосов
/ 08 ноября 2011

Обычно вы создаете свою модель с помощью внешней программы (например, Blender 3D), а затем считываете модель в вашу программу.Может быть, в вашем случае было бы лучше взглянуть на существующий бесплатный игровой движок, чтобы получить лучшее представление о том, как он работает, тем, что людям нравится использовать бесплатно, является quake3 engine , который хотя и являетсянемного устаревшие должны дать вам лучшее понимание и, возможно, может служить источником вдохновения для вашего собственного двигателя.Другой рекомендуемый, более простой графический движок - Ogre3D

...