GCC, stringification y GLSL en línea?

Me gustaría declarar las cadenas de sombreado GLSL en línea usando macro cadenas:

#define STRINGIFY(A) #A const GLchar* vert = STRINGIFY( #version 120\n attribute vec2 position; void main() { gl_Position = vec4( position, 0.0, 1.0 ); } ); 

Esto se comstack y funciona bien con VS2010 pero no comstack en gcc con:

 error: invalid preprocessing directive #version 

¿Hay alguna manera de usar una stringificación como esta de manera portátil?

Estoy tratando de evitar las cotizaciones por línea:

 const GLchar* vert = "#version 120\n" "attribute vec2 position;" "void main()" "{" " gl_Position = vec4( position, 0.0, 1.0 );" "}" ; 

… y / o continuación de línea:

 const GLchar* vert = "\ #version 120\n \ attribute vec2 position; \ void main() \ { \ gl_Position = vec4( position, 0.0, 1.0 ); \ } \ "; 

Desafortunadamente, tener directivas de preprocesador en el argumento de una macro no está definido, por lo que no puede hacer esto directamente. Pero mientras ninguno de sus sombreadores necesite directivas de preprocesador que no sean #version , podría hacer algo como:

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

¿Puedes usar C ++ 11? Si es así, podrías usar literales de cadena sin formato :

 const GLchar* vert = R"END( #version 120 attribute vec2 position; void main() { gl_Position = vec4( position, 0.0, 1.0 ); } )END"; 

No hay necesidad de escapes o nuevas líneas explícitas. Estas cadenas comienzan con R (o r). Necesitas un delimitador (elegí END) entre la cita y el primer paréntesis para escapar del paréntesis que tienes en el fragmento de código.

El problema se debe a las macros de preprocesamiento de gcc destinadas a GLSL. El uso de directivas de preprocesador stringify y escaping estándar con nuevas líneas en código GLSL funcionó para mí.

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

Para lograr este propósito utilicé sed. Tengo archivos separados con GLSL que edito (con el resaltado de syntax adecuado) y, al mismo tiempo, GLSL inlined en C ++. No es muy multiplataforma, pero con msys funciona bajo Windows.

En código C ++:

 const GLchar* vert = #include "shader_processed.vert" ; 

En 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