首次使用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 * );
// 數組排列用nativeOrder
mbb.order(ByteOrder.nativeOrder());
intBuffer = mbb.asIntBuffer();
intBuffer.put(a);
intBuffer.position();
return intBuffer;
}
}
實際使用時,采用如下方式
private int one = ;
private IntBuffer triggerBuffer = BufferUtil.iBuffer(new int[]{
, one, , //上
-one, -one, ,//左
one, -one, });//右