I'd like to declare GLSL shader strings inline using macro stringification:
#define STRINGIFY(A) #A
const GLchar* vert = STRINGIFY(
#version 120\n
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
);
This builds and runs fine using VS2010 but fails to compile on gcc
with:
error: invalid preprocessing directive #version
Is there a way to use stringification like this in a portable manner?
I'm trying to avoid per-line quotes:
const GLchar* vert =
"#version 120\n"
"attribute vec2 position;"
"void main()"
"{"
" gl_Position = vec4( position, 0.0, 1.0 );"
"}"
;
...and/or line continuation:
const GLchar* vert = "\
#version 120\n \
attribute vec2 position; \
void main() \
{ \
gl_Position = vec4( position, 0.0, 1.0 ); \
} \
";
Unfortunately, having preprocessor directives in the argument of a macro is undefined, so you can't do this directly. But as long as none of your shaders need preprocessor directives other than #version
, you could do something like:
#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 );
}
);
Can you use C++11? If so you could use raw string literals:
const GLchar* vert = R"END(
#version 120
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
)END";
No need for escapes or explicit newlines. These strings start with an R (or r). You need a delimiter (I chose END) between the quote and the first parenthesis to escape parenthesis which you have in the code snippet.
The problem is due to gcc preprocessing macros meant for GLSL. Using standard stringify and escaping preprocessor directives with new lines in GLSL code worked for me.
#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 );
}
);
To achieve this purpose I used sed. I have seperate files with GLSL which I edit (with proper syntax highlighting), and in the same time GLSL in inlined in C++. Not very cross platform, but with msys it works under windows.
In C++ code:
const GLchar* vert =
#include "shader_processed.vert"
;
In Makefile:
shader_processed.vert: shader.vert
sed -f shader.sed shader.vert > shader_processed.vert
programm: shader_processed.vert main.cpp
g++ ...
shader.sed
s|\\|\\\\|g
s|"|\\"|g
s|$|\\n"|g
s|^|"|g