glDrawArrays有3個參數
void glDrawArrays(
int mode,
int first,
int count
);
第一個就是繪圖的類型:
1.GL_TRIANGLES:每三個頂之間繪制三角形,之間不連接
2.GL_TRIANGLE_FAN:以V0V1V2,V0V2V3,V0V3V4,……的形式繪制三角形
3.GL_TRIANGLE_STRIP:順序在每三個頂點之間均繪制三角形。這個方法可以保證從相同的方向上所有三角形均被繪制。以V0V1V2,V1V2V3,V2V3V4……的形式繪制三角形
參數2:從數組緩存中的哪一位開始繪制,一般都定義為0
參數3:頂點的數量
第一個三角形是逆時針第二個是順時針,如果第二個是逆時針有時候可以畫出總之很容易出問題,同glDrawElements一樣。
glDrawElements 有四個參數,
void glDrawElements(
int mode,
int count,
int type,
java.nio.Buffer indices
);
第一個參數是點的類型,第二個參數是點的個數,第三個是第四個參數的類型,第四個參數是點的存儲繪制順序。
如正方形:0 3 ----------------> 存儲的點順序是0,1,2,3 而 繪圖的時候是每三個點就會繪制一個三角形,因此012 可以為三角形,1,2,3則與前面的三角形重復切不會覆蓋整個矩形,
1 2
因此就需要我們認為的設定繪圖點的順序,第四個參數的作用就是如此,我們把點的順序設置為0,1,3,2 這樣0,1,3和1,3,2 成2個三角形且剛好形成矩陣。
因此,
在利用glDrawElements時候只需記住所有定點,在第四個參數中來秒數所需面的頂點順序即可,且每取三個點繪圖一個三角形,下面的demo只記住了立方體的8個點,利用18個點的順序就可以繪圖成一個立方體,而不是4*6個點。
第一個三角形是逆時針第二個是順時針,依次循環否則不對應的就不會繪出。
package com.example.zp.myapplication;
import android.opengl.GLSurfaceView;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by lenovo on 2016/9/1.
*/
public class GLRender0 implements GLSurfaceView.Renderer
{
float rotateSpeed =5* (float) Math.PI/18;
float rotateTri = 0;
float one = 1f;
//正方形的4個頂點
private FloatBuffer quaterBuffer2 = BufferUtil.floatToBuffer(new float[]{
-one,-one,one,
one,-one,one,
one,one,one,
-one,one,one,
-one,-one,-one,
-one,one,-one,
one,one,-one,
one,-one,-one,
});
private FloatBuffer colorBuffer2 = BufferUtil.floatToBuffer(new float[]{
one,0,0,one,
0,one,0,one,
0,0,one,one,
});
ByteBuffer indices = ByteBuffer.wrap(new byte[]{
0,1,3,2,
5,6,4,7,
0,1,2,6,
1,7,4,0,
5,3
});
@Override
public void onDrawFrame(GL10 gl)
{
// 清除屏幕和深度緩存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 允許設置頂點
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//****************************繪制立方體***********************************//
// 重置當前的模型觀察矩陣
gl.glLoadIdentity();
//右移 1.5 單位,並移入屏幕 6.0
gl.glTranslatef(1.5f, 0.0f, -6.0f);
//旋轉矩陣
gl.glRotatef(rotateTri, 0.1f, 0.0f,0.0f);
//設置和繪制立方體
gl.glVertexPointer(3,GL10.GL_FLOAT,0,quaterBuffer2);
//單一着色
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 18, GL10.GL_UNSIGNED_BYTE, indices);
// gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glFinish();
// 關閉頂點設置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
rotateTri=rotateSpeed+rotateTri;
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
float ratio = (float) width / height;
//設置OpenGL場景的大小
gl.glViewport(0, 0, width, height);
//設置投影矩陣
gl.glMatrixMode(GL10.GL_PROJECTION);
//重置投影矩陣
gl.glLoadIdentity();
// 設置視口的大小
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
// 選擇模型觀察矩陣
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置模型觀察矩陣
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// 啟用陰影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 黑色背景
gl.glClearColor(0, 0, 0, 0);
// 設置深度緩存
gl.glClearDepthf(1.0f);
// 啟用深度測試
gl.glEnable(GL10.GL_DEPTH_TEST);
// 所作深度測試的類型
gl.glDepthFunc(GL10.GL_LEQUAL);
// 告訴系統對透視進行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
}
}