有没有办法检查程序使用了哪些 OpenGL / GLSL 扩展?

Is there a way to check what OpenGL / GLSL extensions are used by a program?

我想知道是否有一些工具可以检查您在程序或着色器中使用了哪些扩展(或者您必须检查的最低 GL 版本)。

类似于:'checkGL directory' 获取目录中程序使用的扩展列表。

输出类似于:

GL_MIRRORED_REPEAT        - GL_VERSION_1_4 - GL_OES_texture_mirrored_repeat
glUseProgram              - GL_VERSION_2_0 - GL_ES_VERSION_2_0
glEnableVertexAttribArray - GL_VERSION_2_0 - GL_ES_VERSION_2_0

我从未以编程方式完成此操作,但如果您依赖编译器错误并且有解析 XML 文件的经验,应该可以直接进行操作。代替实际存在的工具(我不知道),这就是您自己实现它的方式。

像往常一样构建您的程序,但注释掉所有与 GL 相关的包含(例如 #include <GL/gl.h>#include <GL/glew.h>),然后保存编译器错误记录到一个文件。鉴于此错误日志,您可以通过解析 OpenGL XML registry.

来追踪缺少的函数和常量需要哪个 GL 扩展 and/or 核心版本的 GL

我建议解析 GL 常量、类型和函数的编译器错误日志,而不是源代码,因为编译器将 运行 通过 pre-processor,这将消除很多误报.您可以自己轻松地解析项目目录中的每个 .c.cpp.h 等文件,并查找以 gl* 或 [=19= 开头的任何内容],但这将天真地包括非活动代码分支、注释等。


XML 注册表是 Khronos 用于在其网站上生成 headers 的内容,它包含每个 API 函数、枚举数、typedef 和扩展名的非常详细的信息(如果您知道的话)如何解析它。

As-per 你的例子,你会发现:

<feature api="gl" name="GL_VERSION_1_4" number="1.4">
    <require>
        ...
        <enum name="GL_MIRRORED_REPEAT"/>
        ...
     </require>
</feature>

...

<feature api="gles2" name="GL_ES_VERSION_2_0" number="2.0">
    <require>
        ...
        <enum name="GL_MIRRORED_REPEAT"/>
        ...
     </require>
</feature>

这意味着在“gl”(桌面 GL)中,GL_MIRRORED_REPEAT 是 1.4 版的核心,而在“gles2”(OpenGL ES 2.0+)中,它是 2.0 版的核心。

注意不要过多阅读标签“gles2”(这是 OpenGL ES 的一个分支,包含任何 ES 2.0 或更新版本,解析实际的 namenumber 找出版本要求)。

如果您知道核心常量的枚举值 GL_MIRRORED_REPEAT,那么您可以查找具有相同值的所有其他枚举,并将它们追溯到提升为核心的相应扩展。

交叉引用所有提供 GL_MIRRORED_REPEAT (0x8370) 的扩展:

<enums namespace="GL" start="0x8370" end="0x837F" vendor="HP">
        <!-- NOTE: IBM is using values in this range, because of a
             bobble when an employee left DEC for IBM at the same
             time as they were assigned the range. their registry
             became inconsistent. It's unknown whether HP has any
             conflicts. They have never reported using any values in
             this range. Lesson: assigned ranges belong to vendors,
             not engineers! -->
    <enum value="0x8370" name="GL_MIRRORED_REPEAT"/>
    <enum value="0x8370" name="GL_MIRRORED_REPEAT_ARB"/>
    <enum value="0x8370" name="GL_MIRRORED_REPEAT_IBM"/>
    <enum value="0x8370" name="GL_MIRRORED_REPEAT_OES"/>
        <unused start="0x8371" end="0x837F" vendor="HP"/>
</enums>

...

<extension name="GL_ARB_texture_mirrored_repeat" supported="gl">
    <require>
        <enum name="GL_MIRRORED_REPEAT_ARB"/>
    </require>
</extension>

<extension name="GL_IBM_texture_mirrored_repeat" supported="gl">
    <require>
        <enum name="GL_MIRRORED_REPEAT_IBM"/>
    </require>
</extension>

<extension name="GL_OES_texture_mirrored_repeat" supported="gles1">
    <require>
        <enum name="GL_MIRRORED_REPEAT_OES"/>
    </require>
</extension>

在这种情况下,GL_MIRRORED_REPEAT 在 GL 中由 GL_ARB_texture_mirrored_repeatGL_IBM_texture_mirrored_repeat 提供,在 GLES 1.x 中由 GL_OES_texture_mirrored_repeat 提供(它是 ES 的核心2.0).


关于确定 GLSL 着色器的最低版本号,那里没有可以解析的 XML 文件。唯一真正的优点是,如果您将 #version ... 指令设置得太低,大多数 GLSL 编译器会在着色器信息日志的 error/warning 中包含所需的版本 and/or 扩展。

你最好的选择是使用 GLslang (OpenGL Reference Compiler) 和 110 (Desktop GL) 的强制版本来验证你的着色器,并且100 (OpenGL ES)。它不像供应商 GLSL 编译器那么完整,但无论您使用什么 GPU,它的输出始终是一致的,您应该能够为它编写解析器。


更新:

我在几个小时内完成了一个大致符合您要求的项目,这是一些示例输出:

Enter OpenGL name to search for: GL_MIRRORED_REPEAT
--------------------------------
 >> Enum:   GL_MIRRORED_REPEAT is 0x8370

  * Core in                   GL_VERSION_1_4    (   gl 1.4)
  * Core in                GL_ES_VERSION_2_0    (gles2 2.0)

 >> Enum Alias: GL_MIRRORED_REPEAT_ARB <<
  * Provided by GL_ARB_texture_mirrored_repeat (gl)

 >> Enum Alias: GL_MIRRORED_REPEAT_IBM <<
  * Provided by GL_IBM_texture_mirrored_repeat (gl)

 >> Enum Alias: GL_MIRRORED_REPEAT_OES <<
  * Provided by GL_OES_texture_mirrored_repeat (gles1)


Enter OpenGL name to search for: glEnableVertexAttribArray
--------------------------------
 >> Command:  void glEnableVertexAttribArray (GLuint index)

  * Core in                   GL_VERSION_2_0    (   gl 2.0)
  * Core in                GL_ES_VERSION_2_0    (gles2 2.0)

 >> Command Alias: glEnableVertexAttribArrayARB <<
  * Provided by GL_ARB_vertex_program (gl)

此项目的源代码可在 GitHub here.

上获得