#include与GLSL / C的自定义IO?

时间:2018-05-10 09:43:25

标签: c glsl c-preprocessor preprocessor physfs

我有两个问题,两个非常重要的问题:

  1. 是否有一个C预处理器可以使用任何自定义函数来查找由#include调用的文件?因为,比方说,我将我的代码存储在ZIP文件或其他东西中,并依靠PhysFS访问它们而不是解压缩它们。是否有一个可以使用的开源C预处理器,而不是仅限于正常的fopen?
  2. 是否可以在GLSL代码上使用自定义或标准C预处理器?我知道GLSL已经有一个预处理器,但它缺少#include功能,我想纠正它。
  3. 是否可以将上述两者合并为一个程序或视频游戏,其中GLSL源代码存储在ZIP或PK3文件中(因此可以通过PhysFS或任何自定义IO事件访问),自定义/修改后的C预处理器用于处理#include并获取包含的源?
  4. 我问这个是因为我不想为GLSL编写自己的C预处理器,除非绝对必要,并且宁愿利用现有的预处理器来实现#include与自定义IO。

    我需要C预处理器的唯一原因是因为我需要#include,我希望它与我的自定义IO一样。

    我想要实现的预处理器功能的示例:

    1. 使用#version 450#version 310 es以及#extension GL_ARB_separate_shader_objects : enable预先填充已经预处理的整个源代码
      1. 包含运行时常量。有人说制服可能更适合这个目的,但预定义的ambigious常数也可能很好。
      2. 功能的可重用性。
    2. 预期用法的一个例子:

      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));
      }
      

      这显然是一个微不足道的例子,但主要目的是增加代码的可重用性,并减少非预处理着色器必须包含的不必要代码的数量。

      我的最终目的是整合GlSlangSPIR-V Cross以将与Vulkan兼容的GLSL (使用自定义C预处理器扩展)编译为SPIR-V,并可选择返回如果使用的后端不是Vulkan,则为GLSL (或HLSL)。由于我不知道如何在反编译回GLSL之前将多个SPIR-V二进制文件拼接在一起,我认为每个着色器模块只有一个二进制文件很重要,因此需要#include而不是使用多个二进制文件。 / p>

1 个答案:

答案 0 :(得分:0)

#include指令只不过是将代码粘贴到某个位置,因此与“#include <path>”或“#include "path"”进行简单匹配就足够了。

如果需要更复杂的包含,还应该处理定义以便于保护(就像你的代码中那样),但这些在开始时是不必要的。

所有这一切,我认为支持这些增加是一种不好的做法:

  1. 不应使用Include来访问其他单元中的代码,因为函数已经可以在同一着色器类型的其他单元中调用。你基本上强迫“半内联”,这可能只会导致膨胀,而不是速度提升。
  2. 还应避免定义常量的使用,因为它们不是类型和上下文安全的。在这种情况下使用const float会更安全。
  3. 总而言之,这些不存在的事实主要是因为精心设计的GLSL开始时不需要这些。因此,在明确地将“特征”添加到有效的东西之前,必须询问这些添加是否必要,或者可以通过其他方式实现。