GCC, строение и встроенный GLSL? - программирование
Подтвердить что ты не робот

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

Ответ 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