glGetError()在下一帧之前不起作用

时间:2015-01-12 18:54:07

标签: ios objective-c opengl-es glkit

我正在尝试调试这个我没写过的渲染循环。某个地方出现错误导致程序崩溃,但glGetError()似乎很有趣。

这是在 iOS 上,我正在使用GLKViewControllerGLKViewEAGLContext来绘制。

渲染循环的总结版本是这样的:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
   // At this point, GLKView's EAGLContext should be the active context

   checkGlGetError();

   if (!isTextureInit || geometryChanged)
   {
        setupRenderTextureAndRenderbuffer();
   } 
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_originalFramebufferId);
    glBindFramebuffer(GL_FRAMEBUFFER, _framebufferId);

    // a. Some complex operations
    // b. Some rendering on the texture framebuffer

    glBindFramebuffer(GL_FRAMEBUFFER, _originalFramebufferId);

    // c. Some additional complex operations
    // d. Render the texture on screen

    checkGlGetError();
}

这会导致应用崩溃。问题是第一个渲染帧的最后checkGlGetError()调用不会产生任何错误(并且屏幕上没有显示任何错误)。

第二个渲染帧的第一个checkGlGetError()调用会产生一个神秘的GL_INVALID_ENUM,此后不久,应用就会崩溃。

如果我用这个替换我的渲染循环:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    checkGlGetError();

    // a. Some complex operations
    // b. Some rendering on the screen

    checkGlGetError();
}

一切正常,并且没有报告任何错误。但是:为什么glGetError()在错误的OpenGL调用之后没有立即捕获错误?为什么它只在下一帧开始时报告?

带有错误的代码很长,并且没有任何更多迹象表明错误在哪里,它很难调试。


更新

我上传了所有代码here。这是我正在尝试完成的从Java到Objective-C ++的Google's CardboardSDKdecompiled)的正在进行的端口。

主渲染循环位于CardboardViewController类。导致崩溃的OpenGL命令应该在DistortionRenderer类上(其功能是采用普通的立体视口并在纹理上渲染它们,以便将镜头失真应用于每个)。

如果您将CardboardViewController的{​​{1}}设置为distortionCorrectionEnabled,则崩溃就会消失。

1 个答案:

答案 0 :(得分:3)

这里没有足够的信息来调试你的问题,所以相反,关于调试的一般说明...

glGetError一般来说调试GL问题的方法很糟糕,尤其是在iOS中,尤其是在您使用GLKView或其他代表您工作GL的系统时更是如此。您很可能会设置一些不会导致错误的状态,直到GLKView开始向GPU提交内容(当drawRect: / glkView:drawInRect:返回时)。< / p>

请尝试使用Xcode Frame Capture tool。而不是要求您在代码中粘贴glGetError检查(并确保它们在发布版本中被禁用),然后尝试了解结果,它会向您显示错误(至少有一些错误)每次通话的解释级别,包括代表您在系统代码中进行的通话。它显示了完整的状态图,以及逐个调用的帧的快照,因此您可以更早地告诉您是否设置了某个导致问题的状态。


好的,有人认为这可能与您的问题有关:尝试在bindDrawable上使用GLKView,而不是直接将其帧缓冲重新绑定到glBindFramebuffer