002-GLKView是如何工作的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了002-GLKView是如何工作的相关的知识,希望对你有一定的参考价值。

参考技术A 这篇文章是对 OpenGL ES之绘制三角形(一) 的补充解释, 在这篇文章里会解释苹果封装的GLKView帮我们做了哪些工作? GLKView是如何工作的?

CAEAGLLayer 和GLKView之间的关系就如同UIView和CALayer之间的关系, GLKView是对CAEAGLLayer的封装, 简化了我们使用Core Animation去渲染OpenGL ES的步骤.

Core Animation 是ios上图形渲染和动画的核心基础, OpenGL ES通过CAEAGLLayer该类连接到Core Animation ,这是一种特殊类型的Core Animation层,其内容来自OpenGL ES renderbuffer。Core Animation将renderbuffer的内容与其他图层复合,并在屏幕上显示生成的图像。

CAEAGLLayer提供的两项主要功能,首先,它为renderbuffer分配共享存储。其次,它将渲染缓冲区呈现给Core Animation,用renderbuffer中的数据替换了以前的内容。该模型的一个优点是,只有当渲染的图像更改时,Core Animation图层的内容不需要在每个帧中绘制。

使用Core Animation 渲染OpenGL ES步骤

glGenFramebuffers() 需要2个参数; 第一个是要创建的帧缓冲区的数量,第二个参数是指向GLuint变量或数组以存储单个ID或多个ID的指针。
当不再使用glDeleteFramebuffers()时,FBO可能会被删除。

创建FBO后,必须先绑定FBO。
glBindFramebuffer() 第一个参数target为GL_FRAMEBUFFER,第二个参数为framebuffer对象的ID。一旦绑定FBO,所有OpenGL操作都会影响当前绑定的帧缓冲区对象。对象ID 0保留给默认的窗口系统提供的帧缓冲区。因此,为了取消绑定当前帧缓冲区(FBO),请在glBindFramebuffer()中使用ID 0。

通过调用上下文的 renderbufferStorage:fromDrawable: 方法并传递层对象作为参数来分配其存储空间。宽度,高度和像素格式取自层,用于为renderbuffer分配存储空间。

renderbuffer对象是新引入的用于屏幕外渲染。它允许将场景直接渲染到renderbuffer对象,而不是渲染到纹理对象。Renderbuffer只是一个包含可渲染内部格式的单个映像的数据存储对象。它用于存储没有相应纹理格式的OpenGL逻辑缓冲区,例如模板或深度缓冲区。

与FBO一样, 需要先创建 glGenRenderbuffers ,然后绑定 glBindRenderbuffer

当创建一个renderbuffer对象时,它没有任何数据存储,所以我们必须为它分配一个内存空间。这可以通过使用glRenderbufferStorage()来完成。第一个参数必须是GL_RENDERBUFFER。第二个参数是彩色渲染(GL_RGB,GL_RGBA等),深度可渲染(GL_DEPTH_COMPONENT)或模板可渲染格式(GL_STENCIL_INDEX)。width和height是以像素为单位的renderbuffer图像的尺寸。

宽度和高度应小于GL_MAX_RENDERBUFFER_SIZE,否则会生成GL_INVALID_VALUE错误。

FBO本身没有任何图像存储(缓冲区)。相反,我们必须在FBO上附加framebuffer可附加的图像(纹理或renderbuffer对象)。该机制允许FBO快速切换(分离和附加)FBO中的可帧缓冲附件的图像。切换帧缓冲附加图像比在FBO之间切换要快得多。并且,它可以节省不必要的数据副本和内存消耗。例如,纹理可以附加到多个FBO,并且其图像存储可以被多个FBO共享。

将一个Renderbuffer图像附加到FBO

可以通过调用glFramebufferRenderbuffer()来附加renderbuffer映像。第一个参数必须是GL_FRAMEBUFFER,第二个参数是连接纹理图像的 连接点 。FBO有多个颜色附加点(GL_COLOR_ATTACHMENT0,...,GL_COLOR_ATTACHMENT n),GL_DEPTH_ATTACHMENT和GL_STENCIL_ATTACHMENT。。第三个参数必须是GL_RENDERBUFFER,最后一个参数是renderbuffer对象的ID。

有两种类型的帧缓冲可附加图像; 纹理图像和renderbuffer图像。如果纹理对象的图像附加到帧缓冲区,则OpenGL会执行“渲染到纹理”。如果renderbuffer对象的图像附加到帧缓冲区,则OpenGL将执行“屏幕外渲染”。

下图显示了framebuffer对象,纹理对象和renderbuffer对象之间的连接。多个纹理对象或renderbuffer对象可以通过附件点附加到framebuffer对象。

帧缓冲对象中 有多个颜色附加点(GL_COLOR_ATTACHMENT0,...,GL_COLOR_ATTACHMENT n),一个深度附加点(GL_DEPTH_ATTACHMENT)和一个模板附加点(GL_STENCIL_ATTACHMENT)。颜色连接点的数量取决于实现,但每个FBO必须至少具有一个颜色附加点。您可以使用GL_MAX_COLOR_ATTACHMENTS查询最大数量的颜色附加点,这是由显卡支持的。FBO具有多个颜色附加点的原因是允许在同一时间将颜色缓冲区渲染到多个目的地。这个“多个渲染目标”(MRT)可以通过GL_ARB_draw_buffers扩展来完成。

创建一个深度或深度/模板的渲染缓冲区,为其分配存储空间,并将其附加到framebuffer的深度附件点。

一旦可连接的图像(纹理和渲染缓冲区)附加到FBO并且在执行FBO操作之前,必须使用glCheckFramebufferStatus()验证FBO状态是完整还是不完整。如果FBO不完整,则任何绘图和读取命令(glBegin(),glCopyTexImage2D()等)将失败。

glCheckFramebufferStatus()验证当前绑定的FBO上的所有附加图像和帧缓冲区参数。而且,这个函数不能在glBegin()/ glEnd()对中调用。目标参数应为GL_FRAMEBUFFER。检查FBO后返回非零值。如果满足所有要求和规则,则返回GL_FRAMEBUFFER_COMPLETE。否则,它返回一个相关的错误值,它告诉什么规则被违反。

通过将CAEAGLLayer对象传递给addSublayer:可见层的方法,将对象添加到Core Animation层次结构中。

至此, 就实现了一个自定义的GLKView.
当你想在一个视图的内容层的OpenGL ES绘制是应该使用GLKView, 而不是CAEAGLLayer

在 UIViewController 内部集成 UIView 和 GLKView

【中文标题】在 UIViewController 内部集成 UIView 和 GLKView【英文标题】:Integrate UIView and GLKView inside of UIViewController 【发布时间】:2012-04-19 08:24:49 【问题描述】:

我使用 Xcode 4.3.2 和 iOS SDK 5.1。

我想在我的故事板中创建一个视图控制器,其中包含半屏上的 GLKView 和另一半屏上的 Buttons + Text。

我尝试将两者都放在 UIViewController 中,但可以让它工作。

有什么想法吗?文章?教程?

【问题讨论】:

【参考方案1】:

在 UIViewController 中创建 GLKViewController 的实例,现在将 GLKViewController 添加为子视图控制器,并将 GLKView 作为子视图添加到 UIViewController

【讨论】:

【参考方案2】:

我会遵循的方法是:

    照常创建您的GLKView/GLKViewController

    将包含按钮和文本的 UIView 添加为 GLKView 的子视图。

我会以编程方式在GLKViewControllerviewDidLoad 方法中执行第二步。

【讨论】:

这不是我真正需要的,因为子视图将覆盖我的 opengl 场景。但场景应该是屏幕的一半。想法?

以上是关于002-GLKView是如何工作的的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI中的GLKView?

在 UIView 或 GLKView 上绘图?

为啥在 ViewDidLoad 中没有设置 GLKView 的 DrawableWidth?

在UI视图顶部的OpenGL GLKView覆盖 - iOS / Xcode

在 GLKView 类型的对象上找不到属性“层”

MT5211:本机链接失败,未定义的Objective-C类