В GLSL доступны следующие простые типы данных:
- float
- bool
- int
Эти типы данных — точно такие же, как в C.
Также доступны векторы для перечисленных выше типов данных с двумя, тремя или четырьмя компонентами.
Она обьявляются как:
- vec{2,3,4} — вектор из 2/3/4 float
- bvec{2,3,4} — вектор из 2/3/4 bool
- ivec{2,3,4} — вектор из 2/3/4 int
Также доступны квадратные матрицы 2×2, 3×3 и 4×4, т.к. они часто используются в графике.
Соответствующие типы данных:
- mat2
- mat3
- mat4
Также доступен ряд специальных типов данных для работы с текстурами. Они называются «samplers» и
нуждаются в доступе к значениям текстур, так же известным как «texels». Типы данных:
- sampler1D — для 1D-текстур
- sampler2D — для 2D-текстур
- sampler3D — для 3D-текстур
- samplerCube — для текстур кубических карт
- sampler1DShadow — для карт теней
- sampler2DShadow — для карт теней
Массивы в шейдерах обьявляются так же, как в C, однако они не могут быть инициализированы при обьявлении.
Доступ к элементам — такой же, как в C.
Также в GLSL доступны структуры. Синтаксис такой же, как в C:
vec3 direction;
vec3 color;
};
Переменные
Объявление простых переменных — точно такое же, как в C, вы даже можете инициализировать
переменную при объявлении.
int c=2; // Обьявление и инициализация «c»
bool d = true; // d = true
Объявление других типов переменных соответствует тому же принципу, но есть отличия от C касаемо инициализации. GLSL нужен конструктор для указания типа данных и инициализации.
float e = (float)2; // Неправильно, для указания типа вызывается конструкторint a=2;
float c = float(a); // Правильно, c == 2.0
vec3 f; // Обьявление f как vec3
vec3 g = vec3(1.0, 2.0, 3.0); // Обьявление и инициализация вектора g
GLSL приятно гибок в отношении инициализации переменных. Всё, что нужно — передать соответствующее типу данных число переменных. Посмотрите примеры:
vec2 b = vec2(3.0, 4.0);vec4 c = vec4(a,b); // c = vec4(1.0, 2.0, 3.0, 4.0)
vec2 g = vec2(1.0, 2.0);
float h = 3.0;
vec3 j = vec3(g,h);
Матрицы тоже соответствуют этому принципу. К вашим услугам широкий выбор конструкторов матриц.
Например, доступны следующие конструкторы:
mat4 m = mat4(1.0) // инициализация диагонали матрицы с 1.0
vec2 a = vec2(1.0,2.0);
vec2 b = vec2(3.0,4.0);
mat2 n = mat2(a,b);
mat2 k = mat2(1.0,0.0,1.0,0.0); // указаны все элементы
Пример объявления и инициализации структур:
vec3 direction;
vec3 color;
};dirlight d1;
dirlight d2 = dirlight(vec3(1.0,1.0,0.0), vec3(0.8,0.8,0.4));
Также в GLSL реализованы некоторые возможности, упрощающие нам жизнь и делающие код немного чище. Так же, как и в стандартном C, для присваивания векторам значений можно использовать буквы:
float posX = a.x;
float posY = a[1];vec2 posXY = a.xy;
float depth = a.w;
Как показано в этом коде, для доступа к компонентам вектора можно использовать буквы x,y,z,w.
Если речь идет о цветах, можно использовать буквы r,g,b. Для текстурных координат — s,t,p,q.
Имейте в виде, что по соглашению текстурные координаты часто обьявлялись как s,t,r,q. Однако «r» уже занят для «RGBA». Пришлось искать другую букву, и выбор пал на «p».
Селекторы матриц могут занимать 1 или элемента, например, m[0], или m[0][1]. В первом случае выбирается весь ряд, во втором — только один элемент из него.
Что до структур, то их селекторы работают точно так же, как в C, так что для структуры описанной выше может быть написано:
Квалификаторы переменных
Квалификаторы задают переменным особый смысл. В GLSL доступны следующие:
- const — обьявление константы
- attribute — Глобальные переменные, которые могут изменятся для каждой вершины, и передаются
в вершинные шейдеры. Может использоватся только в них. Для шейдера переменная — read-only. - uniform — глобальная переменная, которая может изменятся для каждого полигона (не может быть
между glBegin/glEnd), передаётся OpenGL в шейдеры. Может использоваться в обоих типах
шейдеров, для шейдеров является read-only. - varying — используются для передачи интерполированных данных между вершинным и пикселным шейдерами.
Доступны для записи в вершинном шейдере, и read-only для пикселного шейдера.