OpenGL ES 推荐的显示背景图片的方法

4

在OpenGL ES应用程序中显示背景图像的推荐方法是什么?

  1. 将UIImage添加到glview下面的视图层次结构中?
  2. 从内存中的纹理绘制OpenGL绘制例程中的图像?

有没有需要考虑的性能/内存问题?


1
不要尝试在EAGLView下方渲染任何内容 - 这会降低性能,因为EAGLView需要被标记为透明。 - Till
2个回答

3

我喜欢使用苹果的Texture2D类来加载纹理。创建一个四边形(两个三角形,六个顶点),将其映射到屏幕的四个角落。然后将纹理坐标映射到这些顶点上,传递给glDrawArrays函数即可。我实际上有一个类,它接收CG坐标中的一个帧,将其转换为OpenGL坐标并在该帧中绘制图像。

假设你有这样一个结构体:

struct {
  GLfloat x;             // OpenGL X Coordinate
  GLfloat y;             // OpenGL Y Coordinate
  GLfloat z;             // OpenGL Z Coordinate
  GLfloat s;             // Texture S Coordinate
  Glfloat t;             // Texture T Coordinate
} vertexData;

还有一个像这样的顶点数据数组:

struct vertexData verts[6];

您有一个Texture2D对象:

 texture = [[Texture2D alloc] initWithImage:[UIImage imageNamed:image] filter:filter pixelFormat:pixelFormat];

现在,你需要填充顶点数组。假设是3D场景,x范围为[-1,1],y范围为[-1,1],z轴以原点为起点,那么你可以按照以下方式初始化顶点:

verts[0].x = verts[1].x = verts[5].x = -1.0;
verts[2].x = verts[3].x = verts[4].x = 1.0;

verts[0].y = verts[2].y = verts[4].y = 1.0;
verts[1].y = verts[3].y = verts[5].y = -1.0;

verts[0].z = verts[1].z = verts[2].z = 0.0;
verts[3].z = verts[4].z = verts[5].z = 0.0;

verts[0].s = verts[1].s = verts[5].s = tlxf;
verts[2].s = verts[3].s = verts[4].s = trxf;

verts[0].t = verts[2].t = verts[4].t = ttyf;
verts[1].t = verts[3].t = verts[5].t = tbyf;

最后,您需要绘制:
glBindTexture(GL_TEXTURE_2D, texture.name);
glVertexPointer(3, GL_FLOAT, sizeof(struct vertexData), &verts[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertexData), &verts[0].s);
glDrawArrays(GL_TRIANGLES, 0, 6);

我不会介绍OpenGL的设置细节,我假设如果您能够阅读到这里,那么您已经完成了设置。
在使用OpenGL时需要考虑大量的性能和内存限制,但是我建议您现在不要过于担心它们。一旦您使其运行起来,请使用OpenGL工具来分析性能问题,然后解决它们。
苹果公司有一份非常好的最佳实践文档,而且Stack Overflow上也有一些有用的问题。我相信一旦您知道自己面临的问题(如果有的话),就能够找到它们。

1
这一切仅为了背景图像吗?..使用glDrawTexOES更方便设置背景图像。手写四边形用于背景图像有些过度设计。 - Alexander Smirnov
你有没有注意到我说这全部都包含在一个类中了?因为绘制背景图像只是绘制图像的特殊情况。我试着将其分解一下,而不是呈现整个类给提问者。 - Rob Jones
1
"你有没有错过我说这全部被封装在一个类里的部分?" 有包装是很好的,但用不必要的操作打扰OpenGL ES栈就不太好了。 - Alexander Smirnov
1
Alexander是正确的,最好的选择是glDrawTexOES。至于你的解决方案Rob,在这种情况下使用GL_TRIANGLES也不是最好的选择,而是应该选择GL_TRIANGLE_STRIP来减少缓冲区传输到GL硬件的大小。无论如何,这基本上都是吹毛求疵,因为我们只谈论一个单一的绘图而不是数以亿计的绘图。 - Till

1

谢谢。OES代表什么?它是针对iPhone上的OpenGLES还是OpenGL总体而言?有没有任何漂浮的示例代码? - acheo
请注意,“此扩展在OpenGL ES 2.0下不受支持”,因此您需要为iPhone 3GS寻找另一个解决方案。 - Alexander Smirnov
GL_OES_draw_texture可以避免传递三角形/四边形等需求。请查看http://www.khronos.org/registry/gles/extensions/OES/OES_draw_texture.txt。该扩展定义了一种从一个或多个纹理向屏幕的矩形区域写入像素矩形的机制。该功能对于快速渲染背景画、位图字体字形和游戏中的2D框架元素非常有用。该扩展主要用于OpenGL ES。 - Alexander Smirnov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接