Название: Компьютерная графика(Е.Н. Павенко)

Жанр: Информатика

Просмотров: 1429


2. наложение текстуры

Одного вывода изображений недостаточно для создания полноценных трехмерных сцен. Часто возникает потребность накладывать изображение на трехмерные объекты и поворачивать/сдвигать их. Для этих целей существуют текстуры. Также текстуры помогут вам покрыть весь объект в виде мозаики. Скажем, когда у вас имеется кирпичная стена, то вам не надо загружать изображение с кучей кирпичей. Достаточно загрузить один кирпич и указать, что эту текстуру нужно размножить по всей плоскости.

Для того чтобы наложить текстуру на объект, вы должны:

1. Загрузить графический файл в память.

2. Создать имя-идентификатор текстуры.

3. Сделать его активным.

4. Создать саму текстуру в памяти.

5. Установить параметры текстуры.

6. Установить параметры взаимодействия текстуры с объектом.

7. Связать координаты текстуры с объектом.

1. Загрузка графического файла выполняется в соответствии с п. 1 лабораторной работы.

2. Создать имя-идентификатор текстуры.

При использовании в сцене нескольких текстур в OpenGL применяется подход, напоминающий создание списков изображений. Вначале с помощью команды

void glGenTextures(GLsizei n, GLuint*textures)

надо создать n идентификаторов для используемых текстур, которые будут записаны в массив textures.

Для единственной текстуры в приложении можно использовать следующую последовательность операторов:

static GLuint texName;

glGenTextures(1, &texName);

3. Сделать имя текстуры активным.

Перед началом определения свойств очередной текстуры следует вызвать команду

void glBindTexture(GLenum target, GLuint texture),

где target может принимать значения GL_TEXTURE_1D или GL_TEXTURE_2D, а параметр texture должен быть равен идентификатору той текстуры, к которой будут относиться последующие команды. Для того чтобы в процессе рисования сделать текущей текстуру с некоторым идентификатором, достаточно опять вызвать команду glBindTexture() c соответствующим значением target и texture. Таким образом, команда glBindTexture() включает режим создания текстуры с идентификатором texture, если такая текстура еще не создана, либо режим ее использования, т. е. делает эту текстуру текущей. Например,

glBindTexture(GL_TEXTURE_2D, texName);

4. Создание текстуры в памяти.

Теперь создать саму текстуру в памяти. Массив байт в структуре AUX_RGBImageRec не является еще текстурой, потому что у текстуры много различных параметров. Создав текстуру, мы наделим ее определенными свойствами. Среди параметров текстуры вы указываете уровень детализации, способ масшабирования и связывания текстуры с объектом. Уровень детализации нужен для наложения текстуры на меньшие объекты, т.е. когда площадь на экране меньше размеров изображения. Нулевой уровень детализации соответствует исходному изображению размером 2nx2m, первый уровень – 2n-1x2m-1, k-й уровень – 2n-kx2m-k. Число уровней соответствует min(n,m). Для создания текстуры имеется две функции glTexImage[1/2]D и gluBuild[1/2]DMipmaps.

glTexImage2D(                 gluBuild2DMipmaps(

  GLenum target,                 GLenum target,  

  GLint lavel,                       GLint components,   

  GLint components,            GLsizei width,

  GLsizei width,                   GLsizei height,

  GLsizei height,                  GLenum format,

  GLint border,                    GLenum type,

  GLenum format,               const GLvoid* pixels)       

  GLenum type,

  const GLvoid* pixels)

Основное различие в том, что первая функция создает текстуру одного определенного уровня детализации и воспринимает только изображения, размер которых кратен степени двойки. Вторая функция более гибкая. Она генерирует текстуры всех уровней детализации. Также эта функция не требует, чтобы размер изображения был кратен степени двойки. Она сама сожмет/растянет изображение подходящим образом, хотя возможно окажется, что и не вполне подходящим. Я воспользуюсь функцией glTexImage2D. Первый параметр этой функции должен быть GL_TEXTURE_2D. Второй – уровень детализации. Нам нужно исходное изображение, поэтому уровень детализации – ноль. Третий параметр указывает количество компонентов цвета. У нас изображение хранится в формате RGB. Поэтому значение этого параметра равно трем. Четвертый и пятый параметры – ширина и высота изображения. Шестой – ширина границы; у нас гарницы не будет, поэтому значение этого параметра – ноль. Далее, седьмой параметр – формат хранения пикселей в массиве – GL_RGB и тип – GL_UNSIGNED_BYTE. И, наконец, восьмой параметр – указатель на массив данных. Еще вы должны вызвать функцию glPixelStorei и задать, что выравнивание в массиве данных идет по байту.

 Добавьте следующий код в функцию main.

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, 3,

             photo_image->sizeX,

             photo_image->sizeY,

             0, GL_RGB, GL_UNSIGNED_BYTE,

             photo_image->data);

Аналогичный результат можно получить, вставив вызов gluBuild2DMipmaps с параметрами, указанными ниже.

gluBuild2DMipmaps(GL_TEXTURE_2D, 3,

                  photo_image->sizeX,

                  photo_image->sizeY,

                  GL_RGB, GL_UNSIGNED_BYTE,

                  photo_image->data);

 

5. Установить параметры текстуры.

Теперь нужно установить параметры текстуры. Для этого служит функция

glTexParameter[if](GLenum target, GLenum pname, GLenum param)

Первый параметр принимает значение GL_TEXTURE_1D или GL_TEXTURE_2D. Второй – pname – определяет параметр текстуры, который вы будете изменять. И третий параметр – это устанавливаемое значение. Если вы воспользовались gluBuild2DMipmaps вместо glTexImage2D, то вам не надо устанавливать следующие параметры, так как уже сформированы текстуры всех уровней детализации, и OpenGL сможет подобрать текстуру нужного уровня, если площадь объекта не совпадает с площадью текстуры. В противном случае, Вы должны добавить следующие строки:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Вы указали, что для уменьшения и увеличения текстуры используется алгоритм GL_NEAREST. Это означает, что цветом пикселя объекта, на который накладывается текстура, становится цвет ближайшего пикселя элемента текстуры. Вместо GL_NEAREST можно указать GL_LINEAR, т.е. цвет элемента объекта будет вычисляться как среднее арифметическое четырех элементов текстуры. Имеются еще четыре алгоритма вычисления цвета элемента объекта. Их можно устанавливать, когда вы создали текстуру со всеми уровнями детализации, т.к. применяют алгоритмы GL_NEAREST и GL_LINEAR к одному или двум ближайшим уровням детализации.

6. Установка параметров взаимодействия текстуры с объектом.

Вы можете установить взаимодействие текстуры с объектом. Тут имеются два режима при использовании трех компонентов цвета. Первый режим, установленный по умолчанию, – когда у вас учитывается цвет объекта и цвет текстуры. Результирующий цвет получается перемножением компонентов цвета текстуры на компоненты цвета объекта. Скажем, если цвет текстуры – (r,g,b), а цвет объекта, на который она накладывается, – (r0,g0,b0), то результирующим цветом будет – (r*r0,g*g0,b*b0). В случае, если цвет объекта черный – (0,0,0), то вы не увидите на нем текстуру, так как она вся будет черной. Второй режим взаимодействия, когда цвет объекта не учитывается. Результирующим цветом будет цвет текстуры. Эти параметры можно установить следующим образом.

glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)

glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)

По умолчанию используется режим GL_MODULATE. На этом заканчивается создание текстуры.

6. Связь координат текстуры с объектом.

Осталось связать координаты текстуры с координатами объекта.

void glTexCoord{1234}{sifd}(TYPEcoords);

void glTexCoord{1234}{sifd}v(TYPE *coords);

Функция устанавливает соответствие текущих координат текстуры (s, t, r, q) с координатами вершины примитива OpenGL, следующей за этой командой. При исползовании функции glTexCoord2*() небходимо определить только координаты s и t.

Например, чтобы связать координаты текстуры с вершинами прямоугольника, можно использовать следующую последовательность команд в функции display:

 glEnable(GL_TEXTURE_2D);

 glColor3d(1,1,1);

 glBindTexture(GL_TEXTURE_2D, space_tex );

  glBegin(GL_QUADS);

     glTexCoord2d(0,0); glVertex3d(-5,-5, -0.1);

     glTexCoord2d(0,1); glVertex3d(-5, 5, -0.1);

     glTexCoord2d(1,1); glVertex3d( 5, 5, -0.1);

     glTexCoord2d(1,0); glVertex3d( 5,-5, -0.1);

  glEnd();

 glDisable(GL_TEXTURE_2D);

glTexCoord2d сопоставляет координаты текстуры вершинам четырехугольника. Нижний левый угол текстуры имеет координаты (0,0), а верхний правый – (1,1).

Порядок выполнения работы

1. Получить средствами OpenGL  изображение .bmp- файла, заданного преподавателем.

2. Наложить изображение этого файла на все грани куба из лабораторной работы № 4.

Контрольные вопросы

Вывод графических изображений на экран средствами OpenGL.

Назначение текстуры. Наложение текстуры на объект средствами OpenGL.

Форматы графических файлов.

Организация видеопамяти персональных компьютеров в режимах SVGA.

 Организация видеопамяти персональных компьютеров в режимах VGA 12h, 13h.