`
lyunabc
  • 浏览: 530602 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

Android OpenGL ES 开发中的Buffer使用

 
阅读更多

在前面介绍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开发指南。

分享到:
评论

相关推荐

    android opengl学习文档

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

    Android OpenGL ES 3.0 VBO VAO应用

    Android OpenGL ES 3.0中Vertex Buffer Object(VBO)和Vertex Array Object(VAO)的应用。

    android opengl es 飘动的国旗

    3. 计算各定点坐标时是使用三维数组的形式生成的,较简单,但是OpenGL绘制的时候需要的是buffer形式的,生成buffer时需要的是一维数组,java中没有指针,所以需要自己写个方法把三维数组的内容转换到一维数组中,以...

    Pro OpenGL ES For Android

    In Pro OpenGL ES for Android, you'll find out how to harness the full power of OpenGL ES, and design your own 3D applications by building a fully-functional 3D solar system model using Open GL ES!...

    Pro OpenGL ES for Android

    In Pro OpenGL ES for Android, you'll find out how to harness the full power of OpenGL ES, and design your own 3D applications by building a fully-functional 3D solar system model using Open GL ES!...

    OpenGL ES 3.0 Programming Guide, 2nd Edition

    All code has been built and tested on iOS 7, Android 4.3, Windows (OpenGL ES 3.0 Emulation), and Ubuntu Linux, and the authors demonstrate how to build OpenGL ES code for each platform. Coverage ...

    glSatellite-Demo:技术演示的各个方面,包括将OpenGL ES与Android NDK一起使用,自定义消息队列,交互JNI和Java活动,使用NORAD数据库并解析其数据

    描述技术演示的各个方面,包括将OpenGL ES与Android NDK一起使用,自定义消息队列,交互JNI和Java活动,使用NORAD数据库并解析其数据。 特征: 带有clang编译器的C ++ 11 OpenGL ES 2 多点触控可缩放,旋转和移动...

    OpenGLES demo - 6. Cull Face

    个人博客中第6部分讲解的关于opengles 中的cull face的功能的源码

    glbuffer:Android 上的 OpenGL ES 缓冲区示例

    这是一个完整的示例,展示了如何在 Android 平台上使用 GLSurfaceView 和本机代码绘制 old-skool 像素缓冲区图形。 它与这篇关于 Android NDK 的有关。 编译代码: ./prepare-android-build.sh SDK [NDK]ant ...

    Android 4游戏编程入门经典

     11.3.4 opengl es中如何对光照过程进行运算:顶点法线  11.3.5 实践  11.3.6 关于opengl es中光照应用的一些建议  11.4 材质变换(mipmapping)  11.5 简单的照相机  11.5.1 第一人称照相机或欧拉照相机  ...

    android游戏编程入门

     11.3.4 OpenGL ES中如何对光照  过程进行运算:顶点  法线 442  11.3.5 实践 443  11.3.6 关于OpenGL ES中光照  应用的一些建议 456  11.4 材质变换(Mipmapping) 456  11.5 简单的照相机 460  11.5.1 第一...

    The Android graphics path in depth

    The Android graphics stack changed a lot in Jelly Bean as a result of project Butter • This presentation describes the current (JB) graphics stack from top to bottom ...• OpenGL ES and EGL

    GPU Instancer 0.9.0

    - OpenGL ES 3.1 (Android 8.0 Oreo or later) - Modern Consoles (PS4, Xbox One) To provide the fastest possible performance, GPU Instancer utilizes Indirect GPU Instancing using Unity's ...

Global site tag (gtag.js) - Google Analytics