黑马程序员技术交流社区

标题: 关于openGl中IllegalArgumentException异常 [打印本页]

作者: 庭院深深深几许    时间: 2019-3-7 09:35
标题: 关于openGl中IllegalArgumentException异常
  一、Android4.0系统的下载与编译
  一、引入
  int one = 0x10000;
  // 三角形的3个顶点
  private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]
  &nbnbsp; { 0, one, 0, //上顶点
  -one, -one, 0, //左下顶点
  one, -one, 0, }); //右下顶点
  如果在Android1.5版本中使用上面数组形式表示顶点,不会出现任何问题,但在Android1.6版本以上运行就会出现java.lang.IllegalArgumentException: Must use a native order direct Buffer这个错误。出现这个错误是因为 OpenGL是一个非常底层的画图接口,它所使用的缓冲区存储结构是和java程序中不相同的。Java是大端字节序(BigEdian),而OpenGL所需要的数据是小端字节序(LittleEdian)。所以,我们需要 Java 的缓冲区转化为 OpenGL 可用的缓冲区
  二、大端排序和小端排序
  说到这里肯定会有人提出什么是大端排序和小端排序?下面来简单介绍一下:
  (1)大端排序(BigEdian):高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
  (2)小端排序(LittleEdian):低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
  举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:
  1)大端模式:
  低地址 -----------------> 高地址
  &nnbsp; 0x12 | 0x34 | 0x56 | 0x78
  2)小端模式:
  低地址 -----------------> 高地址
  0x78 | 0x56 | 0x34 | 0x12
  三、解决方案
  解决方法很简单,就是将Java的大端排序方式转换成openGL的小端排序即可,这里提供一个工具类BufferUtil来进行排序方式的转换,代码如下:
  import java.nio.ByteBuffer;
  import java.nio.ByteOrder;
  import java.nio.IntBuffer;
  public class BufferUtil {
  public static IntBuffer intBuffer;
  public static IntBuffer iBuffer(int[] a) {
  // 先初始化buffer,数组的长度*4,因为一个float占4个字节
  ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
  &nbnbsp; // 数组排列用nativeOrder
  mbb.order(ByteOrder.nativeOrder());
  intBuffer = mbb.asIntBuffer();
  intBuffer.put(a);
  intBuffer.position(0);
  return intBuffer;
  }
  }
  使用工具类:
  int one = 0x10000;
  // 三角形的3个顶点
  private IntBuffer triggerBuffer = BufferUtil.iBuffer((new int[]
  { 0, one, 0, // 上顶点
  -one, -one, 0, // 左下顶点
  one, -one, 0, })); // 右下顶点






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2