首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用GLKit的按需OpenGL ES渲染

使用GLKit的按需OpenGL ES渲染
EN

Stack Overflow用户
提问于 2011-10-13 07:25:17
回答 3查看 10.9K关注 0票数 18

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

对于这种类型的设置,有没有推荐的方法?我希望会有这样的东西:

  • 将视图控制器的preferredFramesPerSecond设置为0,或者仅暂停glkViewControllerUpdateglkView:drawInRect:方法的frame,并在需要时绘制所需内容。
  • 使用视图的setNeedsDisplay as和正常的UIView一起显示框架(鉴于我也将呈现纹理,我是否需要调用bindDrawable?)。

如果这不是设计新API的目的,那么可能就不值得这么做了?我希望文档比它更透彻一点。也许当API“成熟”一点时,会提供更多的示例……

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-08 11:59:59

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

显然,GLKViewController是为那些需要游戏等应用程序的一致渲染循环的人而设计的。没有它,绘制到GLKView就像调用[glkView setNeedsDisplay]一样简单。要启用此行为,请确保将enableSetNeedsDisplay设置为YES

如果您仍然希望使用GLKViewController,则可以在viewWillAppear中禁用动画渲染循环,如下所示:

代码语言:javascript
复制
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];    // setPaused automatically set to NO in super's implementation

    [self setPaused:YES];
}

此外,将resumeOnDidBecomeActive设置为NO,以防止视图控制器再次自动恢复。

然而,在GLKView上使用普通的UIViewController是完全可以接受的,我认为这是一位苹果工程师推荐的一种按需绘图的合适方式。

票数 24
EN

Stack Overflow用户

发布于 2011-10-23 00:53:11

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

你建议你可以"..ignore这些.. glkView:drawInRect:方法,然后在我需要的时候绘制你需要的东西“。从性能上看,这似乎是一个明智的选择;我假设(尽管还没有尝试过)如果您只是不指定GLKViewDelegate或提供一个定义了drawInRect:的子类GLKView,那么就不会出现动画循环呈现。你有没有尝试过?

另一种方法是在您的MyController : GLKViewController <GLKViewDelegate>类中简单地创建一些@property (assign, nonatomic) BOOL shouldUpdate;,它只会在有事情要做时才会更新:

代码语言:javascript
复制
[self setDelegate:self]; // in init or awakeFromNib or other..

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

我相信你已经明白了,这并不复杂。

值得一提的是:官方API文档指出,应该在GLKViewController中使用viewDidLoad进行初始GL设置。我在这方面遇到了问题;出于某种原因,我的glCreateShader调用总是返回零。这可能是因为我在初始化后设置了EAGLContext;我不能将其作为init参数传递,因为我在Storyboard中创建了控制器。但是,代码没有任何逻辑上的错误,所以我提供这个友好的警告,以防您遇到类似的问题。我的解决方案很简单,就是在我的drawInRect中包含以下内容:

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

显然,在那里有一个不必要的IF并不理想,但这是一个简单的解决方案。

如果您尝试更新以使用GLKit,请让我知道它进行得如何。

票数 3
EN

Stack Overflow用户

发布于 2011-11-08 06:41:24

创建GLKView后,添加以下行:

glkView.enableSetNeedsDisplay = TRUE;

(因此,没有人会自动重新绘制视图)

当你想要重画时,插入下面这行:

代码语言:javascript
复制
[glkView setNeedsDisplay];

..。则drawInRect例程将仅被调用一次。

希望能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7747742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档