-
Hi.
I try to load a shader from memory, which use the version 130 of GLSL but it fails to compile :
const std::string vertexCode =
"#version 130"
"attribute vec3 vertexPosition_modelspace;"
"attribute vec3 vertex_color;"
"out vec3 color;"
"void main() {"
"vec4 vertex = vec4(vertexPosition_modelspace.xyz, 1.0f);"
"gl_Position = gl_ModelViewProjectionMatrix * vertex;"
"color = vertex_color;"
"}";
const std::string fragmentCode =
"#version 130"
"in vec3 color;"
"out vec3 fragmentColor;"
"void main() {"
"fragmentColor = color;"
"}";
Here is the error :
preprocessor error : syntax error, unexcepted identifier, unexpected new line.
Is there a way to do this ?
-
The #version 130 directive must be on its own line.
Having the shader code on multiple lines does not automatically insert newline characters. The string literals are simply concatenated without intermediate whitespace. Is there a specific reason why you don't outsource GLSL code into its own file?
-
Haaa, oké, ty!
I just want that the shader code is internal of my framework, because, it's a part of the pipeline of my framework, so, I don't want to put them into a file.
-
#define TO_STRING(x) #x
const std::string vertexCode =
TO_STRING
(
#version 130
attribute vec3 vertexPosition_modelspace;
attribute vec3 vertex_color;
out vec3 color;
void main() {
vec4 vertex = vec4(vertexPosition_modelspace.xyz, 1.0f);
gl_Position = gl_ModelViewProjectionMatrix * vertex;
color = vertex_color;
};
)
-
This will lead to problems when there are commas in the macro argument. Variadic macros (C++11) can help, but then the stringize operator can't be applied directly anymore and things get more complicated. And I'm not sure whether the line break is preserved then.
The preprocessor can be very complex when it comes to things like this, I've once written a bunch of preprocessor metaprogramming tools in Aurora (http://www.bromeon.ch/libraries/aurora/v1.0/doc/group___meta.html), and it was massive trial and error. Maybe AURORA_PP_STRINGIZE would help.
-
Why not ditch all the complexity and preprocessor magic and just put the shader in a file of its own???
-
If you can use C++11, raw string literals should make this a lot easier.
-
This will lead to problems when there are commas in the macro argument.
That's what I thought too, but I used it recently with a fragment shader containing commas, and had no problem.
-
This code works for me :
const std::string vertexShader = TO_STRING(
#pragma #version 130
void main () {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
}
);
Thanks.
-
Finally the solution was very simple !
const std::string depthGenFragShader = TO_STRING (
"#version 130 \n"
"uniform sampler2D depthBuffer;"
"uniform sampler2D texture;"
"uniform vec3 resolution;"
"void main () {"
"vec2 position = ( gl_FragCoord.xy / resolution.xy );"
"vec4 color = texture2D(depthBuffer, position);"
"vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);"
"if (gl_FragCoord.z > color.z && pixel.a >= color.a) {"
"gl_FragColor = vec4(0, 0,gl_FragCoord.z, pixel.a);"
"} else {"
"gl_FragColor = color;"
"}"
"}";
You even don't need the use of a macro. :)