我正在研究转换我的OpenGL渲染代码以利用GLKit
的一些功能(即异步纹理加载和GLKView/Controller
提供的自动化)。但是,似乎这些类的设计主要是为了适应使用动画循环渲染的人,而我正在使用按需渲染。另外,一些渲染是针对纹理而不是GLKView的帧缓冲,所以我是否应该只是将GLKView子类化并添加其他FBO?
这种类型的设置是否有推荐的方法?我期待的是:
preferredFramesPerSecond
设置为0
,或者只是
暂停框架更新?glkViewControllerUpdate
或glkView:drawInRect:
方法
当我需要它时,只需画出我需要的东西。setNeedsDisplay
和普通UIView
显示框架(我需要调用bindDrawable
给我
也会渲染到纹理?)。如果这不是新API的设计,那么也许不值得努力?我希望文档比它更彻底。当API稍微“成熟”时,可能会提供更多样本......
由于
答案 0 :(得分:23)
我最终使用的方法是不打扰GLKViewController
,而只是直接在GLKView
子类下使用UIViewController
。
显然,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
以防止视图控制器再次自动恢复。
使用普通UIViewController
和GLKView
是完全可以接受的,我已经看到Apple工程师推荐它作为执行按需绘图的适当方式。
答案 1 :(得分:3)
我刚刚使用EAGLContext管理器将我的代码转换为使用GLKit类。
你建议你可以“.. {。glkView:drawInRect:
方法,并在我需要的时候画出你需要的东西”。这似乎是表现明智的明智选择;我假设(虽然没有尝试过)如果你只是没有指定GLKViewDelegate
或者提供一个定义了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,请告诉我。
答案 2 :(得分:1)
创建GLKView后,添加以下行:
glkView.enableSetNeedsDisplay = TRUE;
(因此,没有人会自动重绘视图)
如果要重绘,请插入以下行:
[glkView setNeedsDisplay];
...然后drawInRect
例程将只被调用一次。
希望它有所帮助。