旧. -開発日記-

〜とあるプログラマーのつぶやきや開発メモなど〜

OpenGL ES 〜頂点バッファの生成〜

頂点バッファ生成のメモ書きです...。
OpenGLで三角形でも四角形でも、とにかく描画を行うには
頂点バッファと呼ばれる領域に格納してやる必要があります。

では例として、OpenGLでプリミティブを表示するのに
頂点の位置情報を浮動小数の1次元配列で表します。

例えば三角形の位置情報を指定する場合、

float[] vertexs = {
  0.0f, 1.0f, 0.0f, //頂点0 (左上)
  0.0f, 0.0f, 0.0f, //頂点1 (左下)
  1.0f, 1.0f, 0.0f, //頂点2 (右上)
};

このような形で頂点を指定してやります。
この情報をOpenGL ESへ転送するのに、Javaは火葬マシン上の変数を
ビッグエンディアンで格納されることが保証されているため
このままでは渡せません。

この問題を解決するためにこの配列をBufferに変換してやります。

float配列をFloatBufferに変換

上記のような頂点座標のfloat配列は以下の流れでFloatBuffer化されます。


[1] バッファのメモリ確保
[2] ネイティブのエンディアン指定
[3] ByteBuffer型のオブジェクトをFloatBufferに変換する
[4] [3]で変換されたFloatBufferに最初の頂点座標(float配列)をセットする


これをコードで書くと以下のようになります。

  ByteBuffer bb = ByteBuffer.allocateDirect(vertexs.length * 4);
  bb.order(ByteOrder.nativeOrder());
  FloatBuffer fb = bb.asFloatBuffer();
  fb.put(vertexs);
  fb.position(0);


簡単に解説すると、
ByteBufferクラスはバッファのメモリを格納するクラスで
allocateDirectで、メモリサイズを指定しています。

※vertexs.length * 4は「配列の要素数 * 4 (float = 4byte)」

次にネイティブのエンディアンを指定するために
ByteBufferオブジェクトのorderメソッドを使用します。
ByteOrder.nativeOrder()、このメソッドで
ネイティブのエンディアンを取得します。

ByteBuffer→FloatBufferの変換は、asFloatBuffer()で変換します。

最後、その変換されたオブジェクトでput()を呼びます。
fb.position(0)は、JavaのInputStreamやOutputStreamと同様、
書き込みが発生するたびに次書き込むための位置が1進んでしまうため、
それを戻す処理を行っています。

このようにして頂点バッファを生成してやります。
メモメモ完了。