iOS开发-OpenGLES进阶教程4

教程

OpenGLES入门教程1-Tutorial01-GLKit
OpenGLES入门教程2-Tutorial02-shader入门
OpenGLES入门教程3-Tutorial03-三维变换
OpenGLES入门教程4-Tutorial04-GLKit进阶
OpenGLES进阶教程1-Tutorial05-地球月亮
OpenGLES进阶教程2-Tutorial06-光线
OpenGLES进阶教程3-Tutorial07-粒子效果
这一次的内容是帧缓存。

概要

帧缓存:接收渲染结果的缓冲区叫做帧缓存。
在OpenGL的渲染管道中,几何数据和纹理通过一系列变换和测试后,变成渲染到屏幕上的二维像素。渲染的目标管道就是帧缓存区。

(In OpenGL rendering pipeline, the geometry data and textures are transformed and passed several tests, and then finally rendered onto a screen as 2D pixels. The final rendering destination of the OpenGL pipeline is calledframebuffer)

每一个iOS原生控件都有一个对应的CoreAnimation层。
CoreAnimation合成器使用OpenGL ES来尽可能高效地控制GPU、混合层和切换帧缓存。
思考:OpenGL ES的渲染结果会放到帧缓存区,如何与视图的显示联系起来?

效果展示

核心思路

如下图,帧缓存像素颜色的输出结果在GL_COLOR_ATTATCHMENT开头的缓存区。
首先,我们用一个纹理缓存来作为OpenGL ES的第一次输出的缓存区,这样我们可以得到一个纹理Texture0。
然后用Texture0作为第二次绘制的纹理,得到最后的结果。

OpenGL的帧缓存

具体细节

  • 弯路

在实现过程中,走过了几个弯路,先提出来,希望后来者不要再重复:

  • 新建上下文。
    因为需要拿到第一次渲染的结果-纹理Texture0,就想尝试新建上下文mExtraContext来渲染纹理,然后用原来的上下文mBaseContext来进行接收纹理和渲染。
    结果是两个上下文是相互独立的,mExtraContext渲染出来的结果并不能在mBaseContext使用。

  • 使用同一个GLKBaseEffect来渲染纹理Texture0和渲染最后结果。

  • 在渲染纹理Texture0的时候使用不同的视口大小,但是没有调用glviewport()。

  • 把纹理对象关联到帧缓存

1、新建纹理
2、设置纹理格式
3、分配纹理内存
4、新建帧缓存
5、切换帧缓存为纹理对象

GLuint colorTexture;
// 1
glGenTextures(1, &colorTexture);
glBindTexture(GL_TEXTURE_2D, colorTexture);

// 2
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
                GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
                GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                GL_LINEAR_MIPMAP_LINEAR);

// 3
glTexImage2D(GL_TEXTURE_2D,
             0,
             GL_RGBA,
             fboWidth,
             fboHeight,
             0,
             GL_RGBA,
             GL_UNSIGNED_BYTE,
             NULL);

//4
glGenFramebuffers(1, &fboName);
glBindFramebuffer(GL_FRAMEBUFFER, fboName);
//5
glFramebufferTexture2D(GL_FRAMEBUFFER,
                       GL_COLOR_ATTACHMENT0,
                       GL_TEXTURE_2D, colorTexture, 0);
  • 渲染缓存关联到帧缓存

1、新建渲染缓存
2、分配渲染内存
3、新建帧缓存
4、切换帧缓存为渲染缓存

//1
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
//2
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, viewport[2],viewport[3]);

//3
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
//4
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);

结果解析

先渲染里面锥体,得到的结果作为纹理,进行第二次绘制。观察简化版,下图正方形白色区域为渲染后的纹理。


Paste_Image.png

原图如下。被渲染到一个纹理后,再被显示到屏幕上。


思考

答案:CAEGLayer
OpenGL ES会有连接到层,与层分享数据的帧缓存,至少包括一个像素颜色渲染缓存。
CAEAGLLyaer是CoreAnimation提供的标准层类之一,与OpenGL ES的帧缓存共享它的像素颜色仓库。
与一个Core Animation共享内存的像素颜色渲染缓存在层调整大小时会自动调整大小。其他缓存,例如深度缓存,不会自动调整大小。可以在layoutSubviews方法里面删除现存的深度缓存,并创建一个新的与像素颜色渲染缓存的新尺寸相匹配的深度缓存。

总结

这个demo不难,但是很考验对帧缓存的理解。上面的弯路还有包括多个顶点数组、GLKBaseEffect和shader混用等,本来是打算用shader来实现,但是iOS卷 推荐熟练使用GLKBaseEffect,最后还是用的GLKBaseEffect。
学习OpenGL ES对了解iOS的性能优化很有帮助。
现在再看上面那个图,会有不一样的认知。
参考帧缓存
这里有源码

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

推荐阅读更多精彩内容