gen*_*ult 18 c++ opengl gcc glsl c-preprocessor
我想使用宏字符串化声明内联的GLSL着色器字符串:
#define STRINGIFY(A) #A
const GLchar* vert = STRINGIFY(
#version 120\n
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
);
Run Code Online (Sandbox Code Playgroud)
这使用VS2010构建并运行良好,但无法编译gcc:
error: invalid preprocessing directive #version
Run Code Online (Sandbox Code Playgroud)
有没有办法以可移植的方式使用这样的字符串化?
我试图避免每行引用:
const GLchar* vert =
"#version 120\n"
"attribute vec2 position;"
"void main()"
"{"
" gl_Position = vec4( position, 0.0, 1.0 );"
"}"
;
Run Code Online (Sandbox Code Playgroud)
......和/或续行:
const GLchar* vert = "\
#version 120\n \
attribute vec2 position; \
void main() \
{ \
gl_Position = vec4( position, 0.0, 1.0 ); \
} \
";
Run Code Online (Sandbox Code Playgroud)
ems*_*msr 25
你能用C++ 11吗?如果是这样,您可以使用原始字符串文字:
const GLchar* vert = R"END(
#version 120
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
)END";
Run Code Online (Sandbox Code Playgroud)
无需转义或显式换行符.这些字符串以R(或r)开头.您需要在引号和第一个括号之间使用分隔符(我选择END)来转义代码段中的括号.
Chr*_*odd 17
不幸的是,宏的参数中的预处理程序指令是未定义的,因此您无法直接执行此操作.但只要你的着色器都不需要预处理器指令#version,你可以做类似的事情:
#define GLSL(version, shader) "#version " #version "\n" #shader
const GLchar* vert = GLSL(120,
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
);
Run Code Online (Sandbox Code Playgroud)
为了达到这个目的,我使用了 sed。我有我编辑的带有 GLSL 的单独文件(具有正确的语法突出显示),同时 GLSL 内联在 C++ 中。不是很跨平台,但使用 msys 它可以在 Windows 下工作。
在 C++ 代码中:
const GLchar* vert =
#include "shader_processed.vert"
;
Run Code Online (Sandbox Code Playgroud)
在生成文件中:
shader_processed.vert: shader.vert
sed -f shader.sed shader.vert > shader_processed.vert
programm: shader_processed.vert main.cpp
g++ ...
Run Code Online (Sandbox Code Playgroud)
着色器.sed
s|\\|\\\\|g
s|"|\\"|g
s|$|\\n"|g
s|^|"|g
Run Code Online (Sandbox Code Playgroud)
问题是由于用于GLSL的gcc预处理宏.使用标准stringify和转义预处理程序指令与GLSL代码中的新行为我工作.
#define STRINGIFY(A) #A
const GLchar* vert = STRINGIFY(
\n#version 120\n
\n#define MY_MACRO 999\n
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
);
Run Code Online (Sandbox Code Playgroud)