【问题标题】:OpenGL / GLSL - using glShaderSource with multiple source to support include filesOpenGL / GLSL - 使用具有多个源的 glShaderSource 来支持包含文件
【发布时间】:2011-08-02 12:58:37
【问题描述】:

由于 GLSL 没有包含文件选项,我试图通过使用“#pragma include”解析器来添加它。 (我想要这个,因为我有一些通用方法我只想实现一次,但可能会在许多不同的着色器中使用,比如 Ken Perlin 的 smootherstep)

解析着色器文件以获取包含的文件可以正常工作。 但是在使用多个源文件设置 ShaderSource 时,我总是遇到问题;因为我的主着色器通常以“#version 330”开头并且#version-line 总是必须是着色器中的第一行,所以我只能将我的主文件添加为传递给glShadersource的字符串数组中的第一个,然后即所有包含的文件。 但是我的主文件不能使用在这些包含文件中实现的任何函数,因为它们基本上会在我的主文件之后连接,所以编译器抱怨它不知道我的主文件的功能正在使用。

我能想到的让它工作的唯一方法是读取主文件,解析 include pragma,然后 replace 该 pragma 行与文件的文件内容包含(递归地将相同的方法应用于可能包含其他文件本身的所有包含文件)-但这意味着编译错误中的行号将不再与主文件的实际行号匹配。

是否有人为 GLSL 设置了某种“包含”功能,可以正常工作并保留行号?如果是这样 - 如何?

【问题讨论】:

    标签: opengl include glsl shader pragma


    【解决方案1】:

    解析#version 标签并使其成为单独的(也是第一个)源字符串怎么样?这样你也可以在包含中使用不同的版本标签(取决于它们的功能要求),只需将它们减少到只有一个版本标签(版本号最高的那个)。

    【讨论】:

    • 您,先生,真是个天才!不知道为什么我没有想到这一点,但我认为这将是我要走的路。 \o/
    【解决方案2】:

    首先,#line 预处理器指令设置编译器错误消息中报告的当前源代码行。使用此预处理器指令,您可以轻松地包含外部源代码行。这应该可以解决您的问题。

    此外,我已经阅读了shading_language_include 扩展,它应该可以帮助您支持“包含”功能。如果您的驱动程序没有实现它,您仍然可以支持扩展引入的语法,因此您可以优雅地支持需要该扩展的着色器。

    【讨论】:

      【解决方案3】:

      如果您的着色器在文件中,您可以在将它们传递给 openGL 之前使用 cpp(或 gcc -E)来处理它们(并处理任何#include 指令)。您甚至可以使用 popen("cpp -P main.glsl", "r") 之类的东西来读取和预处理您的着色器...

      【讨论】:

      • 使用此技术是设置由 glsl 框架定义的预处理器符号所必需的(例如 VERSION)。
      • 这再次与行号混淆。此外,GCC 不支持 GLSL。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      • 2013-10-25
      相关资源
      最近更新 更多