使用 OpenGL ES 2.0 传输纹理的最快方法是啥?
Posted
技术标签:
【中文标题】使用 OpenGL ES 2.0 传输纹理的最快方法是啥?【英文标题】:What is the fastest way to transfer textures using OpenGL ES 2.0?使用 OpenGL ES 2.0 传输纹理的最快方法是什么? 【发布时间】:2013-06-27 09:38:14 【问题描述】:由于像素缓冲区对象在 OpenGL ES 2.0 中不可用,将纹理传输到 GPU(然后再返回)的最快方法是什么?是否有任何可用于 iPad 2 或更高版本的扩展程序可供我们使用?
很遗憾,我不能使用压缩纹理,因为纹理 (RGBA8) 是在应用程序的另一部分动态生成的。
【问题讨论】:
【参考方案1】:对于 ios(鉴于此处提到的 iPad,我假设是您的平台),往返未压缩纹理的最快方法是通过纹理缓存。这些是在 iOS 5.0 中引入的,基本上是在纹理的支持字节和本地内存字节缓冲区之间进行直接内存映射。
对于使用 CVOpenGLESTextureCacheRef 的上传,我在this answer 中描述了该过程。不过,摄像机有点特殊,因为它提供像素缓冲区供您使用。对于其他用途,您将自己创建像素缓冲区并将内存关联到本地字节缓冲区以上传到纹理中。在我的基准测试中,初始上传并不比glTexImage2D()
快,但我相信这些字节的后续修改更快。
我在this answer 中谈到了使用纹理缓存从 FBO 纹理目标中捕获的过程。该答案还针对特定用例,即视频编码,但可以将相同的基本原理与您自己的自定义像素缓冲区一起使用来提取原始字节。在我进行基准测试的几乎所有情况下,这都比 glReadPixels()
快。
当然,最快的方法是不必在 CPU 和 GPU 之间来回切换。如果可以,请利用 FBO 纹理目标和共享组,将所有渲染都保留在 GPU 上。
【讨论】:
我用 Brad 的例子从纹理缓存中获取了一个 GL 纹理,有效地消除了传输时间。【参考方案2】:EGL 图像扩展可用于分配带有指针的纹理,这些指针可用于直接访问纹理图像数据。通常,这比使用 glTexImage2D() 快得多。我没有适用于 iOS 的示例代码,但本文中有适用于 Linux 和 android 的示例代码:
http://software.intel.com/en-us/articles/using-opengl-es-to-accelerate-apps-with-legacy-2d-guis
【讨论】:
看起来很有趣,但EGL/eglext.h
似乎不存在于 iOS 上。我在其他地方也看到了证据(例如developer.apple.com/library/ios/documentation/DeviceInformation/…) iOS 不支持 EGL 扩展。
没错。 iOS 使用 Apple EAGL 而不是 Khronos EGL。以上是关于使用 OpenGL ES 2.0 传输纹理的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
OPENGL ES 2.0 知识串讲 (10) ——OPENGL ES 详解IV(纹理优化)
OPENGL ES 2.0 知识串讲 (10) ——OPENGL ES 详解IV(纹理优化)
绘制到纹理后的Opengl ES 2.0 glDeleteFramebuffers