【发布时间】:2018-10-20 13:12:23
【问题描述】:
我有两个问题,两个非常重要的:
- 是否有 C 预处理器可以使用任何自定义函数来定位由
#include调用的文件?因为,比如说,我将我的代码存储在一个 ZIP 文件或其他东西中,并且依靠 PhysFS 来访问它们而不是解压缩它们。是否有可以使用的开源 C 预处理器,而不是仅限于普通的 fopen? - 是否可以在 GLSL 代码上使用自定义或标准 C 预处理器?我知道 GLSL 已经有一个预处理器,但它缺少
#include功能,我想纠正它。 - 是否可以将上述两者结合起来,制作一个程序或视频游戏,其中 GLSL 源代码存储在 ZIP 或 PK3 文件中(因此可以使用 PhysFS 或任何自定义 IO 东西访问),并使用自定义/修改的 C 预处理器来处理 #include 并获取包含的源?
我问这个是因为我不想为 GLSL 编写自己的 C 预处理器,除非绝对必要,并且更愿意利用现有的预处理器来实现带有自定义 IO 的#include。
几乎我需要 C 预处理器的唯一原因是因为我想要 #include,并且我想要它与我的自定义 IO 东西。
我想实现的预处理器功能示例:
- 用
#version 450,或#version 310 es,以及#extension GL_ARB_separate_shader_objects : enable前置整个已经预处理的源代码- 包括运行时常量。有人说制服可能更适合这个目的,但预定义的模棱两可的常量也可能没问题。
- 函数的可重用性。
预期用途的一个例子:
ColourGradient.glsl
#ifndef COLOURGRADIENT_GLSL
#define COLOURGRADIENT_GLSL
vec4 gradient(vec4 cl1, vec4 cl2, float distance)
{
return cl1+((cl2-cl1)*distance);
}
#endif // COLOURGRADIENT_GLSL
Gradient.frag
#include <colours/ColourGradient.glsl>
layout(location = 0) in vec2 TexCoords;
layout(location = 0) out vec4 FragColor;
uniform vec4 colourA;
uniform vec4 colourB;
uniform bool colourCentering;
#define MAX_DISTANCE 1.4142135623731 // the square root of 2, basically
void main()
{
float dist = length(TexCoords) / MAX_DISTANCE;
if(colourCentering)
{
FragColor = gradient(colourA,colourB,(abs(dist -0.5) * 2.0));
}
else FragColor = gradient(colourA,colourB,(diff * dist));
}
这显然是一个微不足道的例子,但主要目的是增加代码的可重用性,并减少非预处理着色器必须包含的不必要代码量。
我的最终意图是集成 GlSlang 和 SPIR-V Cross 以将 Vulkan 兼容的 GLSL(使用自定义 C 预处理器扩展)编译为 SPIR-V,并可选择返回 GLSL (或 HLSL) 如果使用的后端不是 Vulkan。由于我不知道如何在反编译回 GLSL 之前将多个 SPIR-V 二进制文件拼接在一起,因此我认为每个着色器模块只有一个二进制文件很重要,因此需要#include 而不是使用多个二进制文件。
【问题讨论】:
-
为什么要能够#include,给出编码示例来说明想要达到的效果
标签: c glsl c-preprocessor preprocessor physfs