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.


⇐ вернуться назад | | далее ⇒