GCC, stringification, and inline GLSL?

久未见 提交于 2019-11-26 11:18:58

问题


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 );  \\
}                                              \\
\";

回答1:


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.




回答2:


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 );
    }
);



回答3:


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 );
}
);



回答4:


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


来源:https://stackoverflow.com/questions/13872544/gcc-stringification-and-inline-glsl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!