glDrawElements 和glDrawArrays
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); } }
浙公网安备 33010602011771号