ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 09.06.2020
Просмотров: 1710
Скачиваний: 4
51
Эти
два
этапа
создания
образа
текстуры
во
внутренней
памяти
OpenGL
можно
провести
с
помощью
команды
void
gluBuild2DMipmaps
(GLenum
target
, GLint
components
,
GLint
width
, GLint
height
,
GLenum
format
, GLenum
type
,
const void *
data
)
где
параметр
target
должен
быть
равен
GL_TEXTURE_2D.
Параметр
components
определяет
количество
цветовых
компонент
текстуры
и
может
принимать
следующие
основные
значения
:
GL_LUMINANCE
одна
компонента
–
яркость
. (
текстура
будет
монохромной
)
GL_RGB
красный
,
синий
,
зеленый
GL_RGBA
все
компоненты
.
Параметры
width
,
height
,
data
определяют
размеры
и
расположение
текстуры
соответственно
,
а
format
и
type
имеют
аналогичный
смысл
,
что
и
в
команде
gluScaleImage()
.
После
выполнения
этой
команды
текстура
копируется
во
внутреннюю
память
OpenGL,
и
поэтому
память
,
занимаемую
исходным
изображением
,
можно
освободить
.
В
OpenGL
допускается
использование
одномерных
текстур
,
то
есть
размера
1xN,
однако
,
это
всегда
надо
указывать
,
задавая
в
качестве
значения
target
константу
GL_TEXTURE_1D
.
Полезность
одномерных
текстур
сомнительна
,
поэтому
не
будем
останавливаться
на
этом
подробно
.
При
использовании
в
сцене
нескольких
текстур
,
в
OpenGL
применяется
подход
,
напоминающий
создание
списков
изображений
(
так
называемые
текстурные
объекты
).
Сначала
с
помощью
команды
void
glGenTextures
(GLsizei
n
, GLuint*
textures
)
надо
создать
n
идентификаторов
текстур
,
которые
будут
записаны
в
массив
textures
.
Перед
началом
определения
свойств
очередной
текстуры
следует
сделать
ее
текущей
(«
привязать
»
текстуру
),
вызвав
команду
void
glBindTexture
(GLenum
target
, GLuint
texture
)
52
где
target
может
принимать
значения
GL_TEXTURE_1D
или
GL_TEXTURE_2D
,
а
параметр
texture
должен
быть
равен
идентификатору
той
текстуры
,
к
которой
будут
относиться
последующие
команды
.
Для
того
,
чтобы
в
процессе
рисования
сделать
текущей
текстуру
с
некоторым
идентификатором
,
достаточно
опять
вызвать
команду
glBindTexture()
c
соответствующим
значением
target
и
texture
.
Таким
образом
,
команда
glBindTexture()
включает
режим
создания
текстуры
с
идентификатором
texture
,
если
такая
текстура
еще
не
создана
,
либо
режим
ее
использования
,
то
есть
делает
эту
текстуру
текущей
.
Так
как
не
всякая
аппаратура
может
оперировать
текстурами
большого
размера
,
целесообразно
ограничить
размеры
текстуры
до
256x256
или
512x512
пикселей
.
Отметим
,
что
использование
небольших
текстур
повышает
эффективность
программы
.
5.2.
Наложение
текстуры
на
объекты
При
наложении
текстуры
,
как
уже
упоминалось
,
надо
учитывать
случай
,
когда
размеры
текстуры
отличаются
от
оконных
размеров
объекта
,
на
который
она
накладывается
.
При
этом
возможно
как
растяжение
,
так
и
сжатие
изображения
,
и
то
,
как
будут
проводиться
эти
преобразования
,
может
серьезно
повлиять
на
качество
построенного
изображения
.
Для
определения
положения
точки
на
текстуре
используется
параметрическая
система
координат
(s,t),
причем
значения
s
и
t
находятся
в
отрезке
[0,1] (
см
.
рисунок
)
Для
изменения
различных
параметров
текстуры
применяются
команды
:
void
glTexParameter[i f]
(GLenum
target
, GLenum
pname
,
GLenum
param
)
Рис
. 8
Текстурные
координаты
s
t
(0,0)
(0,1)
(1,1)
(1,0)
53
void
glTexParameter[i f]v
(GLenum
target
, GLenum
pname
,
Glenum*
params
)
При
этом
target
может
принимать
значения
GL_TEXTURE_1D
или
GL_TEXTURE_2D
,
pname
определяет
,
какое
свойство
будем
менять
,
а
с
помощью
param
или
params
устанавливается
новое
значение
.
Возможные
значения
pname
:
GL_TEXTURE_MIN_FILTER
параметр
param
определяет
функцию
,
которая
будет
использоваться
для
сжатия
текстуры
.
При
значении
GL_NEAREST
будет
использоваться
один
(
ближайший
),
а
при
значении
GL_LINEAR
четыре
ближайших
элемента
текстуры
.
Значение
по
умолчанию
:
GL_LINEAR
.
GL_TEXTURE_MAG_FILTER
параметр
param
определяет
функцию
,
которая
будет
использоваться
для
увеличения
(
растяжения
)
текстуры
.
При
значении
GL_NEAREST
будет
использоваться
один
(
ближайший
),
а
при
значении
GL_LINEAR
четыре
ближайших
элемента
текстуры
.
Значение
по
умолчанию
:
GL_LINEAR
.
GL_TEXTURE_WRAP_S
параметр
param
устанавливает
значение
координаты
s,
если
оно
не
входит
в
отрезок
[0,1].
При
значении
GL_ REPEAT
целая
часть
s
отбрасывается
,
и
в
результате
изображение
размножается
по
поверхности
.
При
значении
GL_CLAMP
используются
краевые
значения
:
0
или
1,
что
удобно
использовать
,
если
на
объект
накладывается
один
образ
.
Значение
по
умолчанию
:
GL_REPEAT
.
GL_TEXTURE_WRAP_T
аналогично
предыдущему
значению
,
только
для
координаты
t.
Использование
режима
GL_NEAREST
повышает
скорость
наложения
текстуры
,
однако
при
этом
снижается
качество
,
так
как
в
отличие
от
GL_LINEAR
интерполяция
не
производится
.
Для
того
чтобы
определить
,
как
текстура
будет
взаимодействовать
с
материалом
,
из
которого
сделан
объект
,
используются
команды
54
void
glTexEnv[i f]
(GLenum
target
, GLenum
pname
,
GLtype
param
)
void
glTexEnv[i f]v
(GLenum
target
, GLenum
pname
,
GLtype *
params
)
Параметр
target
должен
быть
равен
GL_TEXTURE_ENV
,
а
в
качестве
pname
рассмотрим
только
одно
значение
GL_TEXTURE_ENV_MODE
,
которое
наиболее
часто
применяется
.
Наиболее
часто
используемые
значения
параметра
param
:
GL_MODULATE
конечный
цвет
находится
как
произведение
цвета
точки
на
поверхности
и
цвета
соответствующей
ей
точки
на
текстуре
.
GL_REPLACE
в
качестве
конечного
цвета
используется
цвет
точки
на
текстуре
.
Следующая
программа
демонстрирует
общий
подход
к
созданию
текстур
:
/*
нужное
нам
количество
текстур
*/
#define NUM_TEXTURES 10
/*
идентификаторы
текстур
*/
int TextureIDs[NUM_TEXTURES];
/*
образ
текстуры
*/
AUX_RGBImageRec *pImage;
…
/* 1)
получаем
идентификаторы
текстур
*/
glGenTextures(NUM_TEXTURES,TextureIDs);
/* 2)
выбираем
текстуру
для
модификации
параметров
*/
glBindTexture(TextureIDs[i]);
/* 0<=i<NUM_TEXTURES*/
/* 3)
загружаем
текстуру
.
Размеры
текстуры
–
степень
2 */
pImage=dibImageLoad("texture.bmp");
if (Texture!=NULL)
{
/* 4)
передаем
текстуру
OpenGL
и
задаем
параметры
*/
/*
выравнивание
по
байту
*/
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
gluBuildMipmaps(GL_TEXTURE_2D,GL_RGB, pImage->sizeX,
pImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
pImage->data);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,
(float)GL_LINEAR);
55
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
(float)GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
(float)GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
(float)GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
(float)GL_REPLACE);
/* 5)
удаляем
исходное
изображение
.*/
free(Texture);
}else Error();
5.3.
Текстурные
координаты
Перед
нанесением
текстуры
на
объект
необходимо
установить
соответствие
между
точками
на
поверхности
объекта
и
на
самой
текстуре
.
Задавать
это
соответствие
можно
двумя
методами
:
отдельно
для
каждой
вершины
или
сразу
для
всех
вершин
,
задав
параметры
специальной
функции
отображения
.
Первый
метод
реализуется
с
помощью
команд
void
glTexCoord[1 2 3 4][s i f d]
(type
coord
)
void
glTexCoord[1 2 3 4][s i f d]v
(type *
coord
)
Чаще
всего
используется
команды
вида
glTexCoord2*(type s,
type t)
,
задающие
текущие
координаты
текстуры
.
Понятие
текущих
координат
текстуры
аналогично
понятиям
текущего
цвета
и
текущей
нормали
,
и
является
атрибутом
вершины
.
Однако
даже
для
куба
нахождение
соответствующих
координат
текстуры
является
довольно
трудоемким
занятием
,
поэтому
в
библиотеке
GLU
помимо
команд
,
проводящих
построение
таких
примитивов
,
как
сфера
,
цилиндр
и
диск
,
предусмотрено
также
наложение
на
них
текстур
.
Для
этого
достаточно
вызвать
команду
void
gluQuadricTexture
(GLUquadricObj*
quadObject
,
GLboolean
textureCoords
)
с
параметром
textureCoords
равным
GL_TRUE
,
и
тогда
текущая
текстура
будет
автоматически
накладываться
на
примитив
.
Второй
метод
реализуется
с
помощью
команд
void
glTexGen[i f d]
(GLenum
coord
, GLenum
pname
,
GLtype
param
)