调试OpenGL比在每个命令后调用glGetError有更好的方法吗?

Mad*_*ist 7 android opengl-es

我正在Android上尝试一些OpenGL,而且我之前没有任何3D编程经验.显然我在程序中犯了很多错误.

当我遇到问题并发现glGetError产生错误代码时,我只是glGetError在每次调用我的绘图代码中的OpenGL命令后添加了调用.虽然这很有效,但我发现了我的错误,我的绘图代码现在是我认为的两倍大,难以阅读.

有没有办法摆脱所有这些显式调用,glGetError并自动调用它?优选地,如果发生OpenGL错误,我的app应该只是中止错误,指示哪个命令负责.

ssc*_*rth 10

从版本4.2开始,Android在手机的开发者选项中提供了一个名为"启用OpenGL跟踪"的选项.如果将其设置为"在glGetError上调用堆栈",您将获得类似的输出

07-15 15:44:43.045: D/libEGL(14251): [glEnableClientState] 0x500
07-15 15:44:43.068: D/CallStack(14251): glGetError:glEnableClientState#00  pc 00019388  /system/lib/libEGL.so
07-15 15:44:43.076: D/CallStack(14251): glGetError:glEnableClientState#01  pc 0001e290  /system/lib/libdvm.so (dvmPlatformInvoke+112)
07-15 15:44:43.076: D/CallStack(14251): glGetError:glEnableClientState#02  pc 0004d410  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+395)
07-15 15:44:43.076: D/CallStack(14251): glGetError:glEnableClientState#03  pc 000276e4  /system/lib/libdvm.so
Run Code Online (Sandbox Code Playgroud)

在日志中.在这种情况下,我传递了一个错误的枚举/ int glEnableClientState()来触发错误.请注意,启用此选项将"消耗"该错误,并且进一步glGetError()检查将不再报告此错误.相反,您现在可以节省将glGetError()调用放入代码中的时间,只需将日志输出grep为"glGetError:".

  • 我无法在Oreo上找到“启用OpenGL跟踪”。有什么想法为什么他们不见了? (2认同)

Chr*_*ica 0

桌面 OpenGL 4.3+ 具有扩展的调试和回调功能(尽管我对这些没有任何经验)。但在 ES 中确实没有更好的了。可悲的是,最好的解决方案仍然是不写任何s (或者可能只在某些选定的重要点,例如每帧的结尾或其他内容),并且仅在某些“不起作用”glGetError时才集体引入它们。

除此之外,你还可以制作一些包装纸,例如

template<typename F> void checked(F fn)
{
    fn();
    auto error = glGetError();
    if(error != GL_NO_ERROR)
        throw std::runtime_error("OpenGL error: "+std::to_string(error));
}

...
checked([&]() { glDrawElements(...); });
Run Code Online (Sandbox Code Playgroud)

(假设C++11,但其他语言应该有类似的设施)

但我认为这样的解决方案在可读性和简洁性方面仍然不能完全等同于 no glGetError