glActiveTexture(GL_TEXTUREO);
gl BincJTexture (GL_TEXTURE_2D. earthTexName): Эта последовательность вызовов сделает текстурный модуль 0 активным, присоединит текстуру с изображением земли к этому модулю и активизирует ее. Нужно также задать значения двум uniform-переменным. Вершинному шейдеру необходимо знать координаты источника освещения, а фрагментному шейдеру - к какому текстурному модулю нужно обратиться. Координаты источника освещения будут определяться как vec3 в вершинном шейдере под именем lightPosition, а текстурный модуль - как samplегЗО во фрагментном шейдере под именем Earth Texture. Код приложения должен узнать, где находятся эти uniform-переменные, и задать им правильные значения. Предположим, что шейдеры уже скомпилированы, скомпонованы в программном объекте programObj и установлены как часть текущего состояния. Для инициализации uniform-переменных выполним следующий код:
lightLoc = gTGetUniformLocationARBCprogramObj. ''LightPosition"):
glUniforrii3fARB(lightLoc. 0.0, 0.0. 4.0):
texLoc = glGetUniformlocationARBtprogramObj. "EarthTexture"): gl Uniformli AR3(texLoc, 0); Координаты источника освещения соответствуют точке, расположенной на линии обзора перед объектом. Пусть для текстуры изображения земли используется текстурный модуль 0, тогда именно это значение нужно занести в переменную-семплер.
Приложение может вызывать функции OpenGL для рисования сферы, потом на нее будет наложена текстура с изображением Земли. Для каждой вершины должны быть заданы нормаль поверхности, двухмерные координаты текстуры и координаты вершины.
10.2.2. Вершинный шейдер
Вершинный шейдер, используемый в этом простом примере, очень похож на простой шейдер кирпичной стены (см. раздел 6.2). Главное отличие в том, что здесь текстурные координаты передаются как вершинные атрибуты, через встроенную varying-переменную gl_TexCoord[G] (листинг 10.1).
Листинг 10.1. Вершинный шейдер для простого наложения текстуры
varying float Lightlntensity: uniform vec3 LightPosition:
const float SpecularContribution = 0.1:
const float diffuseContribution = 1.0 - SpecularContribution:
void main(vaid)
{
vec3 ecPosition = vec3 {gl_ModelV1ewMatrix * gl_Vertex): vec3 tnorm = normaltzetgl JtormalMatrix * gljtormal); vec3 lightVec = normalizeTlightPosition - ecPosition).; vec3 reflectVec = reflect(-lightVec. tnorm}: vec3 viewVec = normalize(-ecPositioh):
float spec = clampCdoUreflectVec, viewVec). 0.0. 1.0); spec = pow(spec. 16.0).;
Lightlntensity = diffuseContribution * max(dot(li'ghtVec, tnorm). 0.0)
+ SpecularContribution * spec;
gl_TexCoord[0] = gl^MultiTexCoordO: g]_Position = ftransformO:
}
10.2.3. Фрагментный шейдер
Фрагментный шейдер (листинг 10.2) будет накладывать текстуру на входные геометрические фигуры. Например, если определена сфера, где текстурная координатам обозначает долготу (то есть 0° долготы - s = 0, 360° долготы - s ~ 1,0), а текстурная координата £ обозначает широту (90° южной широты - t = 0,0, а 90° северной широты - £ = 1,0), можно наложить текстуру на сферу так, как показано на цветном рис. 3.