2010-03-04 11 views
19

GLSL имеет полный препроцессор C-стиля. Единственное, что не работает, - #include. Одна из замечательных особенностей заключается в том, что вы можете использовать #ifdef для комментирования функций и, таким образом, создать один шейдер, который может быть разрежен, если некоторые функции не используются.Внешние определения макросов препроцессора в GLSL

Мой вопрос:

Есть ли способ определить макрос из кода C?

Невозможно сделать это с помощью интерфейса openGL. Быстрый взлом - это добавить несколько строк с #define FOO до загрузки файла формы. Но это похоже на обратную сторону.

ответ

23

Вам не нужно добавлять его к загруженному вами коду. Вот почему в glShaderSourceARB API есть несколько строк.

Что-то вроде следующего делает то, что вы ищете:

char *sources[2] = { "#define FOO\n", sourceFromFile }; 
glShaderSourceARB(shader, 2, sources, NULL); 
+4

Это допустимое решение, но не намного лучше, чем добавление исходного кода. – rioki

+2

хорошо, это зависит от того, что вам нужно. Это хорошо, чтобы предотвратить некоторое дополнительное распределение памяти и копировать (именно поэтому я бы рассмотрел взломанное решение preend). Что будет выглядеть лучше для вас и почему? – Bahbar

+1

Я думал больше о строках 'glDefine (« Moo »,« Foo »)' ... но, похоже, я правильно изучил спецификации ... – rioki

6

Вот что я использую, чтобы избежать #version проблем. Это Java и не оптимизирован для perfo, но он отлично работает:

// extract shader sourcecode from file 
StringBuilder shaderSource = Tools.readTextRessource(shaderSrcFile.url); 

// apply defined values 
int versionIndex = shaderSource.indexOf("#version"); 
if(versionIndex == -1) err("missing #version xxx in shader "+shaderSrcFile.name()); 
int defineInsertPoint = shaderSource.indexOf("\n", versionIndex)+1; 

for (int i = defined.size() - 1; i >= 0; --i) 
    shaderSource.insert(defineInsertPoint, "#define " + defined.get(i) + "\n"); 
Смежные вопросы