我有两个问题,两个非常重要的问题:
- 是否有 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
- 包括运行时常量。有人说制服可能更适合这个目的,但预定义的模棱两可的常量也可能没问题。
- 功能的可重用性。
预期用途的一个示例:
颜色渐变.glsl
#ifndef COLOURGRADIENT_GLSL
#define COLOURGRADIENT_GLSL
vec4 gradient(vec4 cl1, vec4 cl2, float distance)
{
return cl1+((cl2-cl1)*distance);
}
#endif // COLOURGRADIENT_GLSL
渐变片段
#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,如果使用的后端不是 Vulkan ,则可以选择返回到 GLSL (或 HLSL) 。由于我不知道如何在反编译回 GLSL 之前将多个 SPIR-V 二进制文件拼接在一起,我认为每个着色器模块只有一个二进制文件很重要,因此有必要#include
使用多个二进制文件来代替。