GCC, строение и встроенный GLSL?
Я хотел бы объявить строковые строки GLSL inline с помощью макроснижения:
#define STRINGIFY(A) #A
const GLchar* vert = STRINGIFY(
#version 120\n
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
);
Это строит и работает отлично, используя VS2010, но не компилируется на gcc
с помощью:
error: invalid preprocessing directive #version
Есть ли способ использовать такую строчку в переносном режиме?
Я пытаюсь избежать кавычек в каждой строке:
const GLchar* vert =
"#version 120\n"
"attribute vec2 position;"
"void main()"
"{"
" gl_Position = vec4( position, 0.0, 1.0 );"
"}"
;
... и/или продолжение строки:
const GLchar* vert = "\
#version 120\n \
attribute vec2 position; \
void main() \
{ \
gl_Position = vec4( position, 0.0, 1.0 ); \
} \
";
Ответы
Ответ 1
К сожалению, наличие директив препроцессора в аргументе макроса undefined, поэтому вы не можете сделать это напрямую. Но пока ни одному из ваших шейдеров не нужны директивы препроцессора, кроме #version
, вы можете сделать что-то вроде:
#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
Можете ли вы использовать С++ 11? Если это так, вы можете использовать необработанные строковые литералы:
const GLchar* vert = R"END(
#version 120
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
)END";
Нет необходимости в экранах или явных переводах строк. Эти строки начинаются с R (или r). Вам нужен разделитель (я выбрал END) между цитатой и первой скобкой, чтобы избежать скобок, которая у вас есть в фрагменте кода.
Ответ 3
Проблема связана с макросами предварительной обработки gcc, предназначенными для GLSL. Использование стандартных строковых и экранирующих директив препроцессора с новыми строками в коде GLSL сработало для меня.
#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
Для достижения этой цели я использовал sed. У меня есть отдельные файлы с GLSL, которые я редактирую (с правильной подсветкой синтаксиса), и в то же время GLSL встроен в С++. Не очень перекрестная платформа, но с msys она работает под окнами.
В коде С++:
const GLchar* vert =
#include "shader_processed.vert"
;
В 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