Android OpenGLES Must use a native order direct Buffer

OpenGL所使用的缓冲区存储结构是和我们的java 程序中不相同的。

Java 是大端字节序(BigEdian),而 OpenGL 所需要的数据是小端字节序(LittleEdian)。所以,我们在将 Java 的缓冲区转化为 OpenGL 可用的缓冲区时需要作一些工作。

在调试Android OpenGL ES时候,会报Must use a native order direct Buffer错误。如下:

28427-28453/com.denny.sample4_1 E/AndroidRuntime: FATAL EXCEPTION: GLThread 165
Process: com.denny.sample4_1, PID: 28427
java.lang.IllegalArgumentException: Must use a native order direct Buffer
at android.opengl.GLES20.glVertexAttribPointerBounds(Native Method)
at android.opengl.GLES20.glVertexAttribPointer(GLES20.java:1906)
at com.denny.sample4_1.Triangle.draw(Triangle.java:64)
at com.denny.sample4_1.MyGLRender.onDrawFrame(MyGLRender.java:27)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1553)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1253)

但是在Buffer Util中已经设置了使用nativeOrder。

package com.denny.sample4_1;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

public class BufferUtil
{
    private static ByteBuffer GetBuffer(int len,int bytes)
    {
        ByteBuffer bb=ByteBuffer.allocate(len*bytes);
        // use the device hardware's native byte order
        bb.order(ByteOrder.nativeOrder());
        return bb;
    }

    public static FloatBuffer Create(float[] arr)
    {
        FloatBuffer buffer=GetBuffer(arr.length,4).asFloatBuffer();
        // add the coordinates to the FloatBuffer
        buffer.put(arr);
        // set the buffer to read the first coordinate
        buffer.position(0);
        return buffer;
    }

    public static ShortBuffer Create(short[] arr)
    {
        ShortBuffer buffer=GetBuffer(arr.length,2).asShortBuffer();
        // add the coordinates to the FloatBuffer
        buffer.put(arr);
        // set the buffer to read the first coordinate
        buffer.position(0);
        return buffer;
    }
}

  

解决方案:

1.ByteBuffer bb=ByteBuffer.allocate(len*bytes); 需要使用allocateDirect,而不是allocate。

2.创建ByteBuffer之后,需要调用 .order(ByteOrder.nativeOrder());使用硬件的原生的byte order。

 

posted @ 2020-04-05 15:05  David Dong  阅读(462)  评论(0编辑  收藏  举报