`
xuela_net
  • 浏览: 489348 次
文章分类
社区版块
存档分类
最新评论

使用Android OpenGL ES 2.0绘图之三:绘制形状

 
阅读更多

传送门轮子的专栏转载请注明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程序员面试宝典 李宁

    《Android高薪之路:Android程序员面试宝典》目录: 第1章 Android入门 1 1 关于Android的非技术问题 1 1 1 为什么看好 Android 1 1 2 以前是否从事过Android的工作 做过哪些工作 1 1 3 你做的最复杂的界面是什么 1 ...

    OpenGL 应用开发指南

    OpenGL 应用开发指南,android卷,主要讲解android端的opengl es 二维绘图,3D绘制知识

    NativeGL_demo:此程序使用android native代码实现EGL,并使用SurfaceView作为OpenGL绘图窗口。即可提高图形渲染性能,又可使用java层定义的图形界面

    使用GLSurfaceView作为绘图窗口,使用GLSurfaceView.Renderer实现OpenGL渲染图形,并通过调用android.opengl.GLES20中的API函数实现对图像的渲染 使用GLSurfaceView作为绘图窗口,使用GLSurfaceView.Renderer实现...

    OpenGL ES绘图迷你太阳系

    android平台下使用OpenGL ES绘制的模拟太阳系(日,地,月)运行的图形。 太阳自转,地球自转并绕太阳公转,月亮自转并绕地球公转。

    Rust库可通过易于使用的API通过硬件加速2D形状,图像和文本的绘制。-Rust开发

    Rust库可通过易于使用的API通过硬件加速2D形状,图像和文本的绘制。 Speedy2D硬件加速的形状,图像和文本绘图,并具有易于使用的API。 Speedy2D的目标是:用于创建窗口,渲染图形/文本和处理输入的最简单的Rust API...

    Android openGl 绘制简单图形的实现示例

    学习五部曲,弄清楚5个W一个H(when(什么时候使用)、where(在哪个地方使用?)、who(对谁使用)、what(是个什么东西)、why(为什么要这么用?).一个H即:how(到底该怎么用?)),基本的概念篇主要围绕这几个...

    Android 4游戏编程入门经典

    第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 结束语

    SweetRide:OpenGL Android 3D图形引擎。 主线程中的代码,GL线程中的绘图

    甜蜜的骑基于opengl es 2.0构建的Android 3d图形引擎。 在主线程中编码ui,让引擎在gl线程中绘制。 已有2个月没有进行此工作了,请上传此文件以确保安全,直到我决定/觉得自己再次进行此工作为止。 对于许多其他正在...

    android游戏编程入门

    android游戏编程入门 《Android4游戏编程入门经典》是2012年清华大学出版社出版的图书,作者是(美)策希纳... 14.4 OpenGL ES 2.0以及更多  内容 532  14.5 框架及引擎 532  14.6 网络资源 534  14.7 结束语 534

    Packt.AndEngine.for.Android.Game.Development

    AndEngine基于libGDX框架开发,使用OpenGL ES进行图形绘制,底层使用C++编写,通过JNI调用来实现,因此比较高效,功能强大。同时集成了Box2D物理引擎,因此能实现一些较为复杂的物理效果。在Rokon(另一个Android 2D游戏...

    Android实例代码

    12.2、OpenGL ES基础: 12.3、绘制2D图形: 12.4、绘制3D图形: 第13章、Android的网络应用 13.1、基于TCP协议的网络通信(套接字Socket):Socket; ServerSocket; 13.2、使用URL访问网络资源:URL; ...

    疯狂Android讲义(第2版)源代码 第6章~第9章

    《疯狂Android讲义(第2版)》.(李刚).源代码 疯狂Android讲义目录结构: 第2章、Android应用程序界面设计,即View 2.2、布局管理(Layout):LinearLayout、TableLayout、FrameLayout、RelativeLayout; 2.3、基本...

    疯狂Android讲义源码

     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笔记

    AndEngine基于libGDX框架开发,使用OpenGL ES进行图形绘制,底层使用C++编写,通过JNI调用来实现,因此比较高效,功能强大。同时集成了Box2D物理引擎,因此能实现一些较为复杂的物理效果。在Rokon(另一个Android 2D游戏...

    OpenGL小白入门知识点详解

    CPU: 中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps、Drawables等都是一起打包到统一的纹理)。 GPU:一个类似于CPU的专门用来处理Graphics的处理器, 作用用来帮助加快...

    疯狂Android讲义.part2

    第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 ...

    疯狂Android讲义.part1

    第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 ...

    2D游戏引擎运行库Cantk-Runtime.zip

    用OpenGL ES 2.0 C API实现绘图操作,接近原生游戏引擎的性能。3.强大。实现HTML5 Canvas 2D常用操作,让任何HTML5游戏引擎,只需少量适配代即可运行。4.多平台支持。目前支持Android平台,以后逐步支持iOS, Tizen等...

Global site tag (gtag.js) - Google Analytics