传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ 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 ProgramGLES20.glAttachShader(mProgram, vertexShader);   // 将vertex shader添加到programGLES20.glAttachShader(mProgram, fragmentShader); // 将fragment shader添加到programGLES20.glLinkProgram(mProgram);                  // 创建可执行的 OpenGL ES program
}

此时,应该可以添加真正的绘制调用了。你需要提供一些参数给渲染管道,告诉它想要绘制什么以及如何绘制。因为绘制操作是因形状而异的,让形状类包含特定的绘制逻辑是一个不错的设计。
        创建一个draw()方法负责绘制形状。下面的代码将展示向形状的vertex shader和fragment shader设置位置和颜色值,然后执行绘制操作。

public void draw() {// 添加program到OpenGL ES环境中GLES20.glUseProgram(mProgram);// 获取指向vertex shader的成员vPosition的handlemPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");// 启用一个指向三角形的顶点数组的handleGLES20.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图形管道让形状旋转起来,以及更多有趣的用法。

转载于:https://www.cnblogs.com/innosight/p/3271163.html

使用Android OpenGL ES 2.0绘图之三:绘制形状相关推荐

  1. 使用Android OpenGL ES 2.0绘图之一:搭建一个OpenGL ES环境

    传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...

  2. 使用Android OpenGL ES 2.0绘图之五:添加运动

    传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...

  3. 使用Android OpenGL ES 2.0绘图之四:应用投影和相机视图

    传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...

  4. 使用Android OpenGL ES 2.0绘图之二:定义形状

    传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...

  5. Android OpenGL ES 2.0 屏幕坐标和3D世界坐标转换

    Android OpenGL ES 2.0 屏幕坐标和3D世界坐标转换 查看全文 http://www.taodudu.cc/news/show-6705596.html 相关文章: word中如何加 ...

  6. Android opengl es 3.0 + ndk 绘画涂鸦项目

    前言 写一个opengl es 3.0 + ndk 的绘画涂鸦项目,命名为白板哈哈哈,记录自己遇到的问题,顺便学到的知识整合一遍,算是对自己一段时间的总结. 项目地址:Whiteboard 如果对你有 ...

  7. android opengl es 纹理 不同设备 白色,android – OpenGL ES 2.0纹理没有在某些设备上显示...

    早上好,这是2个纹理非幂的典型例子. 由于多种原因,纹理在分辨率上需要2的幂,这是一个非常常见的错误,每个人都碰巧陷入这个陷阱:)我也是. 2个纹理的非功率在某些设备/ GPU上运行平稳的事实,仅仅取 ...

  8. Android OpenGL ES (八)纹理绘制

    基本原理 与渐变色接近,但有些区别: 渐变色:光栅化过程中,计算出颜色值,然后在片段着色器的时候可以直接赋值 纹理:光栅化过程中,计算出当前片段在纹理上的坐标位置,然后在片段着色器的中,根据这个纹理上 ...

  9. android opengl es 2.0 编程指南,Android OpenGL ES 2.0 初次体验

    本文目录 一. OpenGL ES是什么? 二. OpenGL ES的版本 三. EGL是什么? 四. 需要知道的两个方法 五. 在Android中使用OpenGL ES的步骤 六. 例子1:简单的程 ...

最新文章

  1. Idea groovy表生成实体类带注释
  2. 配置jdk环境 windows
  3. 说说.net事件和委托。
  4. 在Java语言里 ==和equals的区别
  5. 2018深大计算机考研,深圳大学2018年硕士生招生复试分数线及调剂需求
  6. hana数据库导入mysql_【SAP HANA】新建表以及操作数据(3)
  7. Spark之RDD实战2
  8. Android emulator error: x86 emulation currently requires hardware acceleration的解决方案
  9. 听说Java老古董了?快被淘汰了?高级开发:我还就真看上它了!
  10. idea卡顿的解决方法_《王者荣耀》卡顿及无法下载资源解决方法说明 5周年祈愿活动出错了怎么办...
  11. 用到f6的快捷键_让你的办公效率成倍翻得快捷键。
  12. 力扣-5 最长回文子串
  13. 由spin_lock_bh想到的一些事
  14. SARIMA时间序列模型预测城市房价数据
  15. oracle lob函数,Oracle可以处理LOB字段的常用字符函数
  16. 怎样开启浏览器位置服务器,怎样打开浏览器定位服务器地址
  17. CAD能打开PDF格式吗?这样做可以快速实现
  18. AUTOSAR开发工具DaVinci Configurator里的Modules
  19. 十年阿里资深架构师教你如何做到年薪50万的程序员(文末附送学习资料)
  20. 重阳节[转自百度]---又到重阳节了

热门文章

  1. 职场中混日子的人都有这几种习惯
  2. 给新手开店选品的建议
  3. Java中的properties文件中的key不能使用项目中的接口名和Java文件名
  4. SpringMVC_02
  5. Azure Cosmos DB从零到10分钟
  6. ssis 派生列_具有多个表达式与多个转换的SSIS派生列
  7. JS删除数组里的某一个元素
  8. javascript实现奥运倒计时代码
  9. ----初读《构建之法》的疑虑
  10. Android-LayoutInflater