传送门☞轮子的专栏☞转载请注明☞http://blog.csdn.net/leverage_1229
在定义好待绘制的形状之后,就要开始绘制它们了。使用OpenGL ES 2.0绘制形状可能比你想象的要复杂一些,因为它的API中提供了大量控制渲染管道的行为。
这一节将介绍如何使用OpenGL ES 2.0的API绘制上一节你已经定义好的那些形状。
1初始化形状
在做任何绘制之前,你必须初始化形状并加载它。除非形状的结构(原始坐标)在程序执行过程中发生了改变,都应该在你的Renderer类的onSurfaceCreated()方法中进行初始化内存和处理效率。
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
...
// 初始化一个三角形
mTriangle = new Triangle();
// 初始化一个正方形
mSquare = new Square();
}
2绘制一个形状
使用OpenGL ES 2.0绘制一个定义好的形状需要大量的代码,因为必须提供给图形渲染管道很多细节信息。具体定义如下:
2.1VertexShader:用于呈现形状顶点的OpenGL ES图形代码。
2.2FragmentShader:用于呈现形状外观(颜色或纹理)的OpenGL ES代码。
2.3Program:一个OpenGL ES对象,包含了你想要用来绘制一个或多个形状的shader。
你至少需要一个vertex shader来绘制一个形状和一个fragment shader来为形状着色。这些shader必须被编译,然后将它们添加到一个OpenGL ES program中,接着使用program绘制形状。这里有一个例子,演示了如何定义基本的shader来绘制一个形状:
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
Shader包含OpenGL Shading Language(GLSL)代码,必须在OpenGL ES环境下先编译再使用。想要编译这些代码,需要在你的Renderer类中创建一个工具类方法:
public static int loadShader(int type, String shaderCode){
// 创建一个vertex shader类型(GLES20.GL_VERTEX_SHADER)
// 或一个fragment shader类型(GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// 将源码添加到shader并编译它
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
为了绘制形状,必须编译shader代码,接着将它们添加到一个OpenGL ES program 对象中,然后链接这个program。可以在你的renderer对象的构造器中做这些事情,因为只需要执行一次。
注:编译OpenGL ES shader和链接program是很耗CPU的,所以你应该尽量避免多次执行它们。如果在运行时还不知道shader的内容,那么就应该只创建一次代码,然后缓存起来以备后用。
public Triangle() {
...
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // 创建空的OpenGL ES Program
GLES20.glAttachShader(mProgram, vertexShader); // 将vertex shader添加到program
GLES20.glAttachShader(mProgram, fragmentShader); // 将fragment shader添加到program
GLES20.glLinkProgram(mProgram); // 创建可执行的 OpenGL ES program
}
此时,应该可以添加真正的绘制调用了。你需要提供一些参数给渲染管道,告诉它想要绘制什么以及如何绘制。因为绘制操作是因形状而异的,让形状类包含特定的绘制逻辑是一个不错的设计。
创建一个draw()方法负责绘制形状。下面的代码将展示向形状的vertex shader和fragment shader设置位置和颜色值,然后执行绘制操作。
public void draw() {
// 添加program到OpenGL ES环境中
GLES20.glUseProgram(mProgram);
// 获取指向vertex shader的成员vPosition的handle
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// 启用一个指向三角形的顶点数组的handle
GLES20.glEnableVertexAttribArray(mPositionHandle);
// 准备三角形的坐标数据
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// 获取指向fragment shader的成员vColor的handle
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// 设置三角形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// 绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// 禁用指向三角形的顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
一旦你完成了这些代码,绘制这个对象只需要在Renderer类的onDrawFrame()方法中调用draw()方法。当你运行应用程序时,它看起来应该是这样的:
此示例中的代码还存在很多问题。首先,它不会给人留下深刻印象。其次,当你改变设备屏幕的方向时,三角形会被压扁和改变形状。原因是它的各个顶点无法根据屏幕的宽高比例进行修正。可以使用投影和相机视图来解决这个问题。不过那是下一节的内容了。
最后,三角形是静止不动的,这样看起来有点无聊。在后续内容中,我们还将介绍如何使用OpenGL ES图形管道让形状旋转起来,以及更多有趣的用法。
分享到:
相关推荐
《Android高薪之路:Android程序员面试宝典》目录: 第1章 Android入门 1 1 关于Android的非技术问题 1 1 1 为什么看好 Android 1 1 2 以前是否从事过Android的工作 做过哪些工作 1 1 3 你做的最复杂的界面是什么 1 ...
OpenGL 应用开发指南,android卷,主要讲解android端的opengl es 二维绘图,3D绘制知识
使用GLSurfaceView作为绘图窗口,使用GLSurfaceView.Renderer实现OpenGL渲染图形,并通过调用android.opengl.GLES20中的API函数实现对图像的渲染 使用GLSurfaceView作为绘图窗口,使用GLSurfaceView.Renderer实现...
android平台下使用OpenGL ES绘制的模拟太阳系(日,地,月)运行的图形。 太阳自转,地球自转并绕太阳公转,月亮自转并绕地球公转。
Rust库可通过易于使用的API通过硬件加速2D形状,图像和文本的绘制。 Speedy2D硬件加速的形状,图像和文本绘图,并具有易于使用的API。 Speedy2D的目标是:用于创建窗口,渲染图形/文本和处理输入的最简单的Rust API...
学习五部曲,弄清楚5个W一个H(when(什么时候使用)、where(在哪个地方使用?)、who(对谁使用)、what(是个什么东西)、why(为什么要这么用?).一个H即:how(到底该怎么用?)),基本的概念篇主要围绕这几个...
第1章 android,后起之秀 1.1 android简介 1.2 版本分裂 1.3 谷歌的角色 1.3.1 android开源项目 1.3.2 android market... 14.4 opengl es 2.0以及更多内容 14.5 框架及引擎 14.6 网络资源 14.7 结束语
甜蜜的骑基于opengl es 2.0构建的Android 3d图形引擎。 在主线程中编码ui,让引擎在gl线程中绘制。 已有2个月没有进行此工作了,请上传此文件以确保安全,直到我决定/觉得自己再次进行此工作为止。 对于许多其他正在...
android游戏编程入门 《Android4游戏编程入门经典》是2012年清华大学出版社出版的图书,作者是(美)策希纳... 14.4 OpenGL ES 2.0以及更多 内容 532 14.5 框架及引擎 532 14.6 网络资源 534 14.7 结束语 534
AndEngine基于libGDX框架开发,使用OpenGL ES进行图形绘制,底层使用C++编写,通过JNI调用来实现,因此比较高效,功能强大。同时集成了Box2D物理引擎,因此能实现一些较为复杂的物理效果。在Rokon(另一个Android 2D游戏...
12.2、OpenGL ES基础: 12.3、绘制2D图形: 12.4、绘制3D图形: 第13章、Android的网络应用 13.1、基于TCP协议的网络通信(套接字Socket):Socket; ServerSocket; 13.2、使用URL访问网络资源:URL; ...
《疯狂Android讲义(第2版)》.(李刚).源代码 疯狂Android讲义目录结构: 第2章、Android应用程序界面设计,即View 2.2、布局管理(Layout):LinearLayout、TableLayout、FrameLayout、RelativeLayout; 2.3、基本...
12.2 OpenGL和OpenGL ES简介 453 12.3 绘制2D图形 454 12.3.1 在Android应用中使用 OpenGL ES 454 12.3.2 绘制平面上的多边形 457 12.3.3 旋转 463 12.4 绘制3D图形 465 12.4.1 构建3D图形 465 ...
AndEngine基于libGDX框架开发,使用OpenGL ES进行图形绘制,底层使用C++编写,通过JNI调用来实现,因此比较高效,功能强大。同时集成了Box2D物理引擎,因此能实现一些较为复杂的物理效果。在Rokon(另一个Android 2D游戏...
CPU: 中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps、Drawables等都是一起打包到统一的纹理)。 GPU:一个类似于CPU的专门用来处理Graphics的处理器, 作用用来帮助加快...
第1章 Android应用与开发环境 1 1.1 Android的发展和历史 2 1.1.1 Android的发展和简介 2 1.1.2 Android平台架构及特性 3 1.2 搭建Android开发环境 5 1.2.1 下载和安装Android SDK 5 1.2.2 安装Eclipse和ADT插件 7 ...
第1章 Android应用与开发环境 1 1.1 Android的发展和历史 2 1.1.1 Android的发展和简介 2 1.1.2 Android平台架构及特性 3 1.2 搭建Android开发环境 5 1.2.1 下载和安装Android SDK 5 1.2.2 安装Eclipse和ADT插件 7 ...
用OpenGL ES 2.0 C API实现绘图操作,接近原生游戏引擎的性能。3.强大。实现HTML5 Canvas 2D常用操作,让任何HTML5游戏引擎,只需少量适配代即可运行。4.多平台支持。目前支持Android平台,以后逐步支持iOS, Tizen等...