inout vec3 coord) ^ // Копируется при входе и при выходе.
Или
vec3 ComputeCoord( const vec3 normal. it нельзя записывать в normal vec3 tangent,
in vec3 coord) // функция вернет результат
Следующие объявления некорректны:
void ComputeCoord(const out vec3 normal, // нельзя записывать в normal
const inout vec3 tang, // нельзя записывать в tang
in out vec3 coord) // неверно: следует использовать
//inout
Функции возвращают либо какое-то значение, либо ничего. Если функция ничего не возвращает, ее надо объявлять как voi d. Если функция возвращает значение, оно может быть любого типа, кроме массива, хотя и массивы могут возвращаться в составе структур.
3.6.3. Встроенные функции
В языке шейдеров OpenGL доступен обширный набор встроенных функций. Они подробно описаны в главе 5.
Шейдер может переопределить любую из этих функций. Чтобы переопределить функцию, нужно объявить ее прототип или определение в области видимости шейдера. При этом компилятор или компоновщик, встретив вызов этой функции, будет искать определенную шейдером реализацию, чтобы переадресовать вызов туда. Например, одна из встроенных тригонометрических функций объявлена как
float sintfloat х): Если шейдер хочет переопределить эту функцию или специализировать ее для конкретного типа параметров, это можно сделать следующим образом:
float siп(f 1 oat х)
{
return <.. какая-то функция от х..>
}
void mainO
{
// вызывается функция, определенная ранее, а не встроенная float s = sin(x):
)
Это напоминает стандартные приемы компоновки разных библиотек и функций, где преимуществом обладает локальная функция - если функция определена, то вызывается именно она, а не функция из внешней библиотеки. Если определение такой функции находится в другом шейдере, нужно просто перед вызовом этой функции указать в текущем шейдере ее прототип. В противном случае будет использоваться встроенная функция.
3,7. Операции
В табл. 3.1 в порядке приоритетности приведены операторы, доступные в языке шейдеров OpenGL. Приоритетность и ассоциативность совместимы с С.
Таблица 3.1. Операторы в порядке приоритетности
Оператор |
Описание |
[] |
Индекс |
Выбор компонента | |
++ -- |
Постфиксный инкремент/декремент |
++ -- |
Префиксный инкремент/декремент |
■! |
Унарное отрицание и логическое «НЕ» |
*! |
Умножение и деление |
+ - |
Сложение и вычитание |
<><=>= |
Относительные |
= = ! = |
Равенства |
&& |
Логическое «И» |
.Л Л |
Логическое «исключающее ИЛИ» |
II |
Логическое «ИЛИ» |
Выбор | |
= += -= *= /= |
Присваивание |
Последовательность |
3.7.1. Обращение по индексу
К векторам, матрицам и массивам можно обращаться с помощью оператора индекса ([ ]). Все индексы начинаются с нуля; первый элемент всегда имеет индекс 0. Индексирование массива такое же, как в С.
Оператор индекса для вектора возвращает скалярный компонент. Это позволяет компонентам вектора иметь номера 0, 1… и обеспечивает произвольный ДОС' туп к ним,например: