OpenGL ES渲染三角网格 - iPhone中的黑点和模拟器中的完美图像

时间:2011-10-16 12:48:50

标签: ios opengl-es rendering

这不是其他StackOverflow问题中描述的与纹理相关的问题:Rendering to texture on iOS...

我的Redraw循环:

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glTranslatef(0.0f, 0.0f, -300.0f);
glMultMatrixf(transform);

glVertexPointer(3, GL_FLOAT, MODEL_STRIDE, &model_vertices[0]);
glEnableClientState(GL_VERTEX_ARRAY);

glNormalPointer(GL_FLOAT, MODEL_STRIDE, &model_vertices[3]);
glEnableClientState(GL_NORMAL_ARRAY);

glColorPointer(4, GL_FLOAT, MODEL_STRIDE, &model_vertices[6]);
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_COLOR_MATERIAL);
glDrawArrays(GL_TRIANGLES, 0, MODEL_NUM_VERTICES);

模拟器中的结果:

Image rendered in the Simulator

然后是iPhone 4中的结果(使用OpenGLES 1.1的iOS5): Image rendered in the Device

注意黑点,当你旋转物体(大脑)时它们是随机的

网格有15002个顶点和30k个三角形。

有关如何在设备映像中修复此抖动的任何想法?

2 个答案:

答案 0 :(得分:3)

我已经解决了增加深度缓冲区精度的问题:

// Set up the projection
static const GLfloat zNear = 0.1f, zFar = 1000.0f, fieldOfView = 45.0f;
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
GLfloat size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
CGRect rect = self.bounds;
glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar);
glViewport(0, 0, rect.size.width, rect.size.height);
glMatrixMode(GL_MODELVIEW);

在产生抖动的代码中,zNear为0.01f

提示来自devforums.apple.com

答案 1 :(得分:2)

您发布的代码没有什么特别之处。由于模型中顶点处理的精度限制,问题很可能出在网格数据而不是代码中。如果您的相邻三角形对于它们共享的顶点的位置具有接近但不相同的值,则此类问题很常见。它也是gpu和模拟器之间通常会有所不同的类型。

你说旋转物体时黑点随意闪烁。如果您正在旋转对象,我假设您的实际代码并不总是为模型视图加载单位矩阵?

如果三角形之间的间隙远小于一个像素的投影尺寸,那么通常它们最终会被舍入到同一个像素,您将看不到任何问题。但是,如果一个顶点在一个方向上倒圆而另一个顶点在另一个方向上倒圆,则可以留下一个像素的间隙。舍入误差的位置将根据变换矩阵而变化,因此在对象旋转时将移动每一帧。

如果你加载不同的网格,你会得到相同的错误吗?

如果您的脑网格数据格式可以在3D建模应用程序中编辑,则搜索名为“焊接顶点”或“合并顶点”的选项。您将顶点的最小阈值设置为相同,并且它将查找该距离内的顶点对并移动一个(或两个)以完美匹配。许多3D建模应用程序将具有清理工具以确保网格是多方面的,这意味着(除其他外)网格中没有孔。您通常只想在3D渲染中处理流形网格。你也可以在你自己的代码中焊接顶点,虽然操作很昂贵,通常不是你想在运行时做的事情,除非你真的需要。