我有一个使用 DirectX 在屏幕上呈现图形的应用程序。第一人称的默认 View 使用以下代码设置,将 Y 轴设置为 0。该代码包含在 SetupCamera() 函数中,该函数在 Render() 之前调用。
D3DXVECTOR3 vCamera(5.0f, 0.0f, -45.0f);
我正在使用 DirectInput 来管理用户输入。我希望能够让用户按下 SPACE 并将 Y 轴值更改为 90 以切换到自上而下 View ,然后再次按下将其切换回来。我目前在我的 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
(或任何其他 View vector )已更改,您需要再次调用以下代码块。我建议将代码捆绑在 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);
}
关于c++ - 根据按键修改相机位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16136145/