Изменение местоположения камеры на основе нажатия клавиш

У меня есть приложение, которое отображает графику на экране с помощью DirectX. Вид по умолчанию от первого лица устанавливается с помощью приведенного ниже кода, устанавливая ось Y на 0. Код содержится в функции SetupCamera (), которая вызывается до Render ().

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

Я использую DirectInput для управления пользовательским вводом. Я хочу, чтобы пользователь мог нажать клавишу ПРОБЕЛ и изменить значение оси 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;
}

}
}

1

Решение

Я думаю, что вы на правильном пути. Не беспокойтесь о «прерывании рендеринга». Существует много обработки между вызовами рендеринга в любом графическом приложении. Как насчет чего-то вроде этого:

// 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);
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]