繁体   English   中英

使用GLKit进行按需OpenGL ES渲染

[英]On-demand OpenGL ES rendering using GLKit

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

这种类型的设置是否有推荐的方法? 我希望有类似的东西:

  • 将视图控制器的preferredFramesPerSecond0 ,或者只是暂停帧更新?
  • 忽略glkViewControllerUpdateglkView: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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM