使用 GLKit 进行按需 OpenGL ES 渲染
我正在考虑转换我的 OpenGL 渲染代码,以利用 GLKit 的一些功能(即异步纹理加载和 GLKView/Controller 提供的自动化)。然而,这些类的设计似乎主要是为了适应人们使用动画循环进行渲染,而我正在使用按需渲染。此外,一些渲染是针对纹理而不是 GLKView 的帧缓冲区,所以我是否应该只考虑子类化 GLKView 并添加额外的 FBO?
对于这种类型的设置有推荐的方法吗?我期望的内容如下:
- 将视图控制器的
preferredFramesPerSecond
设置为0
,或者只是 暂停帧更新? - 忽略
glkViewControllerUpdate
或glkView:drawInRect:
方法 当我需要的时候,就画出我需要的东西。 - 按顺序使用视图的
setNeedsDisplay
与普通UIView
一样 显示框架(鉴于我,我是否需要调用bindDrawable
也会渲染到纹理吗?)。
如果这不是新 API 的设计目的,也许就不值得付出努力?我希望文档比现在更全面一些。当API“成熟”一点时,也许会提供更多示例......
谢谢
I am looking into converting my OpenGL rendering code to take advantage of a few features of GLKit
(namely the asynchronous texture loading and the automation provided by GLKView/Controller
). However, it appears that the classes are designed mainly to accommodate people rendering using an animation loop, whereas I'm working with on-demand rendering. Additionally, some of the rendering is to a texture rather than the GLKView's framebuffer, so should I be looking to just subclass the GLKView and add additional FBOs?
Is there a recommended approach for this type of setup? I would expect something along the lines of:
- Set the view controller's
preferredFramesPerSecond
to0
, or just
pause the frame updates? - Ignore the
glkViewControllerUpdate
orglkView:drawInRect:
methods
and just draw what I need, when I need it. - Use the view's
setNeedsDisplay
as with a normalUIView
in order
to display the frame (do I need to callbindDrawable
given that I
will be rendering to a texture as well?).
Perhaps it's not worth the effort if this is not what the new API is designed for? I wish the documentation was a little more thorough than it is. Perhaps more samples will be provided when the API has 'matured' a little...
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
创建 GLKView 后,添加这一行:
glkView.enableSetNeedsDisplay = TRUE;
(因此,没有人会自动重绘视图)
当您想要重绘时,插入这一行:
... then < code>drawInRect 例程将仅被调用一次。
希望有帮助。
After you have created GLKView, add this line:
glkView.enableSetNeedsDisplay = TRUE;
(Because of this, no one will redraw the view automatically)
When you want redraw, insert this line:
... then
drawInRect
routine will be called only once.Hope it helps.
我最终使用的方法是不使用 GLKViewController ,而是直接在 UIViewController 子类下使用 GLKView 。
显然,GLKViewController 适合需要游戏等应用程序一致渲染循环的人们使用。如果没有它,绘制到
GLKView
就像调用[glkView setNeedsDisplay]
一样简单。请务必将enableSetNeedsDisplay
设置为YES
以启用此行为。如果您仍然想使用
GLKViewController
,您可以在viewWillAppear
中禁用动画渲染循环,如下所示:另外,将
resumeOnDidBecomeActive
设置为NO
以防止视图控制器再次自动恢复。然而,使用普通的
UIViewController
和GLKView
是完全可以接受的,而且我看到 Apple 工程师推荐它作为执行按需绘图的适当方法。The approach I ended up using was to not bother with the
GLKViewController
, but just useGLKView
directly under aUIViewController
subclass.Clearly, the
GLKViewController
is intended for use by people who need a consistent rendering loop for apps such as games. Without it, drawing to theGLKView
is as simple as calling[glkView setNeedsDisplay]
. Be sure to setenableSetNeedsDisplay
toYES
in order to enable this behaviour.If you did still want to make use of a
GLKViewController
, you can disable the animation rendering loop inviewWillAppear
like so:Also, set
resumeOnDidBecomeActive
toNO
to prevent the view controller from resuming again automatically.Using a plain
UIViewController
with aGLKView
is perfectly acceptable however, and I have seen it recommended by an Apple engineer as an appropriate way to perform on-demand drawing.我刚刚将我的代码从使用 EAGLContext 管理器转换为使用 GLKit 类。
您建议您可能“..忽略..
glkView:drawInRect:
方法,只在我需要时绘制[您]需要的内容”。从性能角度来看,这似乎是一个明智的选择;我假设(虽然没有尝试过)如果您只是不指定GLKViewDelegate
或提供一个子类GLKView
及其定义的drawInRect:
然后不会发生动画循环渲染。你尝试过这个吗?另一种方法是简单地在您的
MyController : GLKViewController
类中创建一些@property (assign, nonatomic) BOOL shouldUpdate;
,该类仅在有某些内容时才会更新要做的事:我相信您已经明白了,这并不复杂。
值得一提的是:官方 API 文档指出,应在
GLKViewController
中使用viewDidLoad
进行初始 GL 设置。我对此有疑问;由于某种原因,我的glCreateShader
调用始终返回零。这可能是由于我在初始化后设置了EAGLContext
;由于我在 Storyboard 中创建了控制器,因此无法将其作为init
参数传递。然而,代码在逻辑上没有任何错误,所以我提供这个友好的警告,以防您遇到类似的问题。我的解决方案只是在我的drawInRect 中添加以下内容:显然,不必要地在其中添加 IF 并不理想,但这是一个简单的解决方案。
如果您尝试更新以使用 GLKit,请告诉我情况如何。
I've just converted my code from using an EAGLContext manager I rolled myself to using the GLKit classes.
You suggest you might "..ignore the..
glkView:drawInRect:
methods and just draw what [you] need, when I need it". This seems like a sensible option performance-wise; I assume (though haven't tried) if you simply don't specify aGLKViewDelegate
or provide a subclassedGLKView
with itsdrawInRect:
defined then no animation loop rendering will occur. Have you attempted this?The alternative would be to simply create some
@property (assign, nonatomic) BOOL shouldUpdate;
in yourMyController : GLKViewController <GLKViewDelegate>
class which will only update if there is something to do:I'm sure you get the idea, it's hardly complicated.
One thing worth mentioning: the official API docs state that
viewDidLoad
should be used in yourGLKViewController
for initial GL setup. I had issues with this; for some reason myglCreateShader
calls always returned zero. This may have been due to my setting theEAGLContext
post-initialisation; I couldn't pass it as aninit
parameter since I created the controller in Storyboard. However, there was nothing logically wrong with the code, so I offer this friendly warning in case you encounter similar issues. My solution is simply to have the following in my drawInRect:Obviously it's not ideal to have an IF in there unnecessarily, but it was an easy solution.
Let me know how it goes if you try updating to use GLKit.