简体   繁体   English

使用GLKit进行按需OpenGL ES渲染

[英]On-demand OpenGL ES rendering using GLKit

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 ). 我正在研究转换我的OpenGL渲染代码以利用GLKit的一些功能(即异步纹理加载和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? 另外,一些渲染是针对纹理而不是GLKView的帧缓冲,所以我是否应该只是将GLKView子类化并添加其他FBO?

Is there a recommended approach for this type of setup? 这种类型的设置是否有推荐的方法? I would expect something along the lines of: 我希望有类似的东西:

  • Set the view controller's preferredFramesPerSecond to 0 , or just pause the frame updates? 将视图控制器的preferredFramesPerSecond0 ,或者只是暂停帧更新?
  • Ignore the glkViewControllerUpdate or glkView:drawInRect: methods and just draw what I need, when I need it. 忽略glkViewControllerUpdateglkView:drawInRect:方法,只需在需要时绘制我需要的东西。
  • Use the view's setNeedsDisplay as with a normal UIView in order to display the frame (do I need to call bindDrawable given that I will be rendering to a texture as well?). 使用视图的setNeedsDisplay和普通的UIView一起显示框架(我是否需要调用bindDrawable因为我也将渲染到纹理?)。

Perhaps it's not worth the effort if this is not what the new API is designed for? 如果这不是新API的设计,那么也许不值得努力? 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... 当API稍微“成熟”时,可能会提供更多样本......

Thanks 谢谢

The approach I ended up using was to not bother with the GLKViewController , but just use GLKView directly under a UIViewController subclass. 我最终使用的方法是不打扰GLKViewController ,而只是直接在UIViewController子类下使用GLKView

Clearly, the GLKViewController is intended for use by people who need a consistent rendering loop for apps such as games. 显然, GLKViewController旨在供那些需要为游戏等应用程序提供一致渲染循环的人使用。 Without it, drawing to the GLKView is as simple as calling [glkView setNeedsDisplay] . 没有它,绘制到GLKView就像调用[glkView setNeedsDisplay]一样简单。 Be sure to set enableSetNeedsDisplay to YES in order to enable this behaviour. 请务必将enableSetNeedsDisplay设置为YES以启用此行为。

If you did still want to make use of a GLKViewController , you can disable the animation rendering loop in viewWillAppear like so: 如果您仍想使用GLKViewController ,则可以在viewWillAppear禁用动画渲染循环,如下所示:

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

    [self setPaused:YES];
}

Also, set resumeOnDidBecomeActive to NO to prevent the view controller from resuming again automatically. 另外,将resumeOnDidBecomeActive设置为NO以防止视图控制器自动重新开始。

Using a plain UIViewController with a GLKView is perfectly acceptable however, and I have seen it recommended by an Apple engineer as an appropriate way to perform on-demand drawing. 然而,使用带有GLKView的普通UIViewController是完全可以接受的,我已经看到Apple工程师推荐它作为执行按需绘图的适当方式。

I've just converted my code from using an EAGLContext manager I rolled myself to using the GLKit classes. 我刚刚使用EAGLContext管理器将我的代码转换为使用GLKit类。

You suggest you might "..ignore the.. glkView:drawInRect: methods and just draw what [you] need, when I need it". 你建议你可以“.. glkView:drawInRect: .. glkView:drawInRect:方法,只需要在我需要的时候画出你需要的东西”。 This seems like a sensible option performance-wise; 这似乎是表现明智的明智选择; I assume (though haven't tried) if you simply don't specify a GLKViewDelegate or provide a subclassed GLKView with its drawInRect: defined then no animation loop rendering will occur. 我假设(虽然没有尝试过)如果你只是没有指定GLKViewDelegate或者提供带有drawInRect:的子类GLKView drawInRect:定义那么就不会发生动画循环渲染。 Have you attempted this? 你试过这个吗?

The alternative would be to simply create some @property (assign, nonatomic) BOOL shouldUpdate; 另一种方法是简单地创建一些@property (assign, nonatomic) BOOL shouldUpdate; in your MyController : GLKViewController <GLKViewDelegate> class which will only update if there is something to do: 在你的MyController : GLKViewController <GLKViewDelegate>类中,只有在有事情要做时才会更新:

[self setDelegate:self]; // in init or awakeFromNib or other..

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    if ([self shouldUpdate]) { ...

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 your GLKViewController for initial GL setup. 值得一提的是:官方API文档声明viewDidLoad应该在您的GLKViewController用于初始GL设置。 I had issues with this; 我有这个问题; for some reason my glCreateShader calls always returned zero. 由于某种原因,我的glCreateShader调用总是返回零。 This may have been due to my setting the EAGLContext post-initialisation; 这可能是由于我设置EAGLContext后初始化; I couldn't pass it as an init parameter since I created the controller in Storyboard. 我无法将其作为init参数传递,因为我在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: 我的解决方案只是在我的drawInRect中有以下内容:

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    if ([self initialGLSetupDone] == NO) {
        [self beforeFirstRender];
        [self setInitialGLSetupDone:YES];
    }
    // .. rest of render code goes here.
}

Obviously it's not ideal to have an IF in there unnecessarily, but it was an easy solution. 显然,不必要地在那里安装IF并不理想,但这是一个简单的解决方案。

Let me know how it goes if you try updating to use GLKit. 如果您尝试更新以使用GLKit,请告诉我它是怎么回事。

After you have created GLKView, add this line: 创建GLKView后,添加以下行:

glkView.enableSetNeedsDisplay = TRUE;

(Because of this, no one will redraw the view automatically) (因此,没有人会自动重绘视图)

When you want redraw, insert this line: 如果要重绘,请插入以下行:

[glkView setNeedsDisplay];

... then drawInRect routine will be called only once. ...然后drawInRect例程将只调用一次。

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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