【问题标题】:Is the OpenGL Coordinate System right-handed or left-handed?OpenGL坐标系是右手还是左手?
【发布时间】:2011-03-02 13:33:59
【问题描述】:

假设我在 OpenGL ES 2.0 程序上为我的 modelViewTransformation 矩阵使用了一个身份矩阵。本例中的坐标系是规范的 OpenGL 坐标系,从 (-1,-1,-1) 延伸到 (1,1,1)。

这个坐标系是右手还是左手?

一个更广泛的问题:是否有包含 OpenGL 的文档可以列出 API 遵循的所有数学约定?

【问题讨论】:

    标签: opengl-es coordinate-systems


    【解决方案1】:

    ALWAYS REMEMBER!! OPENGL ONLY KNOWS NDC ,AND IT IS LEFT_HANDED!

    openGL 是右手的错觉,因为在固定管道中,固定函数是右手的,如 glOrtho(...)、glFrustrum(..),所有这些函数在可编程管道时代已被弃用。

    OpenGL 并不关心您在中间矩阵过程中使用的手坐标系。如果需要,您可以使用轴坐标系,只要将其镜像到 NDC 即可。

    忘记相机!

    因为我们的屏幕是一个 2D 平面。想象一下,您的视口是一个黄色的橡胶平面。将这四个角松到 NDC。像这样的东西:

    NDC 中的所有顶点沿 -z 轴命中黄色橡胶平面。这就是您在真实屏幕上看到的。

    【讨论】:

      【解决方案2】:

      我的问题是,这个坐标是 系统是右手还是左手?

      默认情况下,OpenGL 总是用右手的。您可以通过自动正常创建来观察这一点。您可以通过指定每个点来强制创建左手法线,但通常右手规则始终适用。请参阅9.150 in the OpenGL FAQ,了解更多关于 OpenGL 仅右手性质的讨论。

      ...所有的数学约定 然后是 API?

      不清楚您要的是什么。数学是基本的线性代数,重点关注matrix math and linear transformations

      编辑回复评论问题:

      记住,但是,如果您使用的是统一矩阵调用而不是旧的 glRotates 等,则必须指定您使用的是行优先还是列优先矩阵。在这种情况下(来自评论中提到的代码):

      glUniformMatrix4fv(uniforms[UNIFORM_MVP], 16, GL_FALSE, mvpMatrixZRotation);
      

      在此调用中,GL_FALSE 告诉调用这是一个以列为主的矩阵,因此,产生的旋转将是预期的转置。因此,旋转将被反转,看起来像一个左手坐标系。

      将其更改为GL_TRUE,一切都会好起来的。

      这是来自 OpenGL 讨论板的与此特定主题相关的 very simple example

      响应评论请求的另一个编辑:OpenGL 中矩阵管道的Here is another detailed explanation。注意带有三个轴的GL_MODELVIEW 图:它们说明了右手坐标系。常见问题解答中的上述引用仍然适用。

      【讨论】:

      • 假设 OpenGL 是右撇子。假设我在屏幕上绘制 x,y 轴,变换矩阵为 Identity,然后将它们围绕 z 轴旋转角度 theta = 30 度。因此,如果系统是右手的,则旋转应该逆时针进行。但是,旋转恰好是顺时针方向,表示左手系统。所以这让我很困惑。
      • @praveen,我认为您误解了操作顺序。如果您发布实际代码,原因将变得更加清楚。查看 OpenGL 常见问题解答中的 9.070:opengl.org/resources/faq/technical/transformations.htm
      • @BobCross 嗨,鲍勃。我正在尝试在 iOS 上学习 OpenGL ES。我相信规范视图体积具有左手坐标系。我的程序中的代码可以在这里找到:link。 [要尝试此代码,只需将 XCode 生成的 iOS OpenGL 模板项目中的渲染函数替换为这个] 给定角度为正且系统为右手,旋转应逆时针方向发生。与此相反,旋转发生在顺时针方向。
      • @praveen,你的代码有一个 FALSE,它应该有一个 TRUE:你传递的是列优先而不是行优先。有关详细信息,请参阅更新的答案。
      • @bobcross 嗨,鲍勃,如果矩阵是主要列(在我的代码中就是这种情况),则转置参数应该是 GL_False。所以我不认为这个参数是问题。
      【解决方案3】:

      规范化的视图体积也就是标准化的设备坐标是/是左手的。这很容易通过传递单位矩阵并绘制 2 个三角形来测试

      float points[] = { -1,  1,  -0.5,
                         -1, -1,  -0.5,
                          1, -1,  -0.5,
      
                          1,  1,   0.5,
                         -1, -1,   0.5,
                          1, -1,   0.5 };
      

      并查看结果(使用 glEnable(GL_DEPTH_TEST))

      所以你的顶点着色器看起来像这样:

      uniform mat4 mvp_mat;
      
      // Incoming per vertex... position (fills in 1 for w if from vec3 buf)
      layout (location = 0) in vec4 v_vertex;
      
      
      void main(void) 
      { 
          // multiplying by identity doesn't transform the geometry
          gl_Position = mvp_mat * v_vertex;
      }
      

      或者你甚至可以像这样更简单地测试它,因为单位矩阵什么都不做

      layout (location = 0) in vec4 v_vertex;
      
      void main(void) 
      {
          //no transformation, no confusion, just straight to OpenGL
          gl_Position = v_vertex;
      }
      

      显然,您必须使三角形的颜色不同,这样您才能看到它们是如何重叠的。

      另请参阅这篇文章和我在其中的评论/问题: plus.google.com/114825651948330685771/posts/AmnfvYssvSe

      我不知道所有不正确的信息来自整个互联网,甚至是教科书。如果您正在谈论用于确定正面的三角形绕组(默认情况下 CCW = 右手),则 OpenGL 默认情况下仅是右手。 OpenGL 不存在世界空间、对象空间和眼睛空间,只有图形程序员才存在。 OpenGL 只取点,裁剪规范视图体积 [-1, -1, -1] x [1, 1, 1] 之外的任何内容,并将它们转换为默认情况下为 [0, w) x [ 的屏幕空间/窗口坐标0, h) x [0, 1]。如果启用深度测试,则默认行为是左撇子,向下看 +z。

      有几种方法可以解释 OpenGL 的左撇子。大多数人在他们的矩阵中处理​​它(尽管他们没有意识到)。我认为您也可以使用 glDepthFunc 更改它并将其设置为 GL_GREATER。

      http://www.opengl.org/sdk/docs/man3/xhtml/glDepthFunc.xml

      这里是左撇子的进一步证据 http://www.opengl.org/sdk/docs/man3/xhtml/glDepthRange.xml

      “经过裁剪和除以w,深度坐标范围从-1到1,对应于近裁剪平面和远裁剪平面”即正z进入屏幕=左手。您还可以使用 DepthRange 更改为右手行为。

      编辑:作为对 Bob Cross 坚持认为我错了的回应,这里有一个单一的源文件程序表明我是对的。 https://github.com/rswinkle/opengl_reference/blob/master/src/left_handed.c

      您可以在 README 中查看屏幕截图 https://github.com/rswinkle/opengl_reference

      【讨论】:

      • 哇!这是一个很好的解释。所以我的东西仍然是错误的,尽管一些矩阵数学可能已经弥补了错误的假设。
      • 谢谢。好吧,您了解我们的程序员,如果它看起来运行正常,那没关系。哈。但实际上,我添加了指向 Google+ 线程的链接,以显示混乱的另一个方面。整个行主要与列主要的崩溃进一步掩盖了这个问题。
      • 当真对不起,这是第一次真正使用 StackOverflow。我的意思是上面的评论还有更多内容,但是按回车键,显然我在 5 分钟后无法编辑它。无论如何,我会让它休息,但整个 OpenGL 惯用手和矩阵行 vs 主要老鼠巢是我的宠儿。
      • 嗨,Praveen,我知道已经快一年了,我应该问一下,但是你能改变接受的答案吗?或者也许评论鲍勃让他回应我的回答?我不想编辑他的帖子,也没有必要的代表来评论他的帖子。
      • 删除已接受的答案,因为我目前无法验证这一点,而且似乎与这件事有些分歧。所以我会让社区自己判断。
      【解决方案4】:

      Opengl ES 坐标系确实是右手系统,包括 (-1, -1, -1) 到 (1,1,1) 的规范体积。我已经通过代码验证了这一点。

      【讨论】:

        猜你喜欢
        • 2017-01-05
        • 2020-11-11
        • 2014-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多