« prev next »
【Android】【Java】java.lang.IllegalArgumentException: Must use a native order direct Buffer~ と出た時は… 
2014/11/28 Fri [edit]
最近少しばかり Android での OpenGL の実験をしてるのだが、資料そのままでは上手くいかない箇所があった。調べてみたら、どうやら OpenGL が動作しているネイティブ領域でのバイトオーダーの整合性がとれてないらしい。そういうときの修正方法。
以下のような、FloatBuffer.wrap() で上手く行かない場合、
//頂点配列など
float[] vertex = new float[] { …(略)… };
FloatBuffer vertexBuffer = FloatBuffer.wrap(vertex);
↓のように修正すると上手くいく。
//頂点配列など
float[] vertex = new float[] { …(略)… };
//バイトバッファでネイティブオーダーに変換
ByteBuffer bytebuffer = ByteBuffer.allocateDirect(vertex.length * Float.SIZE / Byte.SIZE);
bytebuffer.order(ByteOrder.nativeOrder());
//FloatBuffer で使用する
FloatBuffer vertexBuffer = bytebuffer.asFloatBuffer();
vertexBuffer.put(vertex);
vertexBuffer.flip(); //vertexBuffer.position(0) でも良い
ネイティブでは CPU(機種) によって上手く行ったり、そうでなかったりするのかもね。
少なくとも私の環境では FloatBuffer も IntBuffer も .wrap() で書かれている部分はエラーが出ていた。修正方法はどこでも同じだったので、簡単なライブラリのようにしておけば、使いやすくていいね。
//ネイティブオーダーの FloatBuffer を作成する
public static final FloatBuffer toFloatBuffer(float[] arr) {
ByteBuffer bytebuffer = ByteBuffer.allocateDirect(arr.length * Float.SIZE / Byte.SIZE);
bytebuffer.order(ByteOrder.nativeOrder());
FloatBuffer buffer = bytebuffer.asFloatBuffer();
buffer.put(arr);
buffer.flip();
return buffer;
}
//ネイティブオーダーの IntBuffer を作成する
public static final IntBuffer toIntBuffer(int[] arr) {
ByteBuffer bytebuffer = ByteBuffer.allocateDirect(arr.length * Integer.SIZE / Byte.SIZE);
bytebuffer.order(ByteOrder.nativeOrder());
IntBuffer buffer = bytebuffer.asIntBuffer();
buffer.put(arr);
buffer.flip();
return buffer;
}
//メインでは以下のように使う
float[] vertex = new float[] { …(略)… };
FloatBuffer vertexBuffer = toFloatBuffer(vertex);
//int[] の場合
int[] vertex = new int[] { …(略)… };
IntBuffer vertexBuffer = toIntBuffer(vertex);
| h o m e |