使用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 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绘图之三:绘制形状相关推荐
- 使用Android OpenGL ES 2.0绘图之一:搭建一个OpenGL ES环境
传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...
- 使用Android OpenGL ES 2.0绘图之五:添加运动
传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...
- 使用Android OpenGL ES 2.0绘图之四:应用投影和相机视图
传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...
- 使用Android OpenGL ES 2.0绘图之二:定义形状
传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...
- Android OpenGL ES 2.0 屏幕坐标和3D世界坐标转换
Android OpenGL ES 2.0 屏幕坐标和3D世界坐标转换 查看全文 http://www.taodudu.cc/news/show-6705596.html 相关文章: word中如何加 ...
- Android opengl es 3.0 + ndk 绘画涂鸦项目
前言 写一个opengl es 3.0 + ndk 的绘画涂鸦项目,命名为白板哈哈哈,记录自己遇到的问题,顺便学到的知识整合一遍,算是对自己一段时间的总结. 项目地址:Whiteboard 如果对你有 ...
- android opengl es 纹理 不同设备 白色,android – OpenGL ES 2.0纹理没有在某些设备上显示...
早上好,这是2个纹理非幂的典型例子. 由于多种原因,纹理在分辨率上需要2的幂,这是一个非常常见的错误,每个人都碰巧陷入这个陷阱:)我也是. 2个纹理的非功率在某些设备/ GPU上运行平稳的事实,仅仅取 ...
- Android OpenGL ES (八)纹理绘制
基本原理 与渐变色接近,但有些区别: 渐变色:光栅化过程中,计算出颜色值,然后在片段着色器的时候可以直接赋值 纹理:光栅化过程中,计算出当前片段在纹理上的坐标位置,然后在片段着色器的中,根据这个纹理上 ...
- android opengl es 2.0 编程指南,Android OpenGL ES 2.0 初次体验
本文目录 一. OpenGL ES是什么? 二. OpenGL ES的版本 三. EGL是什么? 四. 需要知道的两个方法 五. 在Android中使用OpenGL ES的步骤 六. 例子1:简单的程 ...
最新文章
- Idea groovy表生成实体类带注释
- 配置jdk环境 windows
- 说说.net事件和委托。
- 在Java语言里 ==和equals的区别
- 2018深大计算机考研,深圳大学2018年硕士生招生复试分数线及调剂需求
- hana数据库导入mysql_【SAP HANA】新建表以及操作数据(3)
- Spark之RDD实战2
- Android emulator error: x86 emulation currently requires hardware acceleration的解决方案
- 听说Java老古董了?快被淘汰了?高级开发:我还就真看上它了!
- idea卡顿的解决方法_《王者荣耀》卡顿及无法下载资源解决方法说明 5周年祈愿活动出错了怎么办...
- 用到f6的快捷键_让你的办公效率成倍翻得快捷键。
- 力扣-5 最长回文子串
- 由spin_lock_bh想到的一些事
- SARIMA时间序列模型预测城市房价数据
- oracle lob函数,Oracle可以处理LOB字段的常用字符函数
- 怎样开启浏览器位置服务器,怎样打开浏览器定位服务器地址
- CAD能打开PDF格式吗?这样做可以快速实现
- AUTOSAR开发工具DaVinci Configurator里的Modules
- 十年阿里资深架构师教你如何做到年薪50万的程序员(文末附送学习资料)
- 重阳节[转自百度]---又到重阳节了