我正在尝试调试这个我没写过的渲染循环。某个地方出现错误导致程序崩溃,但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。这是我正在尝试完成的从Java到Objective-C ++的Google's CardboardSDK(decompiled)的正在进行的端口。
主渲染循环位于CardboardViewController
类。导致崩溃的OpenGL命令应该在DistortionRenderer
类上(其功能是采用普通的立体视口并在纹理上渲染它们,以便将镜头失真应用于每个)。
如果您将CardboardViewController
的{{1}}设置为distortionCorrectionEnabled
,则崩溃就会消失。
答案 0 :(得分:3)
这里没有足够的信息来调试你的问题,所以相反,关于调试的一般说明...
glGetError
一般来说调试GL问题的方法很糟糕,尤其是在iOS中,尤其是在您使用GLKView
或其他代表您工作GL的系统时更是如此。您很可能会设置一些不会导致错误的状态,直到GLKView
开始向GPU提交内容(当drawRect:
/ glkView:drawInRect:
返回时)。< / p>
请尝试使用Xcode Frame Capture tool。而不是要求您在代码中粘贴glGetError
检查(并确保它们在发布版本中被禁用),然后尝试了解结果,它会向您显示错误(至少有一些错误)每次通话的解释级别,包括代表您在系统代码中进行的通话。它显示了完整的状态图,以及逐个调用的帧的快照,因此您可以更早地告诉您是否设置了某个导致问题的状态。
好的,有人认为这可能与您的问题有关:尝试在bindDrawable
上使用GLKView
,而不是直接将其帧缓冲重新绑定到glBindFramebuffer
。