OpenGL / GLSL - 使用glShaderSource和多个源来支持包含文件

时间:2011-08-02 12:58:38

标签: opengl include glsl shader pragma

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

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

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

有没有人为GLSL设置某种“包含”功能,可以使用和保留亚麻布?如果是这样 - 怎么样?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:-1)

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