我有一个使用DirectX在屏幕上呈现图形的应用程序。使用以下代码设置第一人称视角的默认视图,并将Y轴设置为0。该代码包含在SetupCamera()函数中,该函数在Render()之前调用。

 D3DXVECTOR3 vCamera(5.0f, 0.0f, -45.0f);


我正在使用DirectInput来管理用户输入。我希望能够允许用户按下SPACE并将Y轴值更改为90以切换到自顶向下的视图,然后再次按下以将其切换回去。我目前在ProcessKeyboardInput()函数中具有以下代码,此代码在Render()之前调用。

if (KEYDOWN(buffer, DIK_SPACE))
{
  \\ ???
}


但是我不确定我需要做些什么来允许用户调整不会中断渲染的值。我一定在这里缺少一些简单的东西。任何帮助将非常感激。谢谢!

完整的CameraSetup()代码...

void SetupCamera()
{
// Setup View Matrix
D3DXVECTOR3 vCamera(5.0f, 0.0f, -45.0f);    // camera location  x,y,z plane
D3DXVECTOR3 vLookat(5.0f, 5.0f, 0.0f);      // camera direction x,y,z plane
D3DXVECTOR3 vUpVector(0.0f, 1.0f, 0.0f);    // which way is up x,y,z plane
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &vCamera, &vLookat, &vUpVector);
    D3D_Device -> SetTransform(D3DTS_VIEW, &matView);


 // Setup Projection Matrix to transform 2D geometry into 3D space
 D3DXMATRIX matProj;
     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
     D3D_Device -> SetTransform(D3DTS_PROJECTION, &matProj);
}


完整的ProcessKeyboardInput()代码...

void WINAPI ProcessKeyboardInput()
{
// Define a macro to represent the key detection predicate
#define KEYDOWN(name, key) (name[key] & 0x80)

// Create buffer to contain keypress data
char     buffer[256];
HRESULT  hr;

// Clear the buffer prior to use
ZeroMemory(&buffer, 256);

 hr = g_pDIKeyboardDevice -> GetDeviceState(sizeof(buffer),(LPVOID)&buffer);
if FAILED(hr)
{
    // If device state cannot be attained, check if it has been lost and try to      aquire it again
    hr = g_pDIKeyboardDevice -> Acquire();
    while (hr == DIERR_INPUTLOST) hr = g_pDIKeyboardDevice -> Acquire();

    hr = g_pDIKeyboardDevice -> GetDeviceState(sizeof(buffer),(LPVOID)&buffer);
}

bool topView = false;

if (KEYDOWN(buffer, DIK_Q))
{
    // 'Q' has been pressed - instruct the application to exit.
    PostQuitMessage(0);
}

if (KEYDOWN(buffer, DIK_SPACE))
{
    // Space has been pressed - swap from 1st person view to overhead view

    // topView is true
 topView = !topView;

 // if topView is true, adjust camera accordingly
 if (topView)
    {
        vCamera.y = 90.f;
    }
    else        // if untrue, set camera to 1st person
        {
            vCamera.y = 0.f;
        }

    }
}

最佳答案

我认为您在正确的轨道上。不用担心“中断渲染”。在任何图形应用程序中,渲染调用之间都需要进行大量处理。这样的事情怎么样:

// Have this somewhere appropriate in the code
bool topView = false;

if (KEYDOWN(buffer, DIK_SPACE))
{
    // Toggle top view
    topView = !topView;

    // Set camera vector
    if (topView) {
        vCamera.y = 90.f;
    } else {
        vCamera.y = 0.f:
    }
}


更新后,您需要将矩阵再次发送到DirectX。基本上,既然已经更改了vCamera(或任何其他视图矢量),则需要再次调用以下代码块。我建议在检查用户输入后,将代码捆绑在SetupCamera()函数中,并在Render()函数中调用它。这还需要将vCamera等移出该函数之外,以便其他函数可以使用它们。

// vCamera, vLookat, vUpVector defined outside function

// Call this in rendering loop to set up camera
void SetupCamera() {
    // Calculate new view matrix from view vectors
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &vCamera, &vLookat, &vUpVector);
    D3D_Device -> SetTransform(D3DTS_VIEW, &matView);

    // Setup Projection Matrix to transform 2D geometry into 3D space
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
    D3D_Device -> SetTransform(D3DTS_PROJECTION, &matProj);
}

08-16 10:35