I\'d like to declare GLSL shader strings inline using macro stringification:
#define STRINGIFY(A) #A
const GLchar* vert = STRINGIFY(
#version 120\\n
attribu
An alternative approach: include a header file, but with a .glsl extension.
For example, I have a file called bar.h.glsl. It exposes my vertex and fragment shader code as raw literals:
#pragma once
namespace bar {
static const char vertex[] = R"(#version 410 core
// ----- vertex shader start -----
layout( location = 0 ) in vec4 vPosition;
uniform float Time;
uniform float Width;
void main()
{
float x = vPosition.x;
float y = vPosition.y * Width;
float yOffset = mix(sin(Time), sin(Time * 0.75), x * 0.5 + 0.5);
gl_Position = vec4(x, y + yOffset, vPosition.z, vPosition.w);
}
// ------ vertex shader end ------
)";
static const char fragment[] = R"(#version 410 core
// ----- fragment shader start ----
out vec4 fragColor;
void main()
{
fragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
// ------ fragment shader end -----
)";
}
Then in my source, I simply include the file:
#include "bar.h.glsl"
and access the glsl strings like so:
bool success = barShader.Compile( bar::vertex, bar::fragment );
This way, although I need to overlook a bit of C code in my glsl files, I get the best of glsl syntax highlighting without having to dynamically load the file.
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 );
}
);
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
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 );
}
);