c ++第一人称摄像头在directx [英] c++ first person camera in directx

查看:338
本文介绍了c ++第一人称摄像头在directx的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

m a beginner programmer and im creating a project which allows me to walk around rooms via a first person camera so far i have the buildings drawn etc but now im stuck and don't know how to make a first person camera to allow me to walk around could anyone point me towards a camera class i could use or some useful code? thanks in advance

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

below is the code for one of my buildings but not my full project, its rotating so i could see what i was drawing. i want to be able to move forwards and backwards using the arrow keys and also left and right :)

#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 *******************


推荐答案

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

Normally you create your model using an external program (e.g. Blender 3D) and then read the model into your program. Maybe in your case it would be better to take a look at an existing free game engine to get a better idea of how it works, one that people like to use which is free is the quake3 engine which although a bit dated should give you a better understanding and maybe can act as inspiration for your own engine. Another recommended, more simpler graphics engine is Ogre3D

这篇关于c ++第一人称摄像头在directx的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆