在OpenGL中使用左上角原点

时间:2019-08-28 08:00:59

标签: c++ opengl glm-math

我正在尝试设置坐标系,以使y轴指向屏幕下方。

// Determine view-projection matrix
glm::mat4 projection = glm::ortho(
    -3.0f,    // left
    3.0f,     // right
    3.0f,     // bottom
    -3.0f);   // top

// Right handed rule:
// x points right
// y points down
// z points into the screen
glm::mat4 view = glm::lookAt(
    glm::vec3(0, 0, -1),    // camera position
    glm::vec3(0, 0, 0),     // look at
    glm::vec3(0, -1, 0)     // up vector
);

glm::mat4 viewProjMatrix = projection * view;

但是,当我尝试渲染2个对象时:

A at (0, 0)
B at (1, 1)

A出现在屏幕中央,而B出现在右上角。我希望它会出现在右下角。

我在这里想念什么?

1 个答案:

答案 0 :(得分:0)

tl; dr

我的相机位置正确(以某种方式讲),但是我在向glOrtho的通话中翻转了y轴。

让我们想象一下

想象一下习惯使用的右手坐标系,例如OpenGL:

  • x轴指向右
  • y轴朝上
  • z轴指向屏幕之外

如果我的物体位于这个世界上,并且我们从正面观察它们,我们将看到:

    B
A

这与我看到的内容相同,但是我们从正面查看。正如@Scheff在评论中指出的那样,我对glm::lookat的呼叫是将摄像机颠倒过来并将其定位在屏幕“后面”。

现在,如果您想在显示器后面倒立,那么A和B现在看起来像这样:

∀
    ?

等等,但这不是我想要的吗-右下角的B?

是的,但是除了我的相机位置不正确之外,对glm::ortho的调用也使我的y轴发生了翻转。通常,bottom的值应小于top的值(如this example一样。)

因此再次产生:

    B
A

因此,一种解决方案是交换top中的bottomglOrtho参数:

glm::mat4 view = glm::lookAt(
    glm::vec3(0, 0, -1),    // camera position
    glm::vec3(0, 0, 0),     // look at
    glm::vec3(0, -1, 0)     // up vector
);
glm::mat4 projection = glm::ortho(
    -3.0f,      // left
    3.0f,       // right
    -3.0f,      // bottom (less than top -> y-axis is not inverted!)
    3.0f);      // top

如何“正确”翻转y轴

以上解决方案有效,但是有一个更简单的解决方案-或至少要更简单地可视化!那只是将相机放置在场景的前面,并使用glOrtho(通过使bottom大于top来翻转y轴):

glm::mat4 view = glm::lookAt(
    glm::vec3(0, 0, 1),     // camera position
    glm::vec3(0, 0, 0),     // look at
    glm::vec3(0, 1, 0)      // up vector
);
glm::mat4 projection = glm::ortho(
    -3.0f,      // left
    3.0f,       // right
    3.0f,       // bottom (greater than top -> y-axis is inverted!)
    -3.0f);     // top

潜在问题

纹理方向

翻转y轴可能会产生上下颠倒的纹理,可以通过交换顶部和底部纹理坐标来固定。

背面剔除

如果启用face culling,则从不同角度查看场景可能会导致人脸被剔除。可以通过更改顶点的缠绕顺序或更改哪些面被剔除来解决此问题。