首先遇到一个新的事物,我们可以用3w来分析。
What:OpenGL ES是什么?功能是什么?(do what)
Why:为什么要使用OpenGL ES?(Why do)
How:如何使用OpenGL ES?(How do)
大致从这里切入,对OpenGL ES有一个整体的了解,这样有利于学习,避免一叶障目。
what
OpenGL(全写Open Graphics Library)是指定义了一个跨编程语言、跨平台的编程接口规格的专业的图形程序接口。
是一个接口,是行业领域中最为广泛接纳的 2D/3D 图形 API。
功能:
OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植;OpenGL可以与Visual C++紧密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠性;OpenGL使用简便,效率高。它具有七大功能:
1、建模:OpenGL图形库除了提供基本的点、线、多边形的绘制函数外,还提供了复杂的三维物体(球、锥、多面体、茶壶等)以及复杂曲线和曲面绘制函数。
2、变换:OpenGL图形库的变换包括基本变换和投影变换。基本变换有平移、旋转、缩放、镜像四种变换,投影变换有平行投影(又称正射投影)和透视投 影两种变换。其变换方法有利于减少算法的运行时间,提高三维图形的显示速度。
3、颜色模式设置:OpenGL颜色模式有两种,即RGBA模式和颜色索引(Color Index)。
4、光照和材质设置:OpenGL光有自发光(Emitted Light)、环境光(Ambient Light)、漫反射光(Diffuse Light)和高光(Specular Light)。材质是用光反射率来表示。场景(Scene)中物体最终反映到人眼的颜色是光的红绿蓝分量与材质红绿蓝分量的反射率相乘后形成的颜色。
5、纹理映射(Texture Mapping)。利用OpenGL纹理映射功能可以十分逼真地表达物体表面细节。
6、位图显示和图象增强图象功能除了基本的拷贝和像素读写外,还提供融合(Blending)、抗锯齿(反走样)(Antialiasing)和雾(fog)的特殊图象效果处理。以上三条可使被仿真物更具真实感,增强图形显示的效果。
7、双缓存动画(Double Buffering)双缓存即前台缓存和后台缓存,简言之,后台缓存计算场景、生成画面,前台缓存显示后台缓存已画好的画面。
简单地来说,一般用来处理图形显示相关方面。
下面来看OpenGL ES,是为用于嵌入式设备而设计的OpenGL子集。
OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。该API由Khronos集团定义推广,Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。
why
首先因为移动设备本身的图形绘制只支持2D,想要做出绚丽的3D效果必须得借助OpenGL。也许有人会说,在android中使用camera不也能绘制出3D效果么,对此我只能说:Camera只是对OpenGL做了一个封装,它本身仍然是属于OpenGL范畴。 其次OpenGL直接操作native层的内存。在android上会有更高的运行效率。而且由于OpenGL的绘制是在在主线程之外的另一条线程里操作,所以会更加流畅,不会阻塞主线程。
How
为了能适应各种硬件平台,所以OpenGL ES2.0并不包含任何执行窗口任务或者处理用户输入的函数,我们需要通过应用程序本身所运行的窗口系统来提供相应操作才能处理这些操作。比如说:android手机上,我们想要调用OpenGL的话就必须得使用GLSurfaceView来渲染图形。因为GLSurfaceView可以为自己创建一个窗口,并在视图(View Hierarchy)层次上穿个洞让底层的OpenGL surface显示出来。对于大多数情况下这就足够了。(但是由于GLSurfaceView本身就是window的一部分。所以它没法像其他的View一样进行动画和变形操作。)另外 OpenGL ES2.0也不包含任何表达三维模型,读取图像文件的操作,这个时候,我们需要通过一系列的几何图元(点,线,三角形)来创建三维空间的物体。GLSurfaceView和图元(点线面)将是我们后面讲述的重点。
Android支持OpenGL通过其框架API和本地开发工具包(NDK)。
在Android框架有两个基本类,让你创建和操作图形与OpenGL ES API:GLSurfaceView GLSurfaceView.Renderer。
下面重点看如何使用
在讲后面内容的时候我们需要先思考一个问题,假设让你来画一幅画的话,你需要知道哪些要素了才能开始去画这幅画呢?
Android中View的源码实现绘制的时候经历了三步,首先是测量控件的大小,因为只有知道大小了才能在布局中进行定位。其次就是确定位置,不确定位置的话就不知道要画在哪。最后才是开始绘制。
如果按照这个步骤,那么OpenGL ES2中是如何去测量,定位还有绘制的呢?
1.OpenGL中的定位和测量
相比起Android中View,OpenGL的的定位测量要简单的多,他只需要我们在它的坐标系上 定义一些顶点,这些顶点可以有很多属性,但最重要的属性就是位置。位置属性通过x,y,z坐标来体现。通过这些顶点与顶点的组合就形成了不同的图形,而这些图形的位置也根据每个点的位置而确定了下来。
通过代码来体现就是
float[] tableVertices = {
0f, 0f,0f,
-0.5f,-0.8f,0f,
0.5f,-0.8f,0f,
0.5f,0.8f,0f,
-0.5f,0.8f,0f,
-0.5f,-0.8f,0f
};
但这不就是一个普通的float数组么,float数组是java的类型,而OpenGL使用的是却是另外一种语言。那么我们怎么把这份数据传递给运行在本地环境的OpenGL呢?下面就会解答这个问题。
2.如何将java数据传递给本地系统库中的OpenGL。
要知道,Android运行代码的时候并不是直接运行在硬件上的,而是运行在Dalvik虚拟机上的。运行在虚拟机上的代码不能直接访问本地环境。除非通过特定的API的接口。Android这样设计其实也是为了降低系统的耦合性,让开发者不用去关心CPU等硬件,专心搞软件就行了。这样做一般也没问题,但在与本地系统交互的时候就比较麻烦了,比如说OpenGL。OpenGL作为本地系统库直接运行在硬件上。
继续上面那个问题:如何将java数据传递给本地系统库中的OpenGL。 有两种技术可以实现:1.使用本地接口JNI技术,这个技术已经集成在Android系统android.opengl.GLES20中,我们可以直接调用. 2.改变内存分配的方式,java有一个特殊的集合,他们可以分配本地内存快,并且把java的数据复制到本地内存。而本地内存是可以被本地环境读取,这样就可以达到传递数据的目的。
代码实现如下:
private FloatBuffer vertexData; //缓存的顶点数据
vertexData =
//allocateDirect分配本地内存float数组的长度乘以每一个float类型占用的字节数
ByteBuffer.allocateDirect(tableVertices.length * BYTES_PER_FLOAT)
//告诉字节缓冲区按照本地字节序组织它的内容
//当一个值占用多个字节,比如32位整形数,字节按照从高位到低位 或者从低位到高位排序
//排什么顺序其实不重要,重要的是程序运行过程中所有的字节都得按同样的顺序排序,
//不能有的排正序,有的排倒序。 而 //order(ByteOrder.nativeOrder()就能达到这个目的。
.order(ByteOrder.nativeOrder())
//根据分配的内存获取一个能分配本地内存的FloatBuffer实例对象。
.asFloatBuffer();
//将顶点数据 内存从虚拟机中拷贝到本地
vertexData.put(tableVertices);
现在OpenGL已经可以读取这些数据,那么它会如何去使用这些数据呢? 这就涉及到OpenGL管道的概念了。
OpenGL管道
大部分图形系统都可以比作工厂中的装配线(Assemble line)或者称为管道(Pipeline)。前一道的输出作为下道工序的输入。主 CPU 发出一个绘图指令,然后可能由硬件部件完成坐标变换,裁剪,添加颜色或是材质,最后在屏幕上显示出来。
通过打开OpenGL管道的相应开关将顶点参数传给 OpenGL 库。然后调用函数,对这些顶点按一定的方式进行绘制,以达到显示不同的图形的目的。
OpenGL ES 所有能够绘制的基本图形,点,线段和三角形。其它所有复杂的 2D 或 3D 图形都是由这些基本图形构成。
下面来通过一个具体实例来认识OpenGL ES
———————————坑的分割—————
参考链接:
http://blog.csdn.net/hejjunlin/article/details/61615215
https://lord198712071.gitbooks.io/youyang_opengl-es-2-0/content/chapter1.html(这个不完整,没写完。)
https://blog.piasy.com/2016/06/07/Open-gl-es-android-2-part-1/
(这里有个挺全面的实例)
http://www.jianshu.com/c/30e2e76bc140
http://wiki.jikexueyuan.com/project/opengl-es-guide/introduction.html
http://www.cnblogs.com/sunminmin/p/4478578.html