Посте того как информация о вершинах будет занесена в массив дополнительных атрибутов, нужно включить использование массивов. В этом случае дополнительные атрибуты будут передаваться вместе с обычными данными для вершин при вызове команд работы с массивами, например glDrawArrays. Чтобы включить или выключить работу с массивом дополнительных атрибутов, используются функции
void g!EnableVertexAttribArrayARB(GLuint index) void glDisableVertexAttribArrayARBCGLuint index)
Они включают или выключают работу с массивами дополнительных атрибутов вершин, указанными аргументом index. По умолчанию все подобные возможности выключены, в том числе и работа со всеми массивами дополнительных атрибутов вершин. При включении функциональности значения из этих массивов будут извлекаться и использоваться при рендеринге в функциях glArrayElement, gl DrawArrays, gl DrawEl ements, gl DrawRangeEl ements, gl Mul tiDrawArrays или gl Mul ti Draw-E1ements.
Это решает проблему передачи данных о вершинах в OpenGL. Но возникает вопрос: как потом получить эти данные из вершинного шейдера? Обращение по индексам - не очень хорошее решение, так как такие имена не наглядны и их использование может вызвать многочисленные ошибки. API языка шейдеров OpenGL предоставляет два способа доступа к дополнительным атрибутам вершин из вершинного шейдера.
Первый способ - компоновщик связывает параметры автоматически. В таком случае после компоновки приложение должно сделать запрос к OpenGL, чтобы определить индексы дополнительных атрибутов, которые в дальнейшем и использовать для передачи этих атрибутов.
Второй способ - приложение выбирает какой-либо индекс в массиве дополнительных атрибутов и связывает с ним некую attribute-переменную в вершинном шейдере до компоновки, используя функцию
void glBindAttribLocationARB{GLhandleARB program.
:SLuint index,
ccr.st GLcharARB *name)
Функция gl GetAtt ri bLocat i onARS возвращает последнее связывание, заданное до вызова функции gl LimkProgramARB для заданного программного объекта. Те связывания, что были заданы после компоновки, не возвращаются gl GetAtt ri bLocati onARB. Используя эти функции, создадим вершинный шейдер, который будет содержать определенную разработчиком attribute-переменную Opacity (способность закрывать объекты, расположенные на заднем плане), значение которой будет использоваться при вычислении освещения. Предположим, значения для этой переменной будет передаваться под индексом 1 и нужно выполнить соответствующее связывание:
glBindAttribtocationARBCmyProgram. 1, "Opacity”); После этого можно вызвать gl VertexAtt ri bARB для передачи значения для каждой вершины следующим образом: glVertexAttriblfARB(l. opacity); Функция gl VertexAttri bARB вызывается между вызовами функций glBegin и gl End. Она заменяет стандартные OpenGL-функции gl Col or, gl Normal и т. д. Но, как было замечено ранее, для увеличения скорости рисования рекомендуется использовать вершинные массивы.
Профессиональный жаргон в этом разделе может несколько сбить с толку, поэтому следует взглянуть на диаграмму, чтобы удостовериться в правильном понимании предмета. Рисунок 7.1 демонстрирует, как команды установки атрибутов вершин могут быть использованы для модификации значений встроенных переменных, определенных языком шейдеров OpenGL. Связывание между командами для установки стандартных атрибутов (цвет, нормаль, вершина и т. д.) и встроенных переменных (gl_Co1 or, gl_Normal, gl_Vertex и т. д.) происходит автоматически и таким образом, чтобы не противоречить дополнительным установленным атрибутам. Каждая из этих функций, за исключением gl Vertex, меняет состояние OpenGL. Значения встроенных attribute-переменных обновляются автоматически.