简体   繁体   English

在OpenGL中使用左上角原点

[英]Use top-left origin in OpenGL

I am trying to set my co-ordinate system such that the y-axis points down the screen. 我试图将坐标系设置为使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;

However, when I try to render 2 objects: 但是,当我尝试渲染2个对象时:

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

A appears in the centre of the screen, and B appears in the top-right. A出现在屏幕中央,B出现在右上角。 I would expect it to appear in the bottom-right. 我希望它会出现在右下角。

What am I missing here? 我在这里想念什么?

tl;dr tl; dr

My camera was positioned correctly (in a manner of speaking), but I was flipping the y-axis in the call to glOrtho . 我的相机位置正确(以某种方式),但是我在调​​用glOrtho将y轴翻转了。

Let's visualize this 让我们想象一下

Imagine a right-handed co-ordinate system such as OpenGL uses by convention: 想象一下习惯使用的右手坐标系,例如OpenGL:

  • The x-axis points right X轴指向右边
  • The y-axis points up y轴朝上
  • The z-axis points out of the screen Z轴指向屏幕外

If my objects were positioned in this world and we viewed them from the front, we would see this: 如果将我的对象放置在这个世界上,并且从正面观察它们,我们将看到:

    B
A

This is the same as what I was seeing, but we weren't viewing from the front. 这与我所看到的相同,但是我们不是从正面观看。 As @Scheff pointed out in the comments, my call to glm::lookat was flipping my camera upside-down and positioning it "behind" the screen. 正如@Scheff在评论中指出的那样,我对glm::lookat调用是将我的相机上下颠倒并将其定位在屏幕的“后面”。

Now, if you imagine that you are doing a handstand behind your monitor, A and B would now look like this: 现在,如果您想在显示器后面倒立,那么A和B现在看起来像这样:

∀
    𐐒

Wait, but isn't this what I wanted - B in the bottom-right? 等一下,但这不是我想要的吗-右下角的B?

Right, but in addition to my camera being positioned strangely, my y-axis was being flipped by the call to glm::ortho . 没错,但是除了我的相机位置不正确外,我的y轴还因为调用glm::ortho而翻转。 Normally the value for bottom should be less than the value for top (as in this example ). 通常, bottom的值应小于top的值(如本例所示 )。

Thus producing, once again: 因此,再次产生:

    B
A

So, one solution would have been to swap the top and bottom parameters in glOrtho : 因此,一种解决方案是交换glOrthotopbottom参数:

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

How to flip the y-axis "correctly" 如何“正确”翻转y轴

The solution above works, but there is a much simpler solution - or at least much simpler to visualize! 上面的解决方案有效,但是有一个更简单的解决方案-或至少要更简单地可视化! And that is just to position the camera in front of the scene and flip the y-axis using glOrtho (by keeping bottom greater than top ): 那只是将相机放置在场景的前面,并使用glOrtho翻转y轴(通过使bottom大于top ):

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

Potential problems 潜在问题

Texture orientation 纹理方向

Flipping the y-axis may result in upside-down textures, which can be fixed by swapping your top and bottom texture co-ordinates. 翻转y轴可能会产生上下颠倒的纹理,可以通过交换顶部和底部纹理坐标来进行固定。

Back-face culling 背面剔除

Viewing the scene from a different angle may result in faces being culled, if face culling is enabled. 如果启用了脸部剔除,则从不同角度查看场景可能会导致脸部剔除 This can be fixed by changing the winding order of your vertices, or by changing which faces get culled. 这可以通过固定改变你的顶点缠绕顺序,或通过改变面向得到扑杀。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM