正确的位置为GLKView设置着色器?

时间:2013-09-03 15:27:34

标签: ios opengl-es-2.0 glkit

我无法使用GLKView和GLKViewController为OpenGLES应用程序找到正确的着色器设置位置。

看起来viewDidLoad是一个自然的地方,但是当我尝试在这里执行此操作时,着色器创建失败。我的设置是这样的:

//shader helper method
int setupShaders(const char* vShader, const char* fShader); //returns a program handle

//inside GLKViewController subclass

static int program;

-(void)viewDidLoad{
    [super viewDidLoad];
    program = setupShaders(vsh, fsh); //program will be zero indicating setup failure
}

我知道设置代码有效,因为如果我在里面调用它会成功 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect。

所以我假设当调用 - (void)viewDidLoad时,OpenGL没有完全初始化,或者必须要做些什么来为我正在尝试的设置设置正确的OpenGL上下文,我只是不能找到有关在何处或如何正确设置的任何文档。

3 个答案:

答案 0 :(得分:2)

您可以轻松设置着色器的最早位置是drawRect方法。这是因为必须有一个有效的GL上下文当前。根据{{​​3}}:

  

在调用drawRect:方法之前,视图使其EAGLContext对象成为当前的OpenGL ES上下文,并将其framebuffer对象绑定到OpenGL ES上下文作为呈现命令的目标。

因此,最简单的方法是挂起一些信息,比如program句柄,只有在非零时才进行初始化。

if (program == 0)
    program = setupShaders(vsh, fsh);

如果您不喜欢这种方法,可以考虑使用您提供的上下文初始化GLKView,或者覆盖bindDrawable。或者您无法使用GLKView并手动执行操作...

答案 1 :(得分:1)

在调用任何OpenGL ES API之前,需要有一个当前EAGLContext,其中包括编译着色器等设置工作。 GLKView在调用drawRect:(或glkView:drawInRect:)方法之前使其上下文保持最新状态,但欢迎您随时将其设置为当前上下文。

视图的上下文是viewDidAppear:的当前上下文,因为该方法是在视图第一次绘制自身之后调用的。我不确定它是否保证在那时是最新的 - 没有记录的API合同,GLKView的上下文在绘图结束后仍然是最新的。因此,每当您想要为OpenGL ES场景进行设置工作时,最好自己致电[EAGLContext setCurrentContext:myContext](即使您选择在viewDidAppear:中进行设置)。

在为GLKView / GLKViewController设置的示例创建新的Xcode项目时,请参阅 OpenGL ES游戏模板。

答案 2 :(得分:0)

所以事实证明,如果从内部初始化它是完美的 - (void)viewDidAppear。雅各布的解决方案也可以正常工作,但使用回调而不是向draw方法添加条件似乎对我来说更清晰。