OpenGL ES :java.lang.IllegalArgumentException: Must use a native order direct Buffer

首次使用OpenGL ES开发时,经常会出现以下问题:

 java.lang.IllegalArgumentException: Must use a native order direct Buffer
 at com.google.android.gles_jni.GLImpl.glVertexPointerBounds(Native Method

原因:
在Android1.6版本以上运行就会出现,是因为 OpenGL是一个非常底层的画图接口,它所使用的缓冲区存储结构是和java程序中不相同的。Java是大端字节序(BigEdian),而OpenGL所需要的数据是小端字节序(LittleEdian)。所以,我们需要 Java 的缓冲区转化为 OpenGL 可用的缓冲区。
补充说明:
(1)大端排序(BigEdian):高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

(2)小端排序(LittleEdian):低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:
1)大端模式:
低地址 —————–> 高地址
0x12 | 0x34 | 0x56 | 0x78
2)小端模式:
低地址 —————–> 高地址
0x78 | 0x56 | 0x34 | 0x12
解决方案:
我们知道是因为采用大小端模式不同,导致出现该问题的,那么我可以对缓存区数据,人为更改数据高低端地址的存储,将Java的大端模式更改为适用OpenGL的小端模式。

public class BufferUtil {
    public static IntBuffer intBuffer;
    public static IntBuffer iBuffer(int[] a) {
        // 先初始化buffer,数组的长度*4,因为一个int占4个字节
        ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
        // 数组排列用nativeOrder
        mbb.order(ByteOrder.nativeOrder());
        intBuffer = mbb.asIntBuffer();
        intBuffer.put(a);
        intBuffer.position(0);
        return intBuffer;
    }
}

实际使用时,采用如下方式

 private int one = 0x100000;
 private IntBuffer triggerBuffer = BufferUtil.iBuffer(new int[]{
            0, one, 0, //上
            -one, -one, 0,//左
            one, -one, 0});//右

猜你喜欢

转载自blog.csdn.net/xk7298/article/details/79849147