在前面介绍Android OpenGL ES简明开发教程 说过为了提高性能,通常将顶点,颜色等值存放在java.nio 包中定义的Buffer类中。

ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);vbb.order(ByteOrder.nativeOrder());vertexBuffer = vbb.asFloatBuffer();vertexBuffer.put(vertices);vertexBuffer.position(0);


本篇简要介绍一下java.nio 包中各种Buffer的定义和用法,也为后面详细介绍Android OpenGL ES开发做点知识上的准备。

使用Java开发文件读取时经常用到的一个包是java.io ,包内定义了各种流Stream 类,将文件或是Stream看作一个byte数组,这种方法一般无法指定字节顺序(不同的计算机系统Byte order 可能不同),操作如“在文件偏移10个字节出读取一个四字节Little-endian整数“在使用Stream方式读取文件时就不十分方便。此外,Stream 方法是按一个字节一个字节方式处理的,读写性能上不是很好。

java.nio (这里的N代表New 新的IO包) 解决了上述java.io 包的这些局限,java.io 包包含了Buffer,Channel, charset 等,但OpenGL ES 只用到Buffer,Buffer具有以下特点:

  • 允许以内存缓冲区(buffer)的方式来管理一个Buffer 数组,可以整块整块的读写内存区域,并可以指定Byte order.(大头或是小头)。
  • 提供了在指定位置读写各种基本数据类型的简便方法如 putInt ,putLong等。
  • 可以充分利用JVM提供的各种优化方法以达到和使用Native Code类型的读写性能。
  • 可以直接从OS的内存分配空间,这部分空间可以不受Java 的Garbage collector控制。称为Direct buffer.

简单的说使用java.nio 中的Buffer类提供了更高的访问性能,这也是为什么OpenGL ES使用Buffer类的主要原因。

Buffer定义了三个状态变量:position, limit, capacity

  • Capacity: Buffer的容量,表示可以存放的最大字节数,内存分配之后其值保持不变。
  • Position: 类似于文件指针,表示下一个可以读写的字节的缺省位置,可以使用函数来重新设置当前的Position.
  • Limit: 可以控制当前可以读写的区域,你只可以读写从[0,limit-1]范围内的数组空间,读写超过这个范围将导致抛出异常。

通常情况下这些状态变量有buffer自动管理,但也可以使用方法来重新设置这些变量。

比如: public final Bufferlimit(int newLimit) 重新设置limit

public final Bufferposition(int newPosition) 重新设置position

此外reset ,rewind mark ,clear 等在清空Buffer或是恢复Mark位置时也可修改limit ,position 的值。

get()方法

在ByteBuffer类中提供了四种get()方法用于读取:

1. byte get();
2. ByteBuffer get( byte dst[] );
3. ByteBuffer get( byte dst[], int offset, int length );
4. byte get( int index );

put() 方法

在ByteBuffer中定义了五种put()方法用于写入:

1. ByteBuffer put( byte b );
2. ByteBuffer put( byte src[] );
3. ByteBuffer put( byte src[], int offset, int length );
4. ByteBuffer put( ByteBuffer src );
5. ByteBuffer put( int index, byte b );

此外还定义了多种基本数据类型的读取写入方法:

· getByte()
· getChar()
· getShort()
· getInt()
· getLong()
· getFloat()
· getDouble()
· putByte()
· putChar()
· putShort()
· putInt()
· putLong()
· putFloat()
· putDouble()

java.nio 包中定义了基类Buffer ,还定义了和各种基本数据类型特定的Buffer类型ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer和ShortBuffer.其中ByteBuffer是其它类型的基础,因为分配内存是通过ByteBuffer的allocate来进行的,然后通过 ByteBuffer 的asXXXBuffer()转为其它类型:

可以使用下面三个方法来创建一个新的ByteBuffer:

public static ByteBuffer allocate(int capacity)
public static ByteBuffer allocateDirect(int capacity)
public static ByteBuffer wrap(byte[] array)

其中ByteBufferallocateDirect直接从OS分配内存,不受GC的限制,wrap使用已分配的数组作为buffer管理。

然后通过asXXXBuffer 转为其它类型的Buffer:

public abstract CharBuffer asCharBuffer()
public abstract DoubleBuffer asDoubleBuffer()
public abstract FloatBuffer asFloatBuffer()
public abstract IntBuffer asIntBuffer()
public abstract LongBuffer asLongBuffer()
public abstract ShortBuffer asShortBuffer()

以上介绍了Android OpenGL ES相关的Buffer的使用方法,将在不久的将来详细介绍OpenGL ES开发指南。

更多相关文章

  1. qq聊天界面七:表情的发送接收(用富文本现实)
  2. Android(安卓)自定义注解
  3. 源码分析--xutil3 网络源码分析
  4. Android:消息机制
  5. 对hint 设置大小及颜色,可用此方法对字符串设置不同颜色或大小
  6. 【Android】用retrofit使用单独的URL和处理form-data格式的POST
  7. Fragment开发实例
  8. Android(安卓)-- Options Menu,Context Menu,Popup Menu
  9. 关于开机启动activity或者services

随机推荐

  1. Android BaseExpandableListAdapter 教程
  2. Android - View的绘制流程一(measure)
  3. android assert 自定义格式被压缩
  4. eclipse中跳转查看android类的源码
  5. Android ApiDemo下载
  6. Android proguard(混淆)模板
  7. Android adb截屏命令
  8. Android快速开发之封装标题栏
  9. Android 中设计模式 ----原型模式
  10. android - 常用知识点以及代码片段(不断更