OpenGLを使って描画する。
三角形を例にします。
流れとしては頂点を設定して、描画って感じです。
頂点の設定
以下の手順で頂点を設定します。
Step1. 頂点の座標(X,Y,Z)を配列で定義する。
float[] vertices = {
0.0f, 1.0f, 0.0f, //頂点0 (上)
0.0f, 0.0f, 0.0f, //頂点1 (左下)
1.0f, 1.0f, 0.0f, //頂点2 (右上)
};
Step2. バッファのメモリ確保
座標データ数x4倍のメモリを確保します。
※4倍しているのはfloatが4byte扱いの為。
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
Step3. ネイティブのエンディアン指定
nativeのエンディアンを取得し、設定します。
vbb.order(ByteOrder.nativeOrder());
Step4. ByteBuffer型のオブジェクトをFloatBufferに変換
FloatBuffer mVertexBuffer = vbb.asFloatBuffer();
Step5. Step4で変換されたFloatBufferに最初の頂点座標(float配列)をセット
mVertexBuffer.put(vertices);
Step6. 書き込み位置の調整
書き込みが発生するたびに次書き込むための位置が1進んでしまうため、それを戻す処理を行っています。
mVertexBuffer.position(0);
[参考]
http://librastudio.hatenablog.com/entry/2013/08/19/010615
描画の設定
Step1. 頂点配列を有効にする。
glEnableClientState(int array)を使って、どの配列を使って、描画するかを指定します。
今回の場合は、頂点を設定しているので引数は、GL_VERTEX_ARRAYとする。
変数 | 意味 | 参照 |
---|---|---|
GL_COLOR_ARRAY | カラー配列 | glColorPointer() |
GL_EDGE_FLAG_ARRAY | エッジフラグ配列 | glEdgeFlagPointer() |
GL_INDEX_ARRAY | 指標配列 | glIndexPointer() |
GL_NORMAL_ARRAY | 法線配列 | glNormalPointer() |
GL_TEXTURE_COORD_ARRAY | テクスチャ座標配列 | glTexCoordPointer() |
GL_VERTEX_ARRAY | 頂点配列 | glVertexPointer() |
glEnableClientState(GL10.GL_VERTEX_ARRAY);
Step2. 頂点配列を定義する。
glVertexPointer((int size, int type, int stride,java.nio.Buffer pointer)
変数 | 意味 | 備考 |
---|---|---|
size | 頂点データのサイズ | 2次元なら2,3次元なら3,Wを含めるなら4 |
type | GL_SHORT、GL_INT、GL_FLOAT、GL_DOUBLE | |
stride | 連続する頂点間でのバイト・オフセット | 0 を指定すれば、頂点の情報が配列ないに隙間なく入っている |
pointer | 座標情報を含む配列へのポインタ |
X,Y,Z座標を指定しているのでsizeは3。
glVertexPointer(3,GL10.GL_FLOAT,0,mVertexBuffer);
Step3. 法線ベクトルの追加
ここでいう法線ベクトルとは・・・ 面に垂直な長さが1のベクトル。
1)p0→p1という向きのベクトルv1(= p1 - p0)の算出
2)同様に、p0→p2という向きのベクトルv2(= p2 - p0)の算出。
3)v2からv1への外積v2×v1の算出
4)外積の長さの算出
5)外積をその長さで割り、正規化する。
※glEnable(GL_NORMALIZE)とすれば法線ベクトルを単位ベクトルにする必要はないようです。
今回の場合は、以下なので
0.0f, 1.0f, 0.0f, //頂点0 (上)
0.0f, 0.0f, 0.0f, //頂点1 (左下)
1.0f, 1.0f, 0.0f, //頂点2 (右上)
1) p1-p0 = 0.0f, -1.0f, 0.0f
2) p2-p0 = 1.0f, 0.0f, 0.0f
3)外積は以下で求めると、
-1*0-0*0,0*1-0*0,0*0-(-1*1)=0.0f, 0.0f,1.0f
となる。
なので、
4) 外積の長さは以下のようにすでに1なので、単位ベクトルになっている。
ので、
glNormal3f(0.0f, 0.0f, 1.0f)
※四角形の場合は三角形2つに分割して、その三角形2つの面法線ベクトルを平均化するらしい
※三角形の場合はなくても描画できました。
Step4. 描画
glDrawArrays(int mode,int first,int count)を使って描画します。
描画する面に対してglNormal, glDrawArraysをペアで設定する必要があります。
三角形の場合は1つでよいが立方体の場合は6面あるので、6ペア必要です。
変数 | 意味 |
---|---|
mode | 描画方法 |
first | はじめに描画する頂点番号 |
count | 描画する頂点数 |
今回の場合は三角形を塗りつぶしたいので、以下でいいようです。
glDrawArrays(GL10.GL_GL_TRIANGLES, 0, 3);
参考
http://sky.geocities.jp/freakish_osprey/opengl/opengl_normalvecotr.htm
http://opengl.softwarecarpenter.biz/?eid=1075451
http://atelier-yoka.com/dev_android/p_main.php?file=apigl10gldrawarrays
0 件のコメント :
コメントを投稿