Android OpenGl ES使用原理总结与代码示例

一、相关概念简介:
OpenGl :
    OpenGl是一个定义好的跨平台图形处理接口库,通过它可操作GPU来完成图像处理。它跨平台是因为各个硬件厂家都按照这套接口规范具体实现了对应功能,供上层调用。
OpenGl ES:
    手机由于性能相对较弱,难以支持OpenGl的全部功能,所以Android中使用的是OpenGl的子集OpenGl ES。
EGL:
    OpenGl是一套跨平台的接口,它与各个平台本地窗口系统之间的交互,是借助于一个中间控制层,这个中间控制层就是EGL。 EGL也有自己的一套标准API,由各个平台的系统来完成其具体实现。
    EGL是OpenGL和本地窗口体系进行联系的桥梁,负责管理OpenGL的运行状态、渲染图像到本地窗口或缓冲区等功能。
    在Android中,OpenGL的每一步处理,都需要依赖于EGL提供的这些相关功能支持,所以必须先创建EGL环境,才能正常进行OpenGL处理。
    不过Android中GLSurfaceView会自己在GLThread中完成EGL环境的初始化,使用GLSurfaceView时,开发者并不需要自己来初始化EGL环境。
二、OpenGL原理大致理解:
1.首先可以想象Opengl内部有一个三维空间,里面可以放置很多三维物体。它有两个坐标系概念:
        世界坐标系(world space):是整个OpenGl空间的坐标系,里面可以放置多个物体的3D模型
        局部坐标系(local space):物体模型自己内部的坐标系,模型生成时其各部分的位置坐标是相对此坐标系的。
        因此,把模型添加到世界坐标系上时,需要确定模型在世界坐标系中的位置,这一般是通过矩阵变换来处理的(Model matrix)。
        若不变换模型坐标,直接添加,由于各个模型内部的坐标原点在世界坐标系中会重叠,一般会导致模型重叠在一起。
2.想象OpenGl世界中有一个观察者,他从不同的位置和角度看这个世界时,看到的东西肯定也不一样。
        所以,需要确定观察点和观察方向,建立观察空间坐标系,通过矩阵变换(View matrix),
        将世界坐标系中的位置坐标转为为观察空间中的坐标。这代表着观察者在自己视野前方所看到的物体坐标。
        如果不加设置,默认情况下,观察空间坐标系与世界坐标系重合,观察视角朝向Z轴负反向。
3.观察者看到的景象中只有部分是需要最终输出渲染的,通过矩阵变换(Projection matrix)
        可以将观察空间中坐标变换到裁剪空间中,裁剪空间中各个坐标轴上[-1,1]范围内的部分会被保留,其余会被去除。
        因此这个裁剪矩阵通过定义对应关系,从而定义了观察空间中哪些部分是"可见"的。
        Android ES2中,这个矩阵一般是调用投影方式的API,并设置观察范围的相关参数来生成的, 所以这个矩阵变换相当于同时约束了观察范围和投影方式。
        Android ES2中包含了两种投影方式,
            正交投影:观察到的物体不会因为离观察点的远近有差别,即近处的点和远处的点,最终投影在输出画面上的大小都一样大;
            透视投影:观察到的物体随距观察点的远近产生变化,近大远小。
4.然后Android中,OpenGl会自动将裁剪空间上的坐标计算成屏幕指定显示区域上的坐标,经过相应渲染处理后,并最终显示出来。 (这一步不用考虑OpenGL空间中的坐标系与Android屏幕坐标系的异同,API内部自己会正确计算出对应坐标的。)
    最终,裁剪空间 = (Projection matrix) * (View matrix) * (Model matrix) * 模型本地空间;
    最终可观察到的部分,是裁剪空间中各个坐标轴上[-1,1]范围内的部分。
    但我们在屏幕上看到的只能是一个二维画面,所以OpenGl会根据我们的设置,将这部分三维物体映射渲染成一个看起来"像三维物体"的二维画面。
##.内部的一些概念介绍:
    在OpenGl ES三维空间中,本质上讲能生成的只有点、线、三角形,任何复杂的模型图形都是用三角形拼接成的。
    (查资料,好像传统OpenGl中应该是直接支持更复杂的四边形、多边形的。OpenGl ES只是子集,应该做了简化)
1.OpenGL 里有两个最基本的概念:Vertex (顶点)和 Fragment(片元)。
        Vertix(顶点):一切图形都从 Vertix 开始,Vertix 序列围成了一个图形;
        Fragment(片元):是指OpenGl图形映射显示到屏幕上时,那一个个的映射区域。
2.光栅化(Rasterization):光栅化是把点、线、三角形映射到屏幕上的像素点的过程(每个映射区域叫一个 Fragment), 也就是生成 Fragment 的过程。
        通常一个 Fragment 对应于屏幕上的一个像素, 但高分辨率的屏幕可能会用多个像素点映射到一个 Fragment,以减少 GPU 的工作。
3.OpenGl空间对应的x、y、z坐标,都在[-1,1]的范围内。
        这是一个数学概念上的空间范围,这个范围内的坐标称之为归一化设备坐标。 它是独立于屏幕实际的尺寸和形状的。
4.着色器(Shader):OpenGl ES2中使用的,在GPU上运行的小程序。可通过处理它们来处理顶点或片元。
        此程序使用OpenGL ES SL语言来编写。它是一个描述顶点或像素特性的简单程序。
        分为顶点着色器、片元着色器。
        顶点着色器是针对每个顶点执行一次,用于确定顶点的位置;
        片元着色器是针对每个片元执行一次,用于确定每个片元(像素)的颜色
在 OpenGL 的世界里,我们只能画点、线、三角形,复杂的图形都是由三角形构成的。
在 OpenGL 里有两个最基本的概念:Vertex (顶点)和 Fragment(片元)。一切图形都从 Vertix 开始,Vertix 序列围成了一个图形。那什么是 Fragment 呢?为此我们需要了解一下光栅化(Rasterization):光栅化是把点、线、三角形映射到屏幕上的像素点的过程(每个映射区域叫一个 Fragment),也就是生成 Fragment 的过程。通常一个 Fragment 对应于屏幕上的一个像素,但高分辨率的屏幕可能会用多个像素点映射到一个 Fragment,以减少 GPU 的工作。
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值