利用OpenGL ES渲染图片(上)

OpenGL与OpenGL ES发展历史

图形编程接⼝

  • 2D图形编程接⼝口: GDI , Skiz, OpenVG
  • 3D图形编程接⼝口: DirectX , OpenGL/OpenGL ES , Embedded Systems

OpenGL的特点

  • 跨操作系统平台运⾏
  • 隐藏底层硬件信息
  • 专⽤渲染接⼝

    OpenGL历史变更

  • 1992年年7⽉月SGI发布OpenGL1.0版本
  • (硅图)SGI
  • Window NT版本的OpenGL
  • 1995年年OpenGL1.1版本发布
  • 2003年年7⽉月SGI与ARB发OpenGL 1.5
  • 2004年年8⽉月OpenGL2.0版本发布
  • OpenGL Shading Language(GLSL)
  • shader

OpenGL ES的版本

  • OpenGL ES 1.X :针对固定功能流水管线硬件
  • OpenGL ES 2.X :针对可编程流水管线硬件
  • OpenGL ES 3.X :OpenGL ES 2.0的扩展

着⾊色器器渲染过程

在渲染过程中,必须存储2种着⾊器,分别是顶点着⾊器、⽚元着⾊器。顶点着⾊器是第⼀个着⾊器、⽚元着色器是最后一个。顶点着⾊器中处理顶点、⽚元着⾊器处理像素点颜色。

屏幕渲染方式

  • On-Screen Rendering(当前屏幕渲染) : 指的是GPU的渲染操作是在当前用于显示的屏幕缓存区中进行的。

  • Off-Screen Rendering(离幕渲染) : 指的是GPU在当前屏幕缓存区以外新开辟一个缓存区进⾏渲染操作

⼀般情况下,OpenGL ES会将应用提供到渲染服务的动画直接渲染显示(使用基本的渲染流程) 但对于一些复杂的图像动画的渲染,并不能够直接渲染叠加显示出来。⽽是需要根据Command Buffer分通道进行渲染再组合。这个组合过程中,就有些渲染通道是不会直接显示出来的。标记此次渲染需要更多的渲染通道和合并步骤,⽽这些没有直接渲染显示在屏幕上的通道就是离屏渲染通道。

离屏渲染需要更多的渲染通道,⽽不同的渲染通道间切换需要消耗一定的时间,所以离屏渲染可能会发生卡顿。

相⽐于当前屏幕渲染,离屏渲染的代价相对⽽言较高。主要有以下2个原因:
1.创建新的缓存区
2.上下⽂切换

哪些情况会使用离屏渲染(off-Screen Render)?

  • drawRect
  • layer.shouldRasterize = true;
  • 有mask或者阴影(layer.makesToBounds)
    shouldRasterize(光栅化)、masks(遮罩)、shadows(阴影) edge antialiasing(抗锯⻮齿)、group opacity(不不透明)
  • Text(UILabel,CATextLayer,CoreText)

为什么要用FrameBuffer和 RenderBuffer?它们是什么关系?

A renderbuffer object is a 2D image buffer allocated by the application. The renderbuffer can be used to allocate and store color, depth, or stencil values and can be used as a color, depth, or stencil attachment in a framebuffer object. A renderbuffer is similar to an off-screen window system provided drawable surface, such as a pbuffer. A renderbuffer, however, cannot be directly used as a GL texture.

⼀个renderbuffer对象是应⽤分配的一个2D图像缓存区。renderbuffer能够被用来分配和存储颜色、深度或者模板值。也能够在一个framebuffer中被用作颜色、深度、模板的附件。⼀个renderbuffer是一个类似于屏幕窗口系统提供可绘制的表面。⽐如pBuffer。⼀个renderbuffer, 并不能直接被当做⼀个GL纹理使用。

A framebuffer object (often referred to as an FBO) is a collection of color, depth, and stencil buffer attachment points; state that describes properties such as the size and format of the color, depth, and stencil buffers attached to the FBO; and the names of the texture and renderbuffer objects attached to the FBO. Various 2D images can be attached to the color attachment point in the framebuffer object. These include a renderbuffer object that stores color values, a mip-level of a 2D texture or a cube map face, or even a mip-level of a 2D slice in a 3D texture. Similarly, various 2D images contain-ing depth values can be attached to the depth attachment point of an FBO. These can include a renderbuffer, a mip-level of a 2D texture or a cubemap face that stores depth values. The only 2D image that can be attached to the stencil attachment point of an FBO is a renderbuffer object that stores stencil values.

⼀个frameBuffer对象(通常被称为⼀个FBO)。是一个颜色、深度和模板缓存区附着点的集合。描述属性的状态,例如颜⾊、深度和模板缓存区的⼤⼩和格式,都关联到FBO(Frame Buffer Object)。并且纹理的名字和renderBuffer对象也都是关联于FBO。各种各样的2D图形能够被附着framebuffer对象的颜色附着点。它们包含了renderbuffer对象存储的颜色值、一个2D纹理或⽴⽅体贴图。或者一个mip-level的⼆维切面在3D纹理。同样,各种各样的2D图形包含了当时的深度值可以附加到⼀个FBO的深度附着点钟去。唯一的二维图像,能够附着在FBO的模板附着点,是一个renderbuffer对象存储模板值。

好吧, 这很晦涩难懂…
还是看图揣摩吧, 大致意思是RenderBuffer需要附着于FrameBuffer, FrameBuffer管理RenderBuffer, 需要先设置RenderBuffer, 然后和FramBuffer进行绑定操作, 后面的绘制才能起到作用

基本图形硬件流⽔线设计

应⽤用程序层 -> 硬件抽象层 -> 硬件层
应⽤用层: 游戏和应⽤用层软件开发⼈人员为主体,通过调⽤用API进行上层开发,不需要考虑移植性问题。
硬件抽象层: 抽象出硬件的加速功能,进行有利于应用层开发的封装,并向应用层提供开发API
硬件层: 将硬件驱动提供给抽象层,以实现抽象层加速功能的有效性。

shader

着色器。着⾊器其实就是一段在GPU运行的程序。我们平时的程序,是在CPU运行。由于GPU的硬件设计结构与CPU有着很⼤的不同,所以GPU需要一些新的编程语⾔.

渲染流水线分为两种,其中一种为可编程渲染流⽔线。另外一种为固定渲染流水线。(也称可编程管线或固定管线,管线就是流⽔线的意思)。渲染流水线可否编程,取决于程序猿能否在顶点着⾊器以及片段着色器上进行编码。⽽现在的渲染流水线,基本都是可编程的,当然,它们也支持固定渲染流⽔线的功能

渲染流⽔线的具体流程

1、应⽤层 :
在这⼀层,我们⽬前使⽤的是DirectX与OpenGL。对于这一部分,主要是一些API的调⽤
2、硬件抽象层 :
应⽤程序层主要与内存,CPU打交道,诸如碰撞检测,场景图监理,视锥裁剪等经典算法在此阶段执行。在阶段的末端,几何体的数据(顶点坐标,法向量,纹理坐标,纹理)等通过数据总线传送到图形硬件
3、硬件层 :
硬件层在渲染流水线中最为复杂,也最为重要。可编程渲染流⽔线与固定渲染流水线的区别在于是否对着⾊器进⾏编程。

⾸先我们先了解固定渲染流水线, 它主要分为以下⼏个阶段:
顶点变换 -> 图元转配与光栅化 -> ⽚段纹理映射和着色 -> 光栅化操作

硬件层—固定渲染管线流程图 :

硬件层—固定渲染管线流程图

光栅化(Rasterization):
将顶点数据转换为片元的过程, ⽚元中每个一个元素对于帧缓存区的一个像素;
光栅化其实是一个将⼏何图元变成一个二维图像的过程, 光栅化的过程就是为了产出⽚元

硬件层—可编程渲染流⽔水线流程图:

GPU图形渲染管线


应用程序阶段 :
主要是⾼级编程语言开发,如C,OC,C++
输出: 通过数据总线,把⼏何体的数据(顶点坐标\法线\纹理坐标\纹理)等传送到GPU上
几何阶段 :
输⼊: 应⽤程序末端的内容
负责任务: 顶点坐标变换,光照,裁剪,投影,屏幕映射
输出: 经过变换和投影之后的屏幕坐标,颜色,纹理坐标
光栅化阶段 :
参考前面的解释

为什么需要对三维空间的顶点进行坐标空间转换?

输⼊到计算机当中的是一系列三维坐标的点,但是我们看到的屏
幕是⼆维坐标点. 所以需要一系列的坐标转换:
ObjectSpace(物体空间/模型空间)-> WorldSpace(世界空
间)->EyeSpace(观察空间)->ClicpAndProjectSpace(屏幕空间)

CPU与GPU之间的关系

GPU具有⾼并行的结构,所以在处理图形数据和复杂算法时比CPU更加有效率


CPU在执行任务的时候,一个时刻只会处理一个数据,不存在真正意义上的并行,⽽GPU则有多个处理器核,在一个时刻可以并⾏处理多个数据

谢谢你赏我糖果吃