OpenGL ES 简介以及GLKit框架初探

一、OpenGL ES简介

OpenGL ES (OpenGL for Embedded Systems) 是以⼿持和嵌⼊式为⽬标的⾼级3D图形应⽤程序编程接⼝(API), OpenGL ES 是⽬前智能⼿机中占据统治地位的图形API;⽀持的平台: iOS, Andriod , BlackBerry ,bada ,Linux ,Windows。

  • 苹果官方文档
    The Open Graphics Library (OpenGL) is used for visualizing 2D and 3D data. It is a multipurpose open�standard graphics library that supports applications for 2D and 3D digital content creation, mechanical and architectural design, virtual prototyping, flight simulation, video games, and more. You use OpenGL to configure a 3D graphics pipeline and submit data to it. Vertices are transformed and lit, assembled into primitives, and rasterized to create a 2D image. OpenGL is designed to translate function calls into graphics commands that can be sent to underlying graphics hardware. Because this underlying hardware is dedicated to processing graphics commands, OpenGL drawing is typically very fast. OpenGL for Embedded Systems (OpenGL ES) is a simplified version of OpenGL that eliminates redundant
    functionality to provide a library that is both easier to learn and easier to implement in mobile graphics hardware.
    OpenGL ES 开放式图形库(OpenGL的)⽤于可视化的⼆维和三维数据。它是⼀个多功能开放标准图形库,⽀持2D和3D数字内
    容创建,机械和建筑设计,虚拟原型设计,⻜⾏模拟,视频游戏等应⽤程序。您可以使⽤OpenGL配置3D图形管道并向其提交数
    据。顶点被变换和点亮,组合成图元,并光栅化以创建2D图像。OpenGL旨在将函数调⽤转换为可以发送到底层图形硬件的图形命令。由于此底层硬件专⽤于处理图形命令,因此OpenGL绘图通常⾮常快。 OpenGL for Embedded Systems(OpenGL ES)是OpenGL的简化版本,它消除了冗余功能,提供了⼀个既易于学习⼜更易于在移动图形硬件中实现的库。
  • OpenGL ES运行流程图
    我们在Application中的代码调用OpenGL ES framework框架,然后通过OpenGL ES框架中的API来调用在GPU中的OpenGL ES Sever来实现的。
    截屏2020-07-27 15.53.28.png
  • 图形管线
    图形管线

    顶点数据从内存中拷贝到顶点缓存区来处理,处理完成后来到顶点着色器,然后进行图元装配,光栅化,再到片元着色器处理每一个对应的像素点,再进行逐片操作(把每一个片段的颜色保存起来),最后存在了我们的帧缓存区里。

  • 顶点着⾊器
    截屏2020-07-27 16.14.08.png

    1.顶点着色器是描述顶点上执⾏操作的顶点着⾊器程序源代码/可执⾏⽂件。
    2.顶点着⾊器输⼊(属性) 是⽤顶点数组提供每个顶点的数据。
    3.统⼀变量(uniform)—顶点/⽚元着⾊器使⽤的不变数据。
    4.采样器是代表顶点着⾊器使⽤纹理的特殊统⼀变量类型。

  • 顶点着⾊业务
    1.矩阵变换位置
    2.计算光照公式⽣成逐顶点颜⾊
    3.⽣成/变换纹理坐标
    总结: 它可以⽤于执⾏⾃定义计算,实施新的变换,照明或者传统的固定功能所不允许的基于顶点的效果。
  • 顶点着⾊代码案例
attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord; 
void main()
{
 varyTextCoord = textCoordinate; 
 vec4 vPos = position; 
 vPos = vPos * rotateMatrix; 
 gl_Position = vPos;
} 
  • 图元装配
    在顶点着色器完成任务后,下一个阶段是图元装配,图元(Primitive): 点,线,三⻆形等.
    图元装配: 将顶点数据计算成⼀个个图元,在这个阶段会执⾏裁剪、透视分割和Viewport变换操作。
    图元类型和顶点索确定将被渲染的单独图元。对于每个单独图元及其对应的顶点,图元装配阶段执⾏的操作包括:将顶点着⾊器的输出值执⾏裁剪、透视分割、视⼝变换后进⼊光栅化阶段。
  • 光栅化
    在这个阶段绘制对应的图元(点/线/三⻆形), 光栅化就是将图元转化成⼀组⼆维⽚段的过程,⽽这些转化的⽚段将由⽚元着⾊器处理,这些⼆维⽚段就是屏幕上可绘制的像素。
  • ⽚段着⾊器/⽚元着⾊器
    1.着⾊器程序—描述⽚段上执⾏操作的⽚元着⾊器程序源代码/可执⾏⽂件
    2.输⼊变量— 光栅化单元⽤插值为每个⽚段⽣成的顶点着⾊器输出
    3.统⼀变量(uniform)—顶点/⽚元着⾊器使⽤的不变数据
  1. 采样器—代表⽚元着⾊器使⽤纹理的特殊统⼀变量类型.
  • ⽚元着⾊器业务

    1. 计算颜⾊
    2. 获取纹理值
    3. 往像素点中填充颜⾊值(纹理值/颜⾊值);
      总结: 它可以⽤于图⽚/视频/图形中每个像素的颜⾊填充(⽐如给视频添加滤镜,实际上就是将视频中每个图⽚的像素点颜⾊填充进⾏修改。)
  • ⽚元着⾊代码案例:

varying lowp vec2 varyTextCoord; 
uniform sampler2D colorMap; 
void main()
{
 gl_FragColor = texture2D(colorMap, varyTextCoord);
} 
  • 逐⽚段操作
    截屏2020-07-27 17.03.35.png
    像素归属测试: 确定帧缓存区中位置(Xw,Yw)的像素⽬前是不是归属于OpenGL ES所 有. 例如,如果⼀个显示OpenGL ES帧缓存区View被另外⼀个View 所遮蔽.则窗⼝系统
    可以确定被遮蔽的像素不属于OpenGL ES 上下⽂.从⽽不全显示这些像素. ⽽像素归
    属测试是OpenGL ES 的⼀部分,它不由开发者开⼈为控制,⽽是由OpenGL ES 内部进⾏.
    裁剪测试: 裁剪测试确定(Xw,Yw)是否位于作为OpenGL ES状态的⼀部分裁剪矩形范围
    内.如果该⽚段位于裁剪区域之外,则被抛弃.
    深度测试: 输⼊⽚段的深度值进步⽐较,确定⽚段是否拒绝测试
    混合:混合将新⽣成的⽚段颜⾊与保存在帧缓存的位置的颜⾊值组合起来.
    抖动:抖动可⽤于最⼩化因为使⽤有限精度在帧缓存区中保存颜⾊值⽽产⽣的伪像.
  • EGL (Embedded Graphics Library )
    OpenGL ES 命令需要渲染上下⽂和绘制表⾯才能完成图形图像的绘制.
    渲染上下⽂:存储相关OpenGL ES 状态.
    绘制表⾯: 是⽤于绘制图元的表⾯,它指定渲染所需要的缓存区类型,例如颜⾊缓存区,深度缓冲区和模板缓存区。
    • OpenGL ES API 并没有提供如何创建渲染上下⽂或者上下⽂如何连接到原⽣窗⼝系统, EGL 是Khronos 渲染API(如OpenGL ES) 和原⽣窗⼝系统之间的接⼝。 唯⼀⽀持OpenGL ES 却不⽀持EGL 的平台是iOS.Apple 提供⾃⼰的EGL API的iOS实现,称为EAGL.
    因为每个窗⼝系统都有不同的定义,所以EGL提供基本的不透明类型—EGLDisplay, 这个类型封装了所有系统相关性,⽤于和原⽣窗⼝系统接⼝.

二、GLKit 框架

  • GLKit 框架概述
    GLKit 框架的设计⽬标是为了简化基于OpenGL / OpenGL ES 的应⽤开发. 。它的出现加快OpenGL ES或OpenGL应⽤程序开发。 使⽤数学库,背景纹理加载,预先创建的着⾊器效果,以及标准视图和视图控制器来实现渲染循环。GLKit框架提供了功能和类,可以减少创建新的基于着⾊器的应⽤程序所需的⼯作量,或者⽀持依赖早期版本的OpenGL ES或OpenGL提供的固定函数顶点或⽚段处理的现有应⽤程序。GLKView 提供绘制场所(View)、GLKViewController(扩展于标准的UIKit 设计模式. ⽤于绘制视图内容的管理与呈现.)苹果弃⽤OpenGL ES ,但iOS开发者可以继续使⽤。
  • GLKit和OpenGL相比较,它已经帮开发者封装好了方法我们只需要调用就行。
    截屏2020-07-27 17.21.23.png
  • 配置GLKit视图代码实现
- (void)viewDidLoad{
 [super viewDidLoad];
 //创建OpenGL ES上下⽂并将其分配给从故事板加载的视图
 GLKView * view =(GLKView *)self.view;
 view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
 //配置视图创建的渲染缓冲区
 view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
 view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
 view.drawableStencilFormat = GLKViewDrawableStencilFormat8;
 //启⽤多重采样
 view.drawableMultisample = GLKViewDrawableMultisample4X;
}
-(void)drawRect:(CGRect)rect
{
 //清除帧缓冲区
 glClearColor(0.0f,0.0f,0.1f,1.0f);
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//使⽤先前配置的纹理,着⾊器和顶点数组绘制
 glBindTexture(GL_TEXTURE_2D,_planetTexture);
 glUseProgram(_diffuseShading);
 glUniformMatrix4fv(_uniformModelViewProjectionMatrix,1,0,
_modelViewProjectionMatrix.m);
 glBindVertexArrayOES(_planetMesh);
 glDrawElements(GL_TRIANGLE_STRIP,256,GL_UNSIGNED_SHORT); } 

三、GLKit功能介绍

  • 能够为开发者提供哪些便利?
    加载纹理
    提供⾼性能的数学运算
    提供常⻅的着⾊器
    提供视图以及视图控制器

  • GLKTextureInfo 创建OpenGL 纹理信息
    name : OpenGL 上下⽂中纹理名称
    target : 纹理绑定的⽬标
    height : 加载的纹理⾼度
    width :加载纹理的宽度
    textureOrigin :加载纹理中的原点位置
    alphaState: 加载纹理中alpha分量状态
    containsMipmaps:布尔值,加载的纹理是否包含mip贴图
    1,初始化
    - initWithSharegroup:初始化⼀个新的纹理加载到对象中
    - initWithShareContext: 初始化⼀个新的纹理加载对象
    2,从⽂件中加载处理
    + textureWithContentsOfFile:options:errer:从⽂件加载2D纹理图像并从数据中创建新的纹理
    +textureWithContentsOfFile:options:queue:completionHandler:从⽂件中异步加载2D纹理图像,并根据数据创建新纹理GLTextureLoader 简化从各种资源⽂件中加载纹理。
    3,从URL加载纹理
    - textureWithContentsOfURL:options:error:从URL 加载2D纹理图像并从数据创建新纹理
    textureWithContentsOfURL:options:queue:completionHandler: 从URL异步加载2D纹理图像,并根据数据创建新纹理.
    4, 从内存中表示创建纹理
    + textureWithContentsOfData:options:errer:从内存空间加载2D纹理图像,并根据数据创建新纹理
    textureWithContentsOfData:options:queue:completionHandler:从内存空间异步加载2D纹理图像,并从数据中创建新纹理
    GLTextureLoader 简化从各种资源⽂件中加载纹理
    5, 从CGImages创建纹理
    - textureWithCGImage:options:error:从Quartz图像 加载2D纹理图像并从数据创建新纹理
    textureWithCGImage:options:queue:completionHandler:从Quartz图像异步加载2D纹理图像,并根据数据创建新纹理.
    6,从URL加载多维创建纹理
    + cabeMapWithContentsOfURL:options:errer: 从单个URL加载⽴⽅体贴图纹理图像,并根据数据创建新纹理
    cabeMapWithContentsOfURL:options:queue:completionHandler:从单个URL异步加载⽴⽅体贴图纹理图像,并根据数据创建新纹理
    7,从⽂件加载多维数据创建纹理
    + cubeMapWithContentsOfFile:options:errer:从单个⽂件加载⽴⽅体贴图纹理对象,并从数据中创建新纹理
    cubeMapWithContentsOfFile:options:queue:completionHandler:从单个⽂件异步加载⽴⽅体贴图纹理对象,并从数据中创建新纹理
    + cubeMapWithContentsOfFiles:options:errer: 从⼀系列⽂件中加载⽴⽅体贴图纹理图像,并从数据总创建新纹理
    cubeMapWithContentsOfFiles:options:options:queue:completionHandler:从⼀系列⽂件异步加载⽴⽅体贴图纹理图像,并从数据中创建新纹理

  • GLKView 使⽤OpenGL ES 绘制内容的视图默认实现
    • 初始化视图
    - initWithFrame:context:初始化新视图
    • 代理
    delegate 视图的代理
    • 配置帧缓存区对象
    drawableColorFormat 颜⾊渲染缓存区格式
    drawableDepthFormat 深度渲染缓存区格式
    drawableStencilFormat 模板渲染缓存区的格式
    drawableMultisample 多重采样缓存区的格式
    • 帧缓存区属性
    drawableHeight 底层缓存区对象的⾼度(以像素为单位)
    drawableWidth 底层缓存区对象的宽度(以像素为单位)
    • 绘制视图的内容
    context 绘制视图内容时使⽤的OpenGL ES 上下⽂
    - bindDrawable 将底层FrameBuffer对象绑定到OpenGL ES
    enableSetNeedsDisplay 布尔值,指定视图是否响应使得视图内容⽆效的消息
    - display ⽴即重绘视图内容
    snapshot 绘制视图内容并将其作为新图像对象返回
    • 删除视图FrameBuffer对象
    - deleteDrawable 删除与视图关联的可绘制对象

  • 绘制视图的内容GLKViewDelegate⽤于GLKView 对象回调⽅法
    - glkView:drawInRect: 绘制视图内容 (必须实现代理)
    • 更新
    - (void) update 更新视图内容
    - (void) glkViewControllerUpdate:
    • 配置帧速率
    preferredFramesPerSecond 视图控制器调⽤视图以及更新视图内容的速率
    framesPerSencond 视图控制器调⽤视图以及更新其内容的实际速率
    • 配置GLKViewController 代理
    delegate 视图控制器的代理
    • 控制帧更新
    paused 布尔值,渲染循环是否已暂停
    pausedOnWillResignActive布尔值,当前程序重新激活活动状态时视图控制器是否⾃动暂停渲染循环
    resumeOnDidBecomeActive布尔值,当前程序变为活动状态时视图控制是否⾃动恢复呈现循环

  • 获取有关View 更新信息
    frameDisplayed视图控制器⾃创建以来发送的帧更新数
    timeSinceFirstResume⾃视图控制器第⼀次恢复发送更新事件以来经过的时间量
    timeSinceLastResume ⾃上次视图控制器恢复发送更新事件以来更新的时间量
    timeSinceLastUpdate⾃上次视图控制器调⽤委托⽅法以及经过的时间量
    glkViewControllerUpdate:
    timeSinceLastDraw⾃上次视图控制器调⽤视图display ⽅法以来经过的时间量.

• 处理更新事件GLKViewControllerDelegate 渲染循环回调⽅法
- glkViewControllerUpdate: 在显示每个帧之前调⽤
• 暂停/恢复通知
- glkViewController : willPause:在渲染循环暂停或恢复之前调⽤.

  • GLKBaseEffect ⼀种简单光照/着⾊系统,⽤于基于着⾊器OpenGL 渲染
    命名Effect
    label 给Effect(效果)命名
    配置模型视图转换
    transform绑定效果时应⽤于顶点数据的模型视图,投影和纹理变换
    • 配置光照效果
    lightingType ⽤于计算每个⽚段的光照策略
    GLKLightingTypePerVertex 表示在三⻆形中每个顶点执⾏光照计算,然后在三⻆形进⾏插值
    GLKLightingTypePerPixel表示光照计算的输⼊在三⻆形内插⼊,并且在每个⽚段执⾏光照计算

  • 配置光照
    lightModelTwoSided布尔值,表示为基元的两侧计算光照
    material计算渲染图元光照使⽤的材质属性
    lightModelAmbientColor环境颜⾊,应⽤效果渲染的所有图元.
    light0场景中第⼀个光照属性
    light1 场景中第⼆个光照属性
    light2 场景中第三个光照属性

  • 配置纹理
    texture2d0第⼀个纹理属性
    texture2d1第⼆个纹理属性
    textureOrder 纹理应⽤于渲染图元的顺序

  • 配置雾化
    fog 应⽤于场景的雾属性

  • 配置颜⾊信息
    colorMaterialEnable布尔值,表示计算光照与材质交互时是否使⽤颜⾊顶点属性
    useConstantColor布尔值,指示是否使⽤常量颜⾊
    constantColor不提供每个顶点颜⾊数据时使⽤常量颜⾊

  • 准备绘制效果
    - prepareToDraw 准备渲染效果

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335