OpenGL ES 2.0繪製方式

    今天咱們將在OpenGL路上前進一步,瞭解一下其繪製方式。OpenGL ES 2.0能繪製的基本圖元爲:點、線和三角形,固然在OpenGL中能支持更多的圖元,在此則再也不贅述。咱們將以繪製三角形的方式來詳細講解各類繪製方式。java

    首先來了解一下有哪些繪製方式?(姑且把它們放在一塊兒來講)git

    1.畫點:GL_POINTS。數組

    2.畫線:GL_LINES、GL_LINE_STRIP、GL_LINE_LOOP。.net

    3.畫三角形:GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN。code

    4.頂點法繪製:glDrawArrays。blog

    5.頂點索引法繪製:glDrawElements。索引

    下面咱們經過繪製正方形來說解圖元三角形的繪製方式以及頂點法和頂點索引法繪製圖形的方式。首先看一下三角形的三種繪製方式圖解:get

                                                                                 圖2.1源碼

    1.GL_TRIANGLES方式:這種方式從下面能夠很明顯的看出有不少重複的點,因此效率不是很高,可是現在的設備應該能承受的住。但其優勢十分明顯,就是一看明瞭,畫了多少個三角形。這種繪製方式容易理解。it

    首先定義頂點數組並賦值:

//正方形邊長
public static float STEP = 0.8f; 
//頂點數組
float[] mVertex1 = new float[]{//x,y,z
   -STEP,STEP,0,  //0
   -STEP,-STEP,0, //1
   STEP,-STEP,0,  //2
    
   -STEP,STEP,0, //3(0)
   STEP,-STEP,0, //4(2)
   STEP,STEP,0 //5(3)
};
//頂點數
mCount1 = mVertex1.length/3;
//頂點數組緩衝
mVertexBuffer1 = BufferUtils.getFloatBuffer(mVertex1.length*4);
mVertexBuffer1.put(mVertex1).position(0);

    而後使用頂點法來繪製圖形:

//使用頂點法繪製
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mCount1);

    定義頂點索引數組並賦值:OpenGL ES 2.0 只支持byte和short類型。索引其實就是按照必定方式給頂點編號,從0開始。

//頂點索引數組(通常頂點不少時候,用這種索引,方便,不會出錯。)
byte[] mIndex1 = new byte[mCount1];
for(int i=0;i<mCount1;i++){
  mIndex1[i] = (byte) i;
}
/**
  * FIXME:這種索引方式是錯誤的,具體緣由沒弄明白,但我猜想是
  * 上面給頂點數組賦的值形成的。如果定義正方形的四個頂點,再
  * 使用這種方式就是正確的,見第二種方式繪製。
  */
//  byte[] mIndex1 = new byte[]{
//    0,1,2,
//    0,2,3
//  };
//頂點索引緩衝
mIndexBuffer1 = BufferUtils.getByteBuffer(mIndex1.length);
mIndexBuffer1.put(mIndex1).position(0);

    使用頂點索引法來繪製圖形:

//使用頂點索引繪畫,第三個參數type必須爲GL_UNSIGNED_BYTE或者GL_UNSIGNED_SHORT。這也是上面定義索引類型的緣由。
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mCount1, GLES20.GL_UNSIGNED_BYTE, mIndexBuffer1);

2.GL_TRIANGLE_STRIP方式:三角帶方式,應該是效率最高的一種繪製方式,同一圖形它定義的頂點數據最少。但當頂點數一多,人工難以肯定頂點位置和順序。

    首先定義頂點數組並賦值:

/**
  * 若是當前頂點n是奇數:
  * 組成三角形的頂點排列順序:T = [n-1, n-2, n]
  * 若是當前頂點n是偶數:
  * 組成三角形的頂點排列順序:T = [n-2,n-1,n]
  * 繪畫順序爲:0,1,2,  2,1,3
  */
float[] mVertex2 = new float[]{//x,y,z
   -STEP,STEP,0, //0
   -STEP,-STEP,0, //1
   STEP,STEP,0, //2
   STEP,-STEP,0 //3
};
mCount2 = mVertex2.length/3;
mVertexBuffer2 = BufferUtils.getFloatBuffer(mVertex2.length*4);
mVertexBuffer2.put(mVertex2).position(0);

    下面定義頂點索引數組並賦值:

//頂點索引數組
byte[] mIndex2 = new byte[mCount2];
for(int i=0;i<mCount2;i++){
  mIndex2[i]=(byte)i;
}
//採用GL_TRIANGLES方式繪製,mCount2=6
//  byte[] mIndex2 = new byte[]{
//    0,1,2,
//    2,1,3
//  };
//頂點索引緩衝
mIndexBuffer2 = BufferUtils.getByteBuffer(mIndex2.length);
mIndexBuffer2.put(mIndex2).position(0);

     使用頂點法來繪製:

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, mCount2);

    使用頂點索引法來繪製:

GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, mCount2, GLES20.GL_UNSIGNED_BYTE,mIndexBuffer2);

3.GL_TRIANGLE_FAN方式:效率居中。

    首先定義頂點數組並賦值:

/**
  * 0,1,2,  0,2,3,  0,3,4,  0,4,5(1)  
  */
float[] mVertex3 = new float[]{//x,y,z
   0,0,0, //0
   -STEP,-STEP,0, //1
   STEP,-STEP,0, //2
   STEP,STEP,0, //3
   -STEP,STEP,0, //4
   -STEP,-STEP,0 //5(1)
}; 
mCount3 = mVertex3.length/3;
mVertexBuffer3 = BufferUtils.getFloatBuffer(mVertex3.length*4);
mVertexBuffer3.put(mVertex3).position(0);

 定義頂點索引數組並賦值:

//頂點索引數組,採用的是GL_TRIANGLE_FAN方式來繪製。
//  byte[] mIndex3 = new byte[mCount3];
//  for(int i=0;i<mCount3;i++){
//   mIndex3[i]=(byte)i;
//  }
//採用的是GL_TRIANGLE_FAN方式來繪製。[第五個點就是第一個點]
byte[] mIndex3 = new byte[]{
   0,1,2,3,4,1
};
//下面這種索引mCount = 12,採用的是GL_TRIANGLES方式繪製
//  byte[] mIndex3= new byte[]{
//    0,1,2,  0,2,3,  0,3,4,  0,4,1
//  };
//頂點索引緩衝
mIndexBuffer3 = BufferUtils.getByteBuffer(mIndex3.length);
mIndexBuffer3.put(mIndex3).position(0);

 使用頂點法來繪製:

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, mCount3);

    使用頂點索引法來繪製:

GLES20.glDrawElements(GLES20.GL_TRIANGLE_FAN, mCount3, GLES20.GL_UNSIGNED_BYTE, mIndexBuffer3);

    請小夥伴們仔細體悟頂點數組裏面所取頂點順序,還要注意一點:使用同一的繪畫順序的,逆時針或者順時針。

    本節到此結束。

    源碼:http://git.oschina.net/zzero.pj/SGLAndroid01

    下圖爲GL_TRIANGLES效果圖:

參考資料:

  1. 講解GL_TRIANGLE_STRIP:http://blog.csdn.net/xiajun07061225/article/details/7455283

相關文章
相關標籤/搜索