Apple 的 iPhone OpenGLES 2.0 模板项目中的投影矩阵
Posted
技术标签:
【中文标题】Apple 的 iPhone OpenGLES 2.0 模板项目中的投影矩阵【英文标题】:Projection Matrix in Apple's iPhone OpenGLES 2.0 Template Project 【发布时间】:2010-12-20 19:33:18 【问题描述】:背景:
我正在尝试为 iPhone 学习 OpenGLES 2.0,但被 Apple 在 xCode 中提供的模板项目难住了。
默认项目显示一个二维正方形,但我想尝试在 z 轴上添加不同深度的顶点。
在 Apple 的默认 OpenGL 项目中,他们仅使用传递给顶点着色器的 x 和 y 坐标绘制一个 2d 正方形。
为了试验在 3d 空间中放置顶点,我在示例项目中的顶点数据中添加了一个 z 值。然后我将 glVertexAttribPointer 方法中的 size 参数从 2 更改为 3。我更改了顶点上的 z 值,希望在运行程序时它会导致正方形看起来向后倾斜。
问题是它仍然显示为相同的二维正方形。根据我的阅读,我相信这是由于投影矩阵设置为正交而不是透视造成的。
问题:
如何在 Apple 的模板 OpenGL 项目中使用 OpenGLES 2.0 将投影矩阵从 Orthographic 更改为 Perspective?
我试过了:
glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustumf(-0.5, 0.5, -0.5, 0.5, 1, 10);
但这并没有改变结果。
我也尝试在顶点着色器程序中添加类似的内容:
mat4 projectionMatrix = 2.0/320.0, 0.0, 0.0, -1.0, 0.0, 2.0/480.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0;
gl_Position *= projectionMatrix;
但这也没有用。
OpenGLES 2.0 的投影矩阵设置方法与 1.0 不同吗?我在想也许我正在尝试的东西与 2.0 不兼容。
提前致谢。
迈克
更新
感谢约翰的帮助。对此,我真的非常感激。我尝试根据您的建议添加深度缓冲区,方法是将以下代码添加到我的 EAGL 视图中的 createFramebuffer 方法,但仍然没有任何变化。
// Create depth render buffer and allocate backing store.
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
如果我将以下代码添加到我的渲染方法中:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-0.5, 0.5, -0.5, 0.5, 1, 10);
Xcode 抛出异常。有什么想法吗?
【问题讨论】:
【参考方案1】:我终于让投影工作了。
因此,这不是深度缓冲区问题,因为据我所知,除非您在多个深度构造多个对象,否则显然不需要这样做。
在 Opengles 2.0 中,您似乎需要创建自己的投影矩阵并将其应用于位置属性,以便以 3d 透视图渲染事物。问题是我在 2.0 中找不到任何用于生成矩阵的内置方法。
通过查看 Jeff LeMarche 的代码,该代码作为他关于 Opengles 2.0 的章节的一部分发布,我发现他使用文件和许多方便的方法来生成透视矩阵(以及许多其他好东西)。您可以在此处找到该示例项目:http://iphonedevelopment.blogspot.com/2010/07/opengl-es-20-book-teaser.html 该文件名为 GLCommon。谢谢杰夫!
为了创建和应用投影矩阵,我使用了 GLCommon 文件中名为 Matrix3DSetPerspectiveProjectionWithFieldOfView 的方法。
这设置了一个矩阵,可以作为一个uniform传入顶点着色器,然后乘以位置属性,然后传入gl_Position。
我们对 Matrix3DSetPerspectiveProjectionWithFieldOfView 中的近距和远距值进行了一些调整,以使内容显示在视野中。
作为对尝试学习 OpenGLES 2.0 的其他人的提示,网络上有大量关于如何在 OpenGLES 中做事的信息适用于 1.0,但没有这么说,因为它可能之前发布过2.0出来了。每当尝试确保代码适用于 2.0 时,请检查 2.0 标头。如果您使用 Apple 的模板项目,它包含两个版本的框架,因此在您构建和运行之前,您的 1.0 代码不会被识别为有问题。
【讨论】:
作为参考,我还上了一堂关于 OpenGL ES 2.0 的课程,视频可以在 iTunes U 上找到:itunes.apple.com/WebObjects/MZStore.woa/wa/…【参考方案2】:听起来您正在使用不默认使用深度缓冲区的示例。在示例项目中查找对 GL_DEPTH_COMPONENT16 的引用,并实现深度缓冲区的使用。
【讨论】:
嗨,John,我认为问题在于 glMatrixMode 在 OpenGLES 2.0 中不起作用。我查看了标题,它没有出现在 2.0 版本中,但出现在 1.0 版本中。我在网上读到一些东西,glViewport 函数在 2.0 版中取代了 glMatrixMode 和一堆其他相关函数。谁能证实这一点?谢谢!以上是关于Apple 的 iPhone OpenGLES 2.0 模板项目中的投影矩阵的主要内容,如果未能解决你的问题,请参考以下文章
iPad 或 iPhone 是不是支持 OpenGL ES 2.0?
iPhone 上的 OpenGL ES 2.0:无法超过小索引/顶点数