假设我在 OpenGL ES 2.0 程序上为我的 modelViewTransformation 矩阵使用身份矩阵。在这种情况下,坐标系是从 (-1,-1,-1) 延伸到 (1,1,1) 的规范 OpenGL 坐标系。
这个坐标系是右手还是左手?
一个更广泛的问题:是否有包含 OpenGL 的文档可以列出 API 遵循的所有数学约定?
假设我在 OpenGL ES 2.0 程序上为我的 modelViewTransformation 矩阵使用身份矩阵。在这种情况下,坐标系是从 (-1,-1,-1) 延伸到 (1,1,1) 的规范 OpenGL 坐标系。
这个坐标系是右手还是左手?
一个更广泛的问题:是否有包含 OpenGL 的文档可以列出 API 遵循的所有数学约定?
我的问题是,这个坐标系是右手还是左手?
默认情况下,OpenGL 始终是右手的。您可以通过自动正常创建来观察这一点。您可以通过指定每个点来强制创建左手法线,但通常右手规则始终适用。有关 OpenGL仅右手性质的更多讨论,请参阅OpenGL FAQ 中的 9.150 。
... API 遵循的所有数学约定?
目前还不清楚你在问什么。数学是基本的线性代数,重点是矩阵数学和线性变换。
编辑以回应评论问题:
但是,请记住,如果您使用的是统一矩阵调用而不是旧的 glRotates 等,则必须指定您使用的是行优先矩阵还是列优先矩阵。在这种情况下(来自评论中提到的代码):
glUniformMatrix4fv(uniforms[UNIFORM_MVP], 16, GL_FALSE, mvpMatrixZRotation);
在这个调用中,GL_FALSE
它告诉调用这是一个以列为主的矩阵,因此,产生的旋转将是预期的转置。因此,旋转将被反转,看起来像一个左手坐标系。
将其更改为GL_TRUE
,一切都会好起来的。
这是 OpenGL 讨论板中与此特定主题相关的一个非常简单的示例。
响应评论请求的另一个编辑:这是 OpenGL 中矩阵管道的另一个详细说明。请注意GL_MODELVIEW
带有三个轴的图表:它们说明了右手坐标系。常见问题解答中的上述引用也仍然适用。
ALWAYS REMEMBER!! OPENGL ONLY KNOWS NDC ,AND IT IS LEFT_HANDED!
错觉 openGL 是右手的,因为在固定管道中,固定函数是右手的,如 glOrtho(...)、glFrustrum(..),所有这些函数在可编程管道时代已被弃用。
OpenGL 并不关心您在中间矩阵过程中使用的手坐标系。如果需要,您可以使用轴坐标系,只要将其镜像到 NDC 即可。
忘记相机!
因为我们的屏幕是一个 2D 平面。想象一下,你的视口是一个黄色的橡胶平面。将这四个角松到 NDC。像这样的东西:
NDC 中的所有顶点都沿着 -z 轴撞击在黄色橡胶平面上。这就是您在真实屏幕上看到的内容。
规范化视图体积又名归一化设备坐标是左手的。这很容易通过传递单位矩阵并绘制 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中查看屏幕截图
Opengl ES 坐标系确实是右手系统,包括 (-1, -1, -1) 到 (1,1,1) 的规范体积。我已经通过代码验证了这一点。