Debugging 更具体的OpenGL错误信息

Debugging 更具体的OpenGL错误信息,debugging,opengl,error-handling,jogl,Debugging,Opengl,Error Handling,Jogl,当OpenGL标记错误时,是否有方法检索更详细的错误信息?我知道核心OpenGL中没有,但是否有一些常见的扩展、平台或驱动程序相关的方式或其他方式 我的基本问题是我有一个游戏(用Java和JOGL编写),当人们在某些硬件/软件配置上遇到问题时,很难找到问题的根源。出于性能方面的原因,我不能一直为每个命令调用glGetError,而只能在程序中的几个点上调用,因此甚至很难找到哪条命令标记了错误。然而,即使我可以,OpenGL中极其普遍的错误代码并没有真正告诉我发生了什么(看到命令上的手册页甚至描述

当OpenGL标记错误时,是否有方法检索更详细的错误信息?我知道核心OpenGL中没有,但是否有一些常见的扩展、平台或驱动程序相关的方式或其他方式

我的基本问题是我有一个游戏(用Java和JOGL编写),当人们在某些硬件/软件配置上遇到问题时,很难找到问题的根源。出于性能方面的原因,我不能一直为每个命令调用
glGetError
,而只能在程序中的几个点上调用,因此甚至很难找到哪条命令标记了错误。然而,即使我可以,OpenGL中极其普遍的错误代码并没有真正告诉我发生了什么(看到命令上的手册页甚至描述了各种错误代码是如何被重用的,有时有很多不同的实际错误情况)

如果有一种方法可以找出OpenGL命令实际标记了错误,以及关于标记的错误的更多细节(例如,如果我得到
GL\u INVALID\u VALUE
,哪个参数的哪个值是无效的,为什么?),这将非常有帮助


这似乎有点奇怪,司机不会提供这些信息,即使是以完全定制的方式,但看起来像我一样,我肯定没有找到任何方法来找到它。如果他们真的不这样做,有什么好的理由来解释为什么会这样吗?

这里有一些建议

  • 根据手册页,
    glGetError
    返回错误标志的值,然后将其重置为GL\u NO\u error。我会使用这个属性来追踪你的bug——如果没有其他东西的话,你可以切换到你调用它的地方,然后进行二进制搜索来找到错误发生的地方

  • 我怀疑调用
    glGetError
    是否会对性能造成影响。它所做的只是读回一个错误标志

  • 如果您没有能力在这些人拥有的特定硬件/软件配置上测试这一点,那么这可能会很棘手。毕竟,OpenGL驱动程序是为特定设备实现的

  • glGetError
    基本上可以说前一行搞错了。这应该为您提供一个良好的起点—您可以在手册页中查找该函数抛出错误的原因,而不是试图根据其枚举名来找出错误

  • 还有其他特定的错误函数要调用,例如
    glGetProgramiv
    glGetFramebufferStatus
    ,您可能需要检查,因为
    glGetError
    不会检查每种类型的错误。IE仅仅因为它读起来干净并不意味着没有发生另一个错误


实际上,核心OpenGL中有一个功能,可以为您提供详细的调试信息。但您必须将最低版本要求设置得相当高,才能将其作为核心功能

尽管如此,请看——尽管它只是OpenGL 4.3中的核心,但它以扩展形式存在了相当长的一段时间,并且不需要任何特殊的硬件特性。所以在大多数情况下,你真正需要的是来自NV或AMD的最新驱动程序

我举了一个例子,说明了如何在中使用这个扩展,并提供了一些实用函数,使输出更易于阅读。它是用C写的,所以我不知道它会有多大帮助,但你可能会发现一些有用的东西


以下是此扩展(AMD Catalyst)的输出类型: 它不仅会给你错误信息,甚至会给你性能警告,因为你做了一些愚蠢的事情,比如使用8位顶点索引(桌面GPU不喜欢)



为了回答您的另一个问题,如果您将调试输出设置为synchronous,并在调试回调中安装断点,则可以轻松地使任何调试器在OpenGL错误时中断。如果您检查调用堆栈,您应该能够快速准确地确定哪些API调用产生了最多的错误。

“我怀疑调用
glGetError
会给您带来性能影响。”--我也会这么认为,但当我添加太多调用堆栈时,我肯定会看到相当严重的性能影响。这听起来绝对不错,但我看到,在我看到的任何英特尔GPU驱动程序上都没有这种扩展,当然,这也是我最需要它的地方。如果这是提供调试支持的唯一常用方法,那么我是否可以安全地假设不可能从旧的英特尔驱动程序中获得更详细的信息?@Dolda2000:是的,这真是不幸的一部分。如今,NV和AMD都在编写高质量的GL驱动程序,英特尔算是个新手(尽管它们的性能越来越好)。英特尔最终将编写实现OpenGL 4.3的驱动程序,然后他们将被迫实现此扩展,但在此之前,您可能需要NV或AMD卡来使用此扩展。如果有什么安慰的话,所有供应商的简单API错误都是一样的,因此如果您有什么问题,您可以在NV或AMD机器上运行它,并检查调试输出。的确,但我的主要问题是,有时我使用的功能只有英特尔驱动程序缺少。尤其是在像GMA 9xx这样的旧GPU上,它甚至不支持OpenGL 2
OpenGL Error:
=============
 Object ID: 102
 Severity:  Medium
 Type:      Performance
 Source:    API
 Message:   glDrawElements uses element index type 'GL_UNSIGNED_BYTE' that is not
            optimal for the current hardware configuration; consider using 
            'GL_UNSIGNED_SHORT' instead.