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);
}
 
}
 
posted @ 2016-10-16 20:28  Lammy  阅读(12481)  评论(0编辑  收藏  举报