iOS视觉 OpenGL初探

1、图形API

1. 图形API简介

  • OpenGL是一个跨编程语言、跨平台的编程图形程序接口
  • OpenGL ESOpenGL三维图形API的本身,针对 手机、PDA和游戏主机等嵌入式设备而设计的,去除了不少没必要要觉和性能较低的API接口
  • DirectX是由不少API组成的, DirectX并非一个单纯的图形API。最重要的是 DirectX是属于Windows上一个多媒体处理框架,并不支持Windows之外的平台
  • Metal是Apple为游戏开发者退出的新的平台技术,该技术能为3D图像提升10倍的渲染性能

2. 图形API做用

简单来讲就是 实现图形的底层渲染web

  • 好比在游戏开发中对于游戏场景/游戏人物的渲染
  • 好比在音视频开发中对于视频解码后的数据渲染
  • 好比在地图引擎对于地图上的数据渲染
  • 好比在动画中实现动画的绘制
  • 好比在视频处理中对于视频加上滤镜效果

OpenGL/OpenGL ES/Metal 在任何项目中解决问题的本质——利用 GPU芯片来高效渲染图形图像编程

图形API是iOS开发者惟一接近GPU的方式数组

2、OpenGL下专业名词

  • OpenGL上下文 Context
    • 上下文是一个很是庞大的状态机,保存了OpenGL中的各类状态
    • 无论在哪一个语言中,都是相似C语言同样面向过程的函数
  • OpenGL状态机描述了一个对象的生命周期经历各类状态发生转变时的动因、条件及转变中所执行的活动
    • 有记忆功能,能记住其当前的状态(如当前所使用的颜色、是否开始了混合功能等)
      • glClearColor(1,1,1,1)设置颜色
      • glEable(GL_DEPTH_TEST)开启深度测试
      • glEable(GL_BLEND)开启混合
    • 能够接收输入,根据输入的内容和本身的原先状态,修改本身当前状态,而且能够有对应输出
    • 当进入特殊状态(停机状态)时便再也不接收输入,中止工做
  • 渲染:将图形/图像数据转换成3D空间图像的操做叫作渲染(Rendering)即 数据->可视化界面的过程,也就是咱们口中所说的 绘制
  • 顶点数组(VertexArray)和 顶点缓冲区(VertexBuffer):
    • 顶点数据是由GPU处理的
    • 顶点数组是存在内存中,GPU经过操做内存来处理顶点数据
    • 顶点缓冲区存在显卡显存中,使得GPU的操做更为简单
    • 在调用绘制方法的时候,直接有内存传入顶点数据,也就是这部分数据以前是存储在内存中的,被称为顶点数组;性能更高的作法是,提早分配一块显存,将顶点数据预先传入到显存当中,这块显存就是顶点缓冲区
  • 管线:能够理解为流水线。在OpenGL下渲染图形,就会经历一个一个节点,这样的操做能够理解为管线。之因此称为管线是由于显卡在处理数据的时候是按照一个固定的顺序来的
  • 固定管线/存储着色器:在早期OpenGL版本中,开发者只须要传入相应的参数,就能快速完成图形的渲染。开发者只须要调用API使用封装好的固定shader程序段,并不须要关注底层实现原理
  • 着色器程序Shader是一段程序代码,是用来操做GPU进行计算的,主要的着色器有:
    • 顶点着色器(VertexShader)
    • 片元着色器(Metal叫片元函数)/片断着色器(FragmentShader)/像素着色器(PixelShader)
    • 几何着色器(GeometryShader)
    • 曲面细分着色器(TessellationShader)
    • 在绘制的时候首先由 顶点着色器对传入的顶点数据进行运算,将顶点转换为图元;而后进行 光栅化转化为栅格化数据;最后传入 片元着色器进行运算
  • 顶点着色器(VertexShader)
    • 用来处理图形每一个顶点变换——旋转/平移/投影
    • 每个顶点都会执行一次
  • 片元着色器(FragmentShader)
    • 用来处理图形中每一个像素点的颜色计算和填充
    • 每一个像素都会执行一次片元着色器(并行执行)
  • GLSL(OpenGL Shading Language)
    • 是用来在OpenGL中着色编程的语言,即开发人员写的短小的自定义程序
    • 代替了固定渲染管线,使渲染管线中不一样层次具备可编程性,好比:视图转换、投影转换等
    • 用来操做 顶点着色器片元着色器
  • 光栅化(Rasterization)
    • 是把顶点数据转换成片元的过程,具备将图转化为一个个栅格组成的图像的做用
    • 其实就是将 几何图元变为二维图像的过程。该过程包含了两部分工做:决定窗口坐标中的那些整形栅格区域被基本图元占用;分配一个颜色值和一个深度值到各个区域
    • 把物体的数学描述以及与物体相关的颜色信息转换为屏幕上用于对应位置的像素及用于填充像素的颜色,这个过程称为光栅化
  • 纹理:即图片(位图)
  • 混合:两种颜色的视图叠在一块儿后的颜色就叫混合
  • 变换矩阵(Transformation):图形发平生移、缩放、旋转变换
  • 投影矩阵(Projection):将3D坐标转换为二维屏幕坐标
  • 渲染上屏/交换缓冲区(SwapBuffer)
    • 常规的OpenGL程序至少都会有两个缓冲区,显示在屏幕上的成为屏幕缓冲区,没有显示的成为离屏缓冲区。在一个缓冲区渲染完成以后,经过将屏幕缓冲区和离屏缓冲区交换,实现图像在屏幕上的显示
    • 为了防止交换缓冲区的时候屏幕上下区域的图像分属于两个不一样的帧,所以交换通常会等待显示器刷新完成的信号,在显示器两次刷新的间各类进行交换,这个信号就成为 垂直同步信号,这个技术成为 垂直同步

3、OpenGL坐标系统解析

  • 视口:显示的窗口区域 ,OpenGL使用glViewPort来设置视口
  • 投影方式
    • 正投影:用来渲染平面图形(远近物体大小同样)
    • 透视投影:用来渲染立体图形(远小近大)

MVP矩阵:Model、View、Projection框架

  • 2D笛卡尔坐标系:拥有x轴、y轴的平面坐标系(用来描述平面图形)
  • 3D笛卡尔坐标系:拥有x轴、y轴、z轴(z轴表示深度)的立体坐标系(用来描述立体图形)
  • 摄像机坐标系/照相机坐标系/观察者坐标系:自身为原点,向上为+y,向前为+z,向右为+x
  • 标准化设备坐标系(NDC):x轴、y轴的范围都是从-1到1的坐标系
  • 左手坐标系、右手坐标系:拇指方向为+x,食指方向为+y,手心方向为+z
    • 规范化设备坐标是左手坐标系
    • 物体/世界/照相机坐标系都是右手系坐标


经常使用坐标系的比较编程语言

  • 世界坐标系:系统的、绝对的坐标系
  • 物体空间坐标系:针对于物体个体的坐标系
  • 摄像机坐标系:观察的一个角度
  • 惯性坐标系:是 物体坐标系 和 世界坐标系 转换过程当中的一个中转站,为了方便物体坐标系转换到世界坐标系


坐标系对应的空间系编辑器

  • 局部空间(物体空间坐标系) :在描述这个物体自己
  • 世界空间:在大环境中的位置
  • 观察空间:观察坐标系空间
  • 裁剪空间:超过部分要裁剪
  • 屏幕空间:设备

4、理解图片从文件渲染屏幕的过程

1. 渲染过程当中的坐标变换

image.png
物体坐标/对象坐标->(模型变换)->世界坐标->(视觉变换)->观察者坐标/摄像机坐标->(投影变换)->裁剪坐标->(透视除法)->规范化设备坐标->(视口变化)->屏幕坐标
这个过程当中如下过程是能够开发者定义的:函数

  • 顶点信息(Attribute)
  • 模型变换(Vertex)
  • 模型空间(Model Space)
  • 世界空间(World Space)
  • 观察空间(Camera Space)
  • 裁剪空间(Clip Space)

image.png

2. 着色器的渲染流程image.png

  • 顶点着色器处理顶点数据
  • 细分着色器描述物体的形状(OpenGL3.0已经不开放细分着色器的API)
  • 几何着色器 决定输出的图元类型和个数(不须要关心细节)
  • 图元设置明确图元的类型,是三条线仍是三角形(三个顶点并必定是三角形)
  • 光栅化几何图元转为二维图像(像素点)
  • 片元着色器填充像素点的颜色、深度值等

3. 图片渲染流程

具体请见iOS中图片的解压缩到渲染过程oop

  • 图片从文件到屏幕过程 image.png
    • CPU计算视图frame、图片解码,而后经过数据总线交给GPU
    • GPU负责纹理混合、顶点变换与计算、像素点的填充计算,渲染到帧缓冲区
    • 时钟信号:垂直同步信号V-Sync/水平同步信号H-Sync
    • iOS设备双缓冲机制:显示系统一般会引入两个帧缓冲区
  • 图片加载的工做流程
    • 使用 +imageWithContentOfFile:从磁盘中加载一张图片并不会解压缩图片
    • 显示图片时CPU才会去解码图片
    • 隐式的 CATransaction捕获到了 UIImageView图层数的变化
    • 在主线程的下一个 Runloop到来时, Core Animation提交了这个隐式的 transaction
    • 渲染流程:即 4.2流程
  • 为何解压缩图片
    • 位图就是一个像素数组,数组中的每一个像素就表明着图片中的一个点(jpeg和png都是位图)
    • 在将磁盘中的图片渲染到屏幕以前,必须先要获得图片的原始像素数据,才能执行后续的绘制操做
  • 解压缩原理
    • 使用 CGBitmapContextCreate 对图片进行从新绘制,获得一张新的解压缩后的位图
相关文章
相关标签/搜索