Ios 使用GLKit的按需OpenGL ES渲染
我正在研究转换OpenGL渲染代码,以利用Ios 使用GLKit的按需OpenGL ES渲染,ios,opengl-es,glkit,Ios,Opengl Es,Glkit,我正在研究转换OpenGL渲染代码,以利用GLKit的一些功能(即异步纹理加载和GLKView/Controller提供的自动化)。然而,这些类的设计似乎主要是为了适应人们使用动画循环进行渲染,而我使用的是按需渲染。另外,一些渲染是针对纹理而不是GLKView的帧缓冲区,所以我应该只针对GLKView进行子类化并添加其他FBO吗 对于这种类型的设置有推荐的方法吗?我希望有以下几点: 将视图控制器的首选帧秒设置为0,或仅 暂停帧更新 忽略glkViewControllerUpdate或glkVi
GLKit
的一些功能(即异步纹理加载和GLKView/Controller
提供的自动化)。然而,这些类的设计似乎主要是为了适应人们使用动画循环进行渲染,而我使用的是按需渲染。另外,一些渲染是针对纹理而不是GLKView的帧缓冲区,所以我应该只针对GLKView进行子类化并添加其他FBO吗
对于这种类型的设置有推荐的方法吗?我希望有以下几点:
- 将视图控制器的
首选帧秒设置为
,或仅 暂停帧更新0
- 忽略
或glkViewControllerUpdate
方法 当我需要的时候,画我需要的东西glkView:drawInRect:
- 按顺序使用视图的
与普通setNeedsDisplay
ui视图一样 要显示框架(如果我 也将渲染到纹理?)
谢谢我刚刚将代码从使用我自己开发的EAGLContext管理器转换为使用GLKit类 您建议您可以“.忽略..
glkView:drawInRect:
方法,在我需要时只绘制[您]需要的内容”。这似乎是一个明智的选择,从性能角度来看;我假设(尽管尚未尝试)如果您只是不指定GLKViewDelegate
或提供子类GLKView
,并定义其drawInRect:
,则不会发生动画循环渲染。你试过这个吗
另一种方法是简单地创建一些@属性(赋值,非原子)BOOL shouldUpdate
在您的MyController:GLKViewController
类中,该类仅在需要执行某些操作时才会更新:
[self setDelegate:self]; // in init or awakeFromNib or other..
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
if ([self shouldUpdate]) { ...
我相信你明白了,这并不复杂
有一件事值得一提:官方API文档声明,对于初始GL设置,应在GLKViewController
中使用viewDidLoad
。我对此有意见;出于某种原因,我的glCreateShader
调用始终返回零。这可能是由于我设置了EAGLContext
post initialization;我无法将其作为init
参数传递,因为我在脚本中创建了控制器。然而,代码在逻辑上并没有什么错误,所以我提供这个友好的警告,以防您遇到类似的问题。我的解决方案只是在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
例程
希望它能有所帮助。我最终使用的方法是不使用GLKViewController
,而是直接在UIViewController
子类下使用GLKView
显然,GLKViewController
是为那些需要为游戏等应用程序提供一致渲染循环的用户而设计的。没有它,绘制到GLKView
就像调用[GLKView setNeedsDisplay]
一样简单。确保将enableSetNeedsDisplay
设置为YES
以启用此行为
如果仍要使用GLKViewController
,可以禁用视图中的动画渲染循环,如下所示:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated]; // setPaused automatically set to NO in super's implementation
[self setPaused:YES];
}
另外,将resumeOnDidBecomeActive
设置为NO
,以防止视图控制器再次自动恢复
但是,使用普通的UIViewController
和GLKView
是完全可以接受的,我看到苹果工程师推荐它作为执行按需绘图的适当方式。-1。这是不正确的-将enableSetNeedsDisplay
设置为NO
禁用GLKView
的setNeedsDisplay
方法。使用GLKViewController
时,此属性会自动设置为NO
,因此,事实上,在setNeedsDisplay“模式”下绘制时,需要手动将其设置为YES
。对于viewDidLoad
问题,必须在创建着色器之前设置EAGLContext
,就像你注意到自己一样。在设置其余总账代码之前,在viewDidLoad
中执行此操作也没有害处。查看Xcode中的“OpenGL游戏”模板项目,了解如何执行此设置的良好示例。感谢提供闩锁提示。比尝试手动绘制CaeAglayer或其他解决方法容易得多。您仍然可以与GLKit一起渲染到辅助FBO。如果您能够澄清需要按照前面提到的设置enableSetNeedsDisplay和ResumeOnDibEcomeActive的方法,这将有所帮助,因为您没有将它们放在ViewWillDisplay(BOOL)动画中。谢谢。请在创建视图/视图控制器时设置这些属性。例如,如果在代码中创建GLKViewController
,则可以在alloc
/init
之后的行中设置它。如果您在interface builder中创建它,那么在视图控制器中实现-awakeFromNib
方法可能是一个好地方。一般来说,像这样的属性应该在