18

我正在考虑转换我的 OpenGL 渲染代码以利用的一些功能GLKit(即异步纹理加载和由 提供的自动化GLKView/Controller)。但是,这些类似乎主要是为了适应人们使用动画循环进行渲染而设计的,而我正在使用按需渲染。此外,一些渲染是针对纹理而不是 GLKView 的帧缓冲区,所以我是否应该只寻找 GLKView 的子类并添加额外的 FBO?

这种设置有推荐的方法吗?我会期待一些类似的东西:

  • 将视图控制器设置preferredFramesPerSecond0,或者只是暂停帧更新?
  • 忽略glkViewControllerUpdateorglkView:drawInRect:方法,只在需要时绘制我需要的东西。
  • 将视图setNeedsDisplay与法线一起使用UIView以显示框架(bindDrawable鉴于我也将渲染到纹理,我是否需要调用?)。

如果这不是新 API 的设计目的,也许不值得付出努力?我希望文档比它更彻底。当 API 稍微“成熟”一点时,也许会提供更多示例......

谢谢

4

3 回答 3

24

我最终使用的方法是不打扰GLKViewController,而只是GLKView直接在UIViewController子类下使用。

显然,GLKViewController它适用于需要为游戏等应用程序提供一致渲染循环的人。没有它,绘制到GLKView就像调用一样简单[glkView setNeedsDisplay]。请务必设置enableSetNeedsDisplayYES以启用此行为。

如果您仍然想使用 a GLKViewController,您可以像这样禁用动画渲染循环viewWillAppear

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];    // setPaused automatically set to NO in super's implementation

    [self setPaused:YES];
}

此外,设置resumeOnDidBecomeActiveNO防止视图控制器再次自动恢复。

UIViewController然而,使用带有a 的平面GLKView是完全可以接受的,我已经看到 Apple 工程师推荐它作为执行按需绘图的合适方式。

于 2011-11-08T03:59:58.590 回答
3

我刚刚将我的代码从使用 EAGLContext 管理器转换为使用 GLKit 类。

您建议您可以“..忽略..glkView:drawInRect:方法,并在我需要的时候画出[您]需要的东西”。从性能上看,这似乎是一个明智的选择;我假设(虽然没有尝试过)如果你只是不指定 aGLKViewDelegate或提供一个定义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,请告诉我情况如何。

于 2011-10-22T16:53:11.157 回答
1

创建 GLKView 后,添加以下行:

glkView.enableSetNeedsDisplay = TRUE;

(正因为如此,没有人会自动重绘视图)

当你想重绘时,插入这一行:

[glkView setNeedsDisplay];

...然后drawInRect例程将只被调用一次。

希望能帮助到你。

于 2011-11-07T22:41:24.210 回答