GCC, stringification, and inline GLSL?

匿名 (未验证) 提交于 2019-12-03 02:26:02

问题:

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:

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


回答2:

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.



回答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


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