分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
前一篇里使用了glDrawArrays,这次要绘制3D的图形,需要用到glDrawElements,比较一下两者的使用
glDrawArrays(mode, first, count)
这是在OpenGL下绘制一个三角形的方法, 第一个模式如GL10.GL_FLOAT等, 第二个是当前三角形点的索引(标号),第三个参数是点数目, , 该函数会从数组中找到第first个点, 向后找到count个, 用这些点来点点依次相连绘制成一个个三角形。在opengl es中是不支持直接绘制除三角形外的多边形的。
glDrawElements(mode, count, type, indices)
第一个参数是类型(如GL_TRIANGLES),第二个点数目,第三个指的是第四个参数的类型,第四个参数是三角形的索引数据。
第一个参数好理解;第二个参数就是你用glTexCoordPointer传入点的个数;第三个参数是只最后一个参数的类型,要注意,opengl es是不支持GL_UNSIGNED_INT的,现在只支持GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT这两个参数。第四个参数要注意,稍有不慎就会把图片贴得缺胳膊少腿的。下面举个例子:
glDrawArrays(mode, first, count)
这是在OpenGL下绘制一个三角形的方法, 第一个模式如GL10.GL_FLOAT等, 第二个是当前三角形点的索引(标号),第三个参数是点数目, , 该函数会从数组中找到第first个点, 向后找到count个, 用这些点来点点依次相连绘制成一个个三角形。在opengl es中是不支持直接绘制除三角形外的多边形的。
glDrawElements(mode, count, type, indices)
第一个参数是类型(如GL_TRIANGLES),第二个点数目,第三个指的是第四个参数的类型,第四个参数是三角形的索引数据。
第一个参数好理解;第二个参数就是你用glTexCoordPointer传入点的个数;第三个参数是只最后一个参数的类型,要注意,opengl es是不支持GL_UNSIGNED_INT的,现在只支持GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT这两个参数。第四个参数要注意,稍有不慎就会把图片贴得缺胳膊少腿的。下面举个例子:
我们用基本的四变形来举例子,我们有个四边形(v1,v2,v3,v4),那我们怎么去把这个四边形分割为2个三角形呢,就是根据这个索引。如(0,1,2,3)就告诉系统,前3个组成一个三角形,后3个点组成三角形, 0123代表着对应坐标数组的下标。如果说这个索引有问题的话,有可能导致2个三角形不能组成一个四边形,这样纹理贴图就会缺少一块。
下面绘制一个旋转的三角锥和一个正方体
重点是renderer类,Activity部分和上一篇一样
public class MyRenderer implements Renderer{ // 定义三棱椎的4个顶点 float[] taperVertices = new float[] { 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, -0.2f, 0.5f, -0.5f, -0.2f, 0.0f, -0.2f, 0.2f }; // 定义三棱椎的4个顶点的颜色 int[] taperColors = new int[]{ 65535, 0, 0, 0, // 红色 0, 65535, 0, 0, // 绿色 0, 0, 65535, 0, // 蓝色 65535, 65535, 0, 0 //黄色 }; // 定义三棱椎的4个三角面 private byte[] taperFacets = new byte[]{ 0, 1, 2, //0、1、2三个顶点组成一个面 0, 1, 3, //0、1、3三个顶点组成一个面 1, 2, 3, //1、2、3三个顶点组成一个面 0, 2, 3 //0、2、3三个顶点组成一个面 }; // 定义立方体的8个顶点 float[] cubeVertices = new float[] { // 上顶面正方形的四个顶点 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, // 下底面正方形的四个顶点 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f }; // 定义立方体所需要的6个面(一共是12个三角形所需的顶点) private byte[] cubeFacets = new byte[]{ 0, 1, 2, 0, 2, 3, 2, 3, 7, 2, 6, 7, 0, 3, 7, 0, 4, 7, 4, 5, 6, 4, 6, 7, 0, 1, 4, 1, 4, 5, 1, 2, 6, 1, 5, 6 }; FloatBuffer taperVerticesBuffer; IntBuffer taperColorsBuffer; ByteBuffer taperFacetsBuffer; FloatBuffer cubeVerticesBuffer; ByteBuffer cubeFacetsBuffer; // 控制旋转的角度 private float rotate; public MyRenderer() { // 将三棱椎的顶点位置数据数组包装成FloatBuffer; taperVerticesBuffer = FloatBuffer.wrap(taperVertices); // 将三棱椎的四个面的数组包装成ByteBuffer taperFacetsBuffer = ByteBuffer.wrap(taperFacets); // 将三棱椎的四个定点的颜色数组包装成IntBuffer taperColorsBuffer = IntBuffer.wrap(taperColors); // 将立方体的顶点位置数据数组包装成FloatBuffer; cubeVerticesBuffer = FloatBuffer.wrap(cubeVertices); // 将立方体的6个面(12个三角形)的数组包装成ByteBuffer cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 关闭抗抖动 gl.glDisable(GL10.GL_DITHER); // 设置系统对透视进行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); gl.glClearColor(0, 0, 0, 0); // 设置阴影平滑模式 gl.glShadeModel(GL10.GL_SMOOTH); // 启用深度测试 gl.glEnable(GL10.GL_DEPTH_TEST); // 设置深度测试的类型 gl.glDepthFunc(GL10.GL_LEQUAL); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // 设置3D视窗的大小及位置 gl.glViewport(0, 0, width, height); // 将当前矩阵模式设为投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); // 初始化单位矩阵 gl.glLoadIdentity(); // 计算透视视窗的宽度、高度比 float ratio = (float) width / height; // 调用此方法设置透视视窗的空间大小。 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); } // 绘制图形的方法 @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.glEnableClientState(GL10.GL_COLOR_ARRAY); // 设置当前矩阵模式为模型视图。 gl.glMatrixMode(GL10.GL_MODELVIEW); // --------------------绘制第一个图形--------------------- // 重置当前的模型视图矩阵 gl.glLoadIdentity(); gl.glTranslatef(-0.6f, 0.0f, -1.5f); // 沿着Y轴旋转 gl.glRotatef(rotate, 0f, 0.2f, 0f); // 设置顶点的位置数据 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, taperVerticesBuffer); // 设置顶点的颜色数据 gl.glColorPointer(4, GL10.GL_FIXED, 0, taperColorsBuffer); // 按taperFacetsBuffer指定的面绘制三角形 gl.glDrawElements(GL10.GL_TRIANGLE_STRIP , taperFacetsBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, taperFacetsBuffer); // --------------------绘制第二个图形--------------------- // 重置当前的模型视图矩阵 gl.glLoadIdentity(); gl.glTranslatef(0.7f, 0.0f, -2.2f); // 沿着Y轴旋转 gl.glRotatef(rotate, 0f, 0.2f, 0f); // 沿着X轴旋转 gl.glRotatef(rotate, 1f, 0f, 0f); // 设置顶点的位置数据 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer); // 不设置顶点的颜色数据,还用以前的颜色数据 // 按cubeFacetsBuffer指定的面绘制三角形 gl.glDrawElements(GL10.GL_TRIANGLE_STRIP , cubeFacetsBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer); // 绘制结束 gl.glFinish(); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // 旋转角度增加1 rotate+=1; }}