Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用GLKit的按需OpenGL ES渲染_Ios_Opengl Es_Glkit - Fatal编程技术网

Ios 使用GLKit的按需OpenGL ES渲染

Ios 使用GLKit的按需OpenGL ES渲染,ios,opengl-es,glkit,Ios,Opengl Es,Glkit,我正在研究转换OpenGL渲染代码,以利用GLKit的一些功能(即异步纹理加载和GLKView/Controller提供的自动化)。然而,这些类的设计似乎主要是为了适应人们使用动画循环进行渲染,而我使用的是按需渲染。另外,一些渲染是针对纹理而不是GLKView的帧缓冲区,所以我应该只针对GLKView进行子类化并添加其他FBO吗 对于这种类型的设置有推荐的方法吗?我希望有以下几点: 将视图控制器的首选帧秒设置为0,或仅 暂停帧更新 忽略glkViewControllerUpdate或glkVi

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

对于这种类型的设置有推荐的方法吗?我希望有以下几点:

  • 将视图控制器的
    首选帧秒设置为
    0
    ,或仅 暂停帧更新
  • 忽略
    glkViewControllerUpdate
    glkView:drawInRect:
    方法 当我需要的时候,画我需要的东西
  • 按顺序使用视图的
    setNeedsDisplay
    与普通
    ui视图一样
    要显示框架(如果我
    也将渲染到纹理?)
如果这不是新API的设计目的,那么这可能不值得付出努力?我希望文档能比现在更全面一点。当API“成熟”一点时,可能会提供更多的样本


谢谢

我刚刚将代码从使用我自己开发的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
方法可能是一个好地方。一般来说,像这样的属性应该在