1

这个问题类似于How to get around the performance issues with Buffer.put() and Android OpenGL但我问它是因为:

  • 略有不同 - 我的问题是纹理,而不是顶点缓冲区
  • 虽然问题很清楚,但似乎大多数答案都没有抓住重点
  • 这个问题已经 3 岁了,也许有一些新的东西可以解决我的问题
  • 这是一个问题真的让我感到惊讶......我觉得我一定是误解了一些东西。

无论如何,我在 Android 上使用 OpenGL ES 2.0。我有一个大纹理(比如 1024x1024),必须随每一帧更新。没有办法绕过这个 AFAIK - 纹理的内容本质上是一个视频。

问题是 OpenGL 的 Android Java 接口使用 java.nio.Buffer 对象,而不是数组。特别是最后一个参数

public static void GLES20.glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, Buffer pixels) 

是一个缓冲区,而不是一个byte[]int[]

glTexImage2D因此,我必须将内容生成到 int[] 中,然后为整个巨大的数组调用 IntBuffer.put() ,而不是将纹理的内容(对于每一帧)直接生成到可以传递给的 int[] 中. Traceview 和调用周围的 System.nanoTime() 表明这是一个占用大量 CPU,不足为奇。

如何解决这个问题?我尝试使用 IntBuffer.array() 将内容作为数组获取,但是

  • 对于array()分配的缓冲区,调用不成功IntBuffer.allocateDirect()
  • glTexImage2D()调用不适用于分配的缓冲区IntBuffer.allocate()

其他我能想到的:

  • 从本机代码调用glTexImage2D,我认为这不是 Android GL 本机代码接口的问题
  • 在另一个线程上完成工作。但我不知道这是否会导致产生纹理内容的线程和调用 glTexImage2D 的 GL 线程之间出现争用问题。无论如何,当逻辑上没有必要时,复制内存仍然需要额外的 CPU 周期。

如果只有一个 GLES20.glTexImage2D 版本采用 int[] 或其他数组类型而不是缓冲区,我似乎不会成为问题。

4

2 回答 2

1

你会发现 glTexImage2D() 太慢了,无法从实时视频中加载帧。为此,您应该使用本文所述的 EGL 图像扩展和 EGL_NATIVE_BUFFER_ANDROID:

http://software.intel.com/en-us/articles/using-opengl-es-to-accelerate-apps-with-legacy-2d-guis

另外,查看 TextureView 类。

于 2013-08-02T17:30:38.027 回答
1

Android 中的 ABuffer可以由数组支持。这意味着缓冲区实际上只是包装了数组,对数组的修改会反映在缓冲区中。

http://developer.android.com/reference/java/nio/Buffer.html#array()

您可以按照本网站上的代码创建一个ByteBuffer围绕字节数组的代码:

http://examples.javacodegeeks.com/core-java/nio/bytebuffer/convert-between-bytebuffer-and-byte-array/

于 2013-07-31T19:57:50.133 回答