Android(安卓)OpenGL ES 绘图 -- 基础元素
本文章为使用OpengGL绘制-点、线、面
点
准备工作在之前文章中已经介绍,本文直接绘图
在 Android 系统中可以使用一个浮点数数组来定义一个顶点,浮点数数组通常放在一个 Buffer(java.nio)中来提高性能。
比如:下图中定义了四个顶点和对应的 Android 顶点定义:
默认情况下,可视区域的四个顶点分别为v0(-1,1,0);v1(-1,-1,0)v2(1,-1,0);v3(1,1,0)(注:此坐标有可能不为正方形)
// 清除屏幕和深度缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); //创建点坐标(x,y,z),每三个数为一组 float vertices[] = { -0.5f, 0.5f, 0.0f, // 0, Top Left -0.5f, -0.5f, 0.0f, // 1, Bottom Left 0.5f, -0.5f, 0.0f, // 2, Bottom Right 0.5f, 0.5f, 0.0f, // 3, Top Right };
为了提高性能,通常将这些数组存放到 java.io 中定义的 Buffer 类中:
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); FloatBuffer vertexBuffer = vbb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0);
有了顶点的定义,下面一步就是如何将它们传给 OpenGL ES 库,OpenGL ES 提供一个成为”管道 Pipeline ”的机制,这个管道定义了一些“开关”来控制 OpenGL ES 支持的某些功能,缺省情况这些功能是关闭的,如果需要使用 OpenGL ES 的这些功能,需要明确告知 OpenGL “管道”打开所需功能。因此对于我们的这个示例,需要告诉 OpenGL 库打开 Vertex buffer 以便传入顶点坐标 Buffer。要注意的使用完某个功能之后,要关闭这个功能以免影响后续操作:
//设置点的大小 gl.glPointSize(5f); //开启点坐标管道 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //传入点坐标 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); //根据点坐标绘点 gl.glDrawArrays(GL10.GL_POINTS, 0, vertices.length/3); //关闭点坐标 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); }
线
OpenGL绘线,需根据点来绘制,以下示例中的点数据为上绘点的坐标
添加绘线顺序数组
short[] indices = { 0, 1, 2, 0, 2, 3 };
为了提高性能,通常将这些数组存放到 java.io 中定义的 Buffer 类中:
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); ibb.order(ByteOrder.nativeOrder()); ShortBuffer indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indices); indexBuffer.position(0);
开始绘制
//开启点坐标管道 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //传入点坐标 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); //根据点与绘线顺序绘线 gl.glDrawElements(GL10.GL_LINES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); //关闭点坐标 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
其中GL10.GL_LINES:
GL_LINES
顶点两两连接,为多条线段构成。
GL_LINE_STRIP
绘制一系列线段。
GL_LINE_LOOP
类同上,但是首尾相连,构成一个封闭曲线。
面
定义面的顶点的顺序很重要 在拼接曲面的时候,用来定义面的顶点的顺序非常重要,因为顶点的顺序定义了面的朝向(前向或是后向),为了获取绘制的高性能,一般情况不会绘制面的前面和后面,只绘制面的“前面”。虽然“前面”“后面”的定义可以应人而易,但一般为所有的“前面”定义统一的顶点顺序(顺时针或是逆时针方向)。
下面代码设置逆时针方法为面的“前面”:
gl.glFrontFace(GL10.GL_CCW);
打开 忽略“后面”设置:
gl.glEnable(GL10.GL_CULL_FACE);
明确指明“忽略“哪个面的代码如下:
gl.glCullFace(GL10.GL_BACK);
绘制面与绘制线差不多,同样先决定绘制时的顺序
short[] indices = { 0, 1, 2, 0, 2, 3 };
为了提高性能,通常将这些数组存放到 java.io 中定义的 Buffer 类中:
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); ibb.order(ByteOrder.nativeOrder()); ShortBuffer indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indices); indexBuffer.position(0);
开始绘制
//开启点坐标管道 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //传入点坐标 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); //根据点与绘线顺序绘面 gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); //关闭点坐标 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
其中GL10.GL_TRIANGLES:
GL_TRIANGLES
每隔三个顶点构成一个三角形,为多个三角形组成。
GL_TRIANGLE_STRIP
每相邻三个顶点组成一个三角形,为一系列相接三角形构成。
- GL_TRIANGLE_FAN
以一个点为三角形公共顶点,组成一系列相邻的三角形。
更多相关文章
- google手机Android编程语言-Simple语言定义中文版
- Android自定义控件之基本原理(一)
- Android(安卓)Studio 打包 Jar (将自己的 项目/自定义View 打包成
- Android之高德地图自定义样式
- Android(安卓)IPC 进程间通信实现理解
- Android自定义进度条——圆角横向进度条
- Android中自定义一个View的方法详解
- 说说Android中的style和theme
- Rect、RectF矩形类