底线:
如果你想使用 Flex/Bison 在 C++ 中添加一个非常小的特性,你会怎么做?例如,void xxx()
使用语法声明函数的能力:foo%%: xxx
?
整个故事:
一旦我编写了一个自定义着色器处理程序,该程序可以从多个块构建现成的 Cg/GLSL 像素和顶点着色器。我添加了一些功能,主要与静态编译相关(类似于“更好的预处理器”)。
例如,看起来像
#if LIGHT_TYPE == POINT
float lightStrength = dot(N, normalize(pos - lightPos));
#elif LIGHT_TYPE == DIRECTIONAL
float lightStrength = dot(N, lightDir);
#endif
使用纯宏,看起来像
[LightType = Point]
[Require: pos, lightPos]
float LightStrength()
{
!let %N Normal
return dot(%N, normalize(pos - lightPos));
}
用我的“语言”。如您所见,可以为可变的灯光/材质类型提供“功能”。还有可能“调用”其他函数并标记特定着色器需要哪些统一/可变属性。
为什么要这么努力?因为(尤其是在像 SM 2.0 这样的早期卡中)属性有很多限制,我的“编译器”生成了带有所需属性/变量列表的即用型着色器,像素和顶点着色器之间的托管参数,优化了一些静态的东西(只是为了可读性,因为 Cg 编译器稍后会对其进行优化)。
好的,但我写所有这些并不是为了赞美自己或其他什么。
我用 C# 编写了这个“编译器”,它最初是一个非常小的程序。但是随着时间的流逝,添加了许多功能,现在程序完全一团糟,没有重构选项。此外,使用 C# 编码意味着我无法将此编译器直接嵌入到 C++ 游戏中,这迫使我生成进程来编译着色器(这需要很多时间)。
我想使用 C++ 和 Flex/Bison 工具包重写我的语言/编译器。我已经在 Flex/Bison 中编写了高效的数学解析器,所以我在这方面有些经验。但是,有一件事我自己无法解决,这是我的问题的一个主题。
我怎样才能将 GLSL 嵌入到我的语言中?在 C# 编译器中,我只是逐行检查行是否以特殊字符(如 % 或 [)开头,后来使用 string_replace 和/或正则表达式做了许多技巧和黑客攻击。
现在我想写下一个干净的 Bison 语法并正确地做。但是包括 GLSL 的整个语法让我害怕。它是一种庞大而复杂的语言,不断发展。无论如何,我最想做的就是传递所有这些 GLSL 代码。
如果您根本没有 GLSL/Cg/图形编程经验,这不是很重要。这个问题可以改写成“底线”。
那么,如果你想使用 Flex/Bison 在 C++ 中添加一个非常小的特性,你会怎么做呢?例如,void xxx()
使用语法声明函数的能力:foo%%: xxx
?