3.5.5. Отсутствие спецификатора
Если спецификатор для переменной вообще не указан и она не является описанием параметра функции, то шейдер может и читать из нее значения, и записывать их в нее. Такие переменные, объявленные в глобальной области видимости, могут использоваться совместно шейдерами одного и того же типа, скомпонованными в одну программу. И вершинные, и фрагментные шейдеры могут иметь собственные пространства имен для переменных без квалификаторов. Вне программы такие переменные не видимы. Такие права доступа зарезервированы для переменных, определенных как attribute или uniform, а также для встроенных переменных состояния OpenGL.
Время существования переменных без спецификатора ограничено одним запуском шейдера. В языке шейдеров OpenGL не существует понятия «статическая переменная», как в функциях языка С, что позволило бы сохранить значение переменной от одного запуска шейдера до другого, так как это противоречит концепции параллельной обработки (возможность одновременно обрабатывать разные данные, используя одну и ту же память). Обычные переменные, используемые шейдером, не могут быть использованы совместно в параллельной обработке.
Из-за того, что такие глобальные переменные находятся в разных пространствах имен для разных шейдеров, невозможно через них передать информацию между вершинным и фрагментным шейдерами. Переменные, предназначенные только для чтения и используемые совместно, должны быть объявлены как uniform, а переменные, в которые записывает значения вершинный шейдер, а считывает их - фрагментный, должны быть объявлены как varying.
3.6. Последовательность выполнения
Последовательность выполнения программы на языке шейдеров OpenGL похожа на выполнение С++-программы. Точка входа в шейдер - функция main. В программе с разными шейдерами существует две точки входа mi п: одна для вершинного шейдера, для обработки каждой вершины, а другая - для фрагментного, для обработки каждого фрагмента. Перед входом в функцию main выполняется инициализация глобальных переменных.
Организация циклов выполняется с помощью операторов for, while, do-while так же, как и в C++. Переменные можно объявлять в for и while, и область их действия распространяется только на тело цикла. Ключевые слова break и conti nue имеют такое же назначение, как и в С.
Условия можно задавать операторами i f и i f-el se, как и в C++, но здесь нельзя объявлять переменные в операторе i f. Есть также оператор выбора (?:) со следующим ограничением: тип второго операнда должен совпадать с типом третьего.
Тал выражения, переданный в операторы i f и whi 1 е, а также второй операнд for должны иметь логический тип. Как и в С, правый операнд логического «И» fffl) не вычисляется, если левый является false, а правый операнд логического «ИЛИ» ([ |) не вычисляется, если левый является true. Точно так же не будет вычисляться один из операндов оператора выбора (:?). Логическое «исключающее ИЛИ» здесь существует, и для него всегда вычисляются оба операнда.
Специальный оператор discard может запретить записывать фрагмент в кадровый буфер. Если выполнение доходит до этого оператора, текущий фрагмент считается отброшенным. Реализация может продолжать или завершать выполнение шейдера, а данный оператор всего лишь гарантирует, что кадровый буфер не изменится.