【问题标题】:Modifying camera location based on keypress根据按键修改相机位置
【发布时间】:2013-04-21 20:57:57
【问题描述】:

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

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

    }
}

【问题讨论】:

    标签: c++ directx-9 directinput


    【解决方案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);
    }
    

    【讨论】:

    • 感谢您对此 Victor 的快速回复 :) - 我理解您的建议的逻辑,看起来不错 - 但在实施后我得到“标识符 vCamera”未定义(我将 bool 放在设置设备后的 ProcessKeyboardInput 函数)。我知道这是一个范围错误,但我不确定如何在此处正确引用 vCamera.y。我尝试移动 D3DXVECTOR3 vCamera(5.0f, 0.0f, -45.0f);退出 SetupCamera 函数并将其设为全局,尽管错误随后消失,但按空格键不会改变视图,grr
    • 显示整个 SetupCamera 和 Render 函数,听起来好像在某处有一个调用让 DirectX 知道要使用哪个向量 - 可能使用矩阵乘法(不熟悉 DirectX)。
    • 无论如何我都会继续玩它 - 你最初的想法有很大帮助 - 再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多