В языке шейдеров OpenGL входные параметры копируются в функцию сразу после вызова, а выходные параметры копируются обратно перед выходом из нее. Так как функция работает только с копиями параметров, она не имеет доступа к внешним данным, которые, в свою очередь, не получают дополнительных псевдонимов. Входные параметры функции обозначаются спецификатором i п, выходные - спецификатором out, а входные и выходные одновременно - спецификатором mout (если не указано конкретно, параметры считаются входными).
2.5. Обзор системы
В предыдущем разделе были описаны некоторые элементы OpenGL, которые позволяют приложениям программировать графические ускорители. В следующем разделе рассматривается их совместная работа.
2.5.1. Модель драйвера
Часть программного обеспечения, управляющая какой-либо аппаратурой и предоставляющая доступ к ней, называется драйвером. OpenGL - тоже драйвер: он предоставляет доступ к графическому ускорителю. Некоторые задачи OpenGL должны контролироваться или управляться средствами операционной системы.
OpenGL-шейдеры работают в среде выполнения программ OpenGL (рис. 2.4). Приложения передают команды OpenGL, вызывая функции, являющиеся частью OpenGL API. Новая функция OpenGL, gl СгеаteShaderObjectARB, позволяет приложениям выделить внутри драйвера OpenGL структуры данных, которые будут использованы для OpenGL-шейдера. Эти структуры данных называются шейдерные объекты. После создания шейдерного объекта приложение должно установить исходный код шейдера вызовом функции glShaderSourceARB, в которую передают-ся символьные строки с исходным кодом шейдера. Компилятор языка шейдеров на самом деле является частыо OpenGL-драйвера (см. рис. 2.4), Это одно из существенных отличий языка шейдеров OpenGL от других шейдерных языков, например Стэнфордского языка шейдеров, HLSL1 (от Microsoft) или Cg (от NVIDIA). В этих языках компилятор высокоуровневого языка шейдеров находится на уровень выше графического API и преобразует код в последовательность вызовов графического интерфейса, находящегося уровнем ниже. (Более подробное описание читатель найдет в главе 17.) При использовании языка шейдеров OpenGL исходный код шейдеров передается драйверу OpenGL, и для данного сочетания аппаратного и программного обеспечения шейдеры будут скомпилированы в присущий данной среде машинный код настолько эффективно, насколько это возможно.
Рис. 2.4. Модель выполнения OpenGL-шейдеров После загрузки кода шейдера в шейдерный объект OpenGL-драйвера его необходимо скомпилировать функцией gl Compi 1 eShaderARB. Программный объект - это структура данных, управляемая OpenGL. Она служит вместилищем шейдерных объектов. Приложения должны связывать шейдерные объекты с программным объектом командой glAttachObjectARB. При таком связывании скомпилированные шейдерные объекты могут быть скомпонованы вместе функцией gILinkProgramARB. Это одно из основных различий между языком шейдеров OpenGL и API, использующими уровень ассемблера, например, таким расширениями OpenGL, как ARB_vertex_program и ARB_f ragment_program - несколько разных шейдеров можно скомпоновать в одну программу. Для более сложных задач использование нескольких отдельно скомпилированных шейдерных объектов может оказаться предпочтительнее одного цельного блока уже скомпонованного кода.