glGetError() 直到下一帧才工作
glGetError() doesn't work until next frame
我正在尝试调试这个不是我写的渲染循环。某处出错导致程序崩溃,但 glGetError()
似乎表现得很滑稽。
这在 iOS 上,我正在使用 GLKViewController
、GLKView
和 EAGLContext
进行绘图。
渲染循环的一个总结版本是这样的:
- (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. It's a work-in-progress port of Google's CardboardSDK (decompiled) 从 Java 到 Objective-C++ 我正在尝试完成。
主渲染循环在 CardboardViewController
class 上。导致崩溃的 OpenGL 命令应该在 DistortionRenderer
class 上(其功能是采用普通立体视口并将它们渲染到纹理上,以便对每个视口应用镜头失真)。
如果将 CardboardViewController
的 distortionCorrectionEnabled
设置为 NO
,崩溃就会消失。
这里没有足够的信息来调试您的问题,因此,关于调试的一般说明...
glGetError
通常是调试 GL 问题的糟糕方法,但在 iOS 中尤其如此,当您使用 GLKView
或其他执行 GL 的系统时更是如此代表你工作。很可能你正在设置一些不会导致错误的状态,直到 GLKView
开始向 GPU 提交内容(当你的 drawRect:
/glkView:drawInRect:
returns 时)。
请尝试使用 Xcode Frame Capture tool。它不需要您在整个代码中粘贴 glGetError
检查(并确保它们在发布版本中被禁用)然后尝试理解结果,它会向您显示错误(至少在某种程度上解释)对于每次调用,包括那些在系统代码中代表您进行的调用。它显示了完整的状态图,以及逐个调用呈现的帧的快照,因此您可以更早地判断您是否正在设置导致问题的状态。
好的,有人认为这可能与您的问题有关:尝试在 GLKView
上使用 bindDrawable
,而不是直接将其帧缓冲区与 glBindFramebuffer
重新绑定。
我正在尝试调试这个不是我写的渲染循环。某处出错导致程序崩溃,但 glGetError()
似乎表现得很滑稽。
这在 iOS 上,我正在使用 GLKViewController
、GLKView
和 EAGLContext
进行绘图。
渲染循环的一个总结版本是这样的:
- (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. It's a work-in-progress port of Google's CardboardSDK (decompiled) 从 Java 到 Objective-C++ 我正在尝试完成。
主渲染循环在 CardboardViewController
class 上。导致崩溃的 OpenGL 命令应该在 DistortionRenderer
class 上(其功能是采用普通立体视口并将它们渲染到纹理上,以便对每个视口应用镜头失真)。
如果将 CardboardViewController
的 distortionCorrectionEnabled
设置为 NO
,崩溃就会消失。
这里没有足够的信息来调试您的问题,因此,关于调试的一般说明...
glGetError
通常是调试 GL 问题的糟糕方法,但在 iOS 中尤其如此,当您使用 GLKView
或其他执行 GL 的系统时更是如此代表你工作。很可能你正在设置一些不会导致错误的状态,直到 GLKView
开始向 GPU 提交内容(当你的 drawRect:
/glkView:drawInRect:
returns 时)。
请尝试使用 Xcode Frame Capture tool。它不需要您在整个代码中粘贴 glGetError
检查(并确保它们在发布版本中被禁用)然后尝试理解结果,它会向您显示错误(至少在某种程度上解释)对于每次调用,包括那些在系统代码中代表您进行的调用。它显示了完整的状态图,以及逐个调用呈现的帧的快照,因此您可以更早地判断您是否正在设置导致问题的状态。
好的,有人认为这可能与您的问题有关:尝试在 GLKView
上使用 bindDrawable
,而不是直接将其帧缓冲区与 glBindFramebuffer
重新绑定。