Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用数组而不是缓冲区加载Android OpenGL ES 2.0纹理_Java_Android_Performance_Opengl Es_Opengl Es 2.0 - Fatal编程技术网

Java 使用数组而不是缓冲区加载Android OpenGL ES 2.0纹理

Java 使用数组而不是缓冲区加载Android OpenGL ES 2.0纹理,java,android,performance,opengl-es,opengl-es-2.0,Java,Android,Performance,Opengl Es,Opengl Es 2.0,这个问题类似于,但我问这个问题是因为: 这有点不同-我的问题是纹理,而不是顶点缓冲区 虽然问题很清楚,但似乎大多数答案都没有抓住重点 这个问题已经三年了,也许有什么新的东西可以解决我的问题 这真让我惊讶,这是一个问题…我觉得我一定是误解了什么 无论如何,我在Android上使用OpenGLES2.0。我有一个大的纹理(比如1024x1024),它必须随着每一帧更新。没有办法解决这个问题-纹理的内容本质上是一个视频 问题是Android Java与OpenGL的接口使用Java.nio.Buf

这个问题类似于,但我问这个问题是因为:

  • 这有点不同-我的问题是纹理,而不是顶点缓冲区
  • 虽然问题很清楚,但似乎大多数答案都没有抓住重点
  • 这个问题已经三年了,也许有什么新的东西可以解决我的问题
  • 这真让我惊讶,这是一个问题…我觉得我一定是误解了什么
无论如何,我在Android上使用OpenGLES2.0。我有一个大的纹理(比如1024x1024),它必须随着每一帧更新。没有办法解决这个问题-纹理的内容本质上是一个视频

问题是Android Java与OpenGL的接口使用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) 
是缓冲区,而不是
字节[]
int[]

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

如何解决这个问题?我试图使用IntBuffer.array()以数组的形式访问内容,但是

  • 对于使用
    IntBuffer.allocateDirect()分配的缓冲区,
    array()
    调用未成功
  • glTexImage2D()
    调用对于使用
    IntBuffer.allocate()
我能想到的其他事情:

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

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

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

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


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


另外,请看TextureView类。

我根据您提供的链接将其标记为答案(谢谢!)您提到的Buffer.array()方法的问题是glTexImage2D()不喜欢使用allocate()创建的ByteBuffers-only allocateDirect()。和ByteBuffer.array()不适用于使用allocate()创建的缓冲区。但是,从您提供的链接中,我发现首先创建一个数组,然后使用ByteBuffer.wrap()创建ByteBuffer似乎是可行的。这是令人惊讶的,因为从wrap()返回的ByteBuffer不是一个“直接”缓冲区……所以我担心以后事情会爆发。