2013-04-21 35 views
1

我有一个应用程序使用DirectX在屏幕上呈现图形。使用以下代码设置第一人的默认视图,将Y轴设置为0.该代码包含在Render()之前调用的SetupCamera()函数内。基于按键修改相机位置

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; 
     } 

    } 
} 

回答

0

我认为你是在正确的轨道上。不要担心“中断渲染”。任何图形应用程序中的渲染调用之间都有很多处理正在进行。这样的事情如何:

// 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

感谢这个维克托:)快速反应 - 我理解你的建议的逻辑,看起来不错 - 但我得到“标识符vCamera”正在实施之后不确定的(我把ProcessKeyboardInput内的布尔功能在设备设置后)。 我知道这是一个范围错误,但我不确定如何在这里正确引用vCamera.y。我试过移动 D3DXVECTOR3 vCamera(5.0f,0.0f,-45.0f); Out of the SetupCamera function and make it global,尽管错误然后消失,按空间不会改变视图,grr – Vault13 2013-04-21 21:40:29

+0

显示整个SetupCamera和Render函数,听起来像在那里有一个调用,让DirectX知道要使用的矢量 - 可能使用矩阵乘法(不熟悉DirectX)。 – 2013-04-21 21:44:23

+0

好吧,我会添加到我的初始代码,谢谢。 – Vault13 2013-04-21 21:49:08