OpenGL相机扫射不起作用

Posted

技术标签:

【中文标题】OpenGL相机扫射不起作用【英文标题】:OpenGL Camera Strafing doesnt work 【发布时间】:2016-05-01 15:24:35 【问题描述】:

我目前正在开发 OpenGL 框架/引擎,就 OpenGL 部分而言,我对我的结果非常满意。 另一方面,我在让相机工作时遇到了一个严重的问题。 沿 Z 轴移动效果很好,但是一旦我开始扫射(沿 X 轴移动),整个场景就搞砸了。 您可以在下图中看到扫射的结果。 左边部分显示实际场景,右边部分显示由扫射运动产生的场景。

我的代码如下。 在构造函数中:

    //Info is a Struct with Default values
    m_projectionMatrix = glm::perspective(
    info.fieldOfView, width / height,   //info.fov = 90
    info.nearPlane, info.farPlane       // info.near = 0.1f, info.far = 1000
    );

    //m_pos = glm::vec3(0.0f,0.0f,0.0f), info.target = glm::vec3(0.0f, 0.0f, -1.0f)
    m_viewMatrix = glm::lookAt(m_pos, m_pos + info.target, Camera::UP);

    //combine projection and view
    m_vpMatrix = m_projectionMatrix * m_viewMatrix;

在“更新”方法中,我目前正在执行以下操作:

glm::mat4x4 Camera::GetVPMatrix()

    m_vpMatrix = glm::translate(m_vpMatrix, m_deltaPos);
    return m_vpMatrix;

据我所知: 投影矩阵实现了实际的透视图。最初,视图矩阵平移和旋转整个场景,它是居中的吗? 那么为什么用任何 Z 值转换 VP-Matrix 都可以,但用 X 值却不行呢?

我想实现这样的相机行为: 初始凸轮位置是(0,0,0),“中心”是例如(0,0,-1)。 然后 X = 5 平移后:Cam Pos 为 (5,0,0),Center 为 (5,0,-1)。

编辑:附加问题。 为什么VP-Transformation会影响Z坐标?

感谢您的帮助! 最好的问候,克里斯托夫。

【问题讨论】:

【参考方案1】:

好的,我终于找到了解决方案...如您所见,我正在使用 GLM 进行矩阵数学运算。 GLM 按列主要顺序存储其矩阵值。 Open GL 也需要列主要有序矩阵。 C/C++ 原生 2d 数组布局主要是行,所以大多数可用的 OpenGL/C++ 教程都指出,应该使用

    glUniformMatrix4fv(location, 1, GL_TRUE, &mat[0][0]);

在 GL_TRUE 的含义下,矩阵应该从行主要顺序转换(转置?)到列主要顺序。由于我的矩阵已经采用列主要格式,这完全没有意义......

把上面改成

    glUniformMatrix4fv(location, 1, GL_FALSE, &mat[0][0]);

解决了我的问题...

【讨论】:

如果此解决方案解决了您的问题,您应该将此答案标记为已接受(即使它是您自己的答案!),以便其他人看到这是适合您的解决方案。【参考方案2】:

矩阵数学不是我的强项,所以我无法解释为什么您当前的方法不起作用,尽管我有怀疑(翻译投影矩阵似乎不正确)。以下应该允许您移动相机:

// update your camera position
m_pos = new_pos;
// update the view matrix
m_viewMatrix = glm::lookAt(m_pos, m_pos + info.target, Camera::UP);
// update the view-projection matrix, projection matrix never changes
m_vpMatrix = m_projectionMatrix * m_viewMatrix;

【讨论】:

这不会产生以“目标”为中心的视图吗? glm lookAt 应该产生一个聚焦目标点的矩阵,因此不会实现真正的扫射运动。另外,在进行轮换时,会出现同样的问题吗? 查看您的代码,您的目标只是 m_pos 的任意偏移量,而不是世界上的固定点。这意味着随着相机位置的移动,目标也会移动。我假设您这样做是因为您希望相机在相对于相机的固定方向上“看”。 是的,这就是我想要的。当相机横向移动时,焦点应该这样做,“航向”应该保持不变。 代码应该是你想要的。 m_pos 是相机在世界中的位置。相机目标应该是相机的位置 + 归一化的方向向量。您如何计算 UP 向量并不明显。 UP 是 const glm::vec3(0.0f, 1.0f, 0.0f)。我不想滚动运动,所以这应该没问题。

以上是关于OpenGL相机扫射不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 OpenGL 纹理不起作用?

此顶点着色器中的统一浮动不起作用

OpenGL移动对象不起作用

反应本机相机,onBarCodeRead 不起作用

OpenGL 抗锯齿不起作用

Opengl为啥这个着色器不起作用?