[英]On-demand OpenGL ES rendering using GLKit
我正在研究转换我的OpenGL渲染代码以利用GLKit
的一些功能(即异步纹理加载和GLKView/Controller
提供的自动化)。 但是,似乎这些类的设计主要是为了适应使用动画循环渲染的人,而我正在使用按需渲染。 另外,一些渲染是针对纹理而不是GLKView的帧缓冲,所以我是否应该只是将GLKView子类化并添加其他FBO?
这种类型的设置是否有推荐的方法? 我希望有类似的东西:
preferredFramesPerSecond
为0
,或者只是暂停帧更新? glkViewControllerUpdate
或glkView:drawInRect:
方法,只需在需要时绘制我需要的东西。 setNeedsDisplay
和普通的UIView
一起显示框架(我是否需要调用bindDrawable
因为我也将渲染到纹理?)。 如果这不是新API的设计,那么也许不值得努力? 我希望文档比它更彻底。 当API稍微“成熟”时,可能会提供更多样本......
谢谢
我最终使用的方法是不打扰GLKViewController
,而只是直接在UIViewController
子类下使用GLKView
。
显然, GLKViewController
旨在供那些需要为游戏等应用程序提供一致渲染循环的人使用。 没有它,绘制到GLKView
就像调用[glkView setNeedsDisplay]
一样简单。 请务必将enableSetNeedsDisplay
设置为YES
以启用此行为。
如果您仍想使用GLKViewController
,则可以在viewWillAppear
禁用动画渲染循环,如下所示:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated]; // setPaused automatically set to NO in super's implementation
[self setPaused:YES];
}
另外,将resumeOnDidBecomeActive
设置为NO
以防止视图控制器自动重新开始。
然而,使用带有GLKView
的普通UIViewController
是完全可以接受的,我已经看到Apple工程师推荐它作为执行按需绘图的适当方式。
我刚刚使用EAGLContext管理器将我的代码转换为使用GLKit类。
你建议你可以“.. glkView:drawInRect:
.. glkView:drawInRect:
方法,只需要在我需要的时候画出你需要的东西”。 这似乎是表现明智的明智选择; 我假设(虽然没有尝试过)如果你只是没有指定GLKViewDelegate
或者提供带有drawInRect:
的子类GLKView
drawInRect:
定义那么就不会发生动画循环渲染。 你试过这个吗?
另一种方法是简单地创建一些@property (assign, nonatomic) BOOL shouldUpdate;
在你的MyController : GLKViewController <GLKViewDelegate>
类中,只有在有事情要做时才会更新:
[self setDelegate:self]; // in init or awakeFromNib or other..
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
if ([self shouldUpdate]) { ...
我相信你明白了,这并不复杂。
值得一提的是:官方API文档声明viewDidLoad
应该在您的GLKViewController
用于初始GL设置。 我有这个问题; 由于某种原因,我的glCreateShader
调用总是返回零。 这可能是由于我设置EAGLContext
后初始化; 我无法将其作为init
参数传递,因为我在Storyboard中创建了控制器。 但是,代码没有任何逻辑上的错误,所以如果您遇到类似问题,我会提供此友好警告。 我的解决方案只是在我的drawInRect中有以下内容:
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
if ([self initialGLSetupDone] == NO) {
[self beforeFirstRender];
[self setInitialGLSetupDone:YES];
}
// .. rest of render code goes here.
}
显然,不必要地在那里安装IF并不理想,但这是一个简单的解决方案。
如果您尝试更新以使用GLKit,请告诉我它是怎么回事。
创建GLKView后,添加以下行:
glkView.enableSetNeedsDisplay = TRUE;
(因此,没有人会自动重绘视图)
如果要重绘,请插入以下行:
[glkView setNeedsDisplay];
...然后drawInRect
例程将只调用一次。
希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.