So like many that have dealt with OpenGL Shaders in the past being able to write them without an extra program to convert them into a string has always been a want. So what I am looking for is a way to replace enter presses\newline characters in the source code with "\n" for example:
const char *sShaderSrc =
ConvertTextToString(
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4 mModel;
uniform mat3 mNormal;
uniform mat4 mViewProj;
varying vec3 vNormal;
void main()
{
gl_Position = (mViewProj *mModel) * vec4(aPos,1.0) ;
vNormal = mNormal*aNormal;
}
)
;
and then the preprocessor would convert it into
const char *sShaderSrc =
"#version 330 core\n\nlayout (location = 0) in vec3 aPos;\nlayout (location = 1) in vec3 aNormal;\n\nuniform mat4 mModel;\nuniform mat3 mNormal;\nuniform mat4 mViewProj;\n\nvarying vec3 vNormal;\n\nvoid main()\n{\n gl_Position = (mViewProj *mModel) * vec4(aPos,1.0);\n vNormal = mNormal*aNormal;\n}\n"
;
that way if OpenGL gives errors when compiling then I get shader line numbers in the error message.
Help would be much appreciated. The only edge case I could think of is also dealing with the case if the text editior inserts "\r\n" or "\n".
I have tried
#define RAWSTRINGIFY(x) R#x
//then you do
RAWSTRINGIFY((
//glsl code here...
))
but doesn't work the straight insertion
CodePudding user response:
A Macro Solution (and why it doesn't work for your purpose)
This can be implemented as a variadic macro so that it actually compiles.
#define ConvertTextToString(...) #__VA_ARGS__
Unfortunately, there are two problems preventing this from being useful in the scenario.
- It still doesn't preserve the newlines, as the newlines are not passed to the macro. Macro expansion is done after tokenization, which means that by the time a macro is expanded, all the newlines are already gone. See C preprocessor stringification that preserves newlines?
- The
#version 330 core
is seen by the compiler as a preprocessor directive, which causes errors like this. There's no solution around this.
main.cpp:6:2: error: invalid preprocessing directive
#version 330 core
Using Raw String Literals
A solution to your intended use case (i.e. multiline string literals) is to use raw string literals in C . For example,
const char* shaderSrc = R""""(
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
// ...
)"""";