Руководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика
Скачать 0.66 Mb.
|
void glFog[if] (enum pname, T param) void glFog[if]v (enum pname, T params)d*z'; GL_EXP2 —интенсивность задается формулой / = е-^*2^ ;GL LINEAR —интенсивность вычисляется по формуле / = е — z/e — s, где z — расстояние от вершины, в которой вычисляется интенсивность тумана, до точки наблюдения. Коэффициенты d, e, s задаются с помощью следующих значений аргумента pname: GL_FOG_DENSITY — param определяет коээфициент d GL_FOG_START —param определяет коэффициент s GL FOG END —param определяет коэффициент е. Цвет тумана задается с помощью аргумента pname, равного GL_FOG_COLOR. В этом случае params — указатель на массив из 4-х компонент цвета. Приведем пример использования этого эффекта: GLfloat FogColor[4] = {0.5 ,0.5,0.5,1}; glEnable(GL_FOG); g 1F о g i (GL_FOG_MODE, GL_LEMEAR); glFogf (GL_FOG_START, 2 0.0); glFogf (GL_FOG_END, 100.0); glFogfv (GL_FOG_COLOR, FogColor ); 5.5. Контрольные вопросы Поясните разницу между локальными и бесконечно удаленными источниками света. Для чего служит команда glColorMaterial? Как задать положение источника света таким образом, чтобы он всегда находился в точке положения наблюдателя? Как задать фиксированное положение источника света? Можно ли задавать положение источника относительно локальных координат объекта? 5.5. Контрольные вопросы 75 Как задать конусный источник света? Если в сцене включено освещение, но нет источников света, какой цвет будут иметь объекты? Глава 6. Текстурирование Под текстурой будем понимать изображение, которое надо определенным образом нанести на объект, например, для придания иллюзии рельефности поверхности. Для работы с текстурой следует выполнить следующую последовательность действий: выбрать изображение и преобразовать его к нужному формату; передать изображение в OpenGL; определить, как текстура будет наноситься на объект и как она будет с ним взаимодействовать; связать текстуру с объектом. 6.1. Подготовка текстуры Для использования текстуры необходимо сначала загрузить в память нужное изображение и передать его OpenGL. 77 78 Глава 6. Текстурирование Считывание графических данных из файла и их преобразование можно проводить вручную. В приложении Б приведен исходный текст функции для загрузки изображения из файла в формате BMP. Можно также воспользоваться функцией, входящей в состав библиотеки GLAUX (для ее использования надо дополнительно подключить glaux.lib), которая сама проводит необходимые операции. Это функция AUX_RGBImageRec* auxDIBImageLoad (const char *file) где file —название файла с расширением *.bmp или *.dib. Функция возвращает указатель на область памяти, где хранятся преобразованные данные. При создании образа текстуры в памяти следует учитывать указываемые требования. Во-первых, размеры текстуры, как по горизонтали, так и по вертикали должны представлять собой степени двойки. Это требование накладывается для компактного размещения текстуры в текстурной памяти и способствует ее эффективному использованию. Работать только с такими текстурами конечно неудобно, поэтому после загрузки их надо преобразовать. Изменение размеров текстуры можно провести с помощью команды void gluScalelmage (GLenum format , GLint widthin , GL heightin , GLenum typein , const void *datain , GLint widthout , GLint heightout , GLenum typeout , void *dataout) В качестве значения параметра format обычно используется значение GL_RGB или GL_RGBA, определяющее формат хранения информации. Параметры widthin, heightin, widhtout, heightout определяют размеры входного и выходного изображений, а с помощью typein и typeout задается тип элементов массивов, распо- 6.1. Подготовка текстуры 79 ложенных по адресам datain и dataout. Как и обычно, это может быть тип GL_UNSIGNED_BYTE, GL_SHORT, GL_INT и т.д. Результат своей работы функция заносит в область памяти, на которую указывает параметр dataout. Во-вторых, надо предусмотреть случай, когда объект после растеризации оказывается по размерам значительно меньше наносимой на него текстуры. Чем меньше объект, тем меньше должна быть наносимая на него текстура и поэтому вводится понятие уровней детализации текстуры (mipmap). Каждый уровень детализации задает некоторое изображение, которое является, как правило, уменьшенной в два раза копией оригинала. Такой подход позволяет улучшить качество нанесения текстуры на объект. Например, для изображения размером 2т х 2п можно построить тах(т, п) + 1 уменьшенных изображений, соответствующих различным уровням детализации. Эти два этапа создания образа текстуры во внутренней памяти 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 —красный, синий, зеленый, альфа (см. п. 7.1). Параметры width, height, data определяют размеры и расположение текстуры соответственно, a format и type имеют аналогичный смысл, что и в команде gluScalelmageQ. 80 Глава 6. Текстурирование После выполнения этой команды текстура копируется во внутреннюю память OpenGL, и поэтому память, занимаемую исходным изображением, можно освободить. В OpenGL допускается использование одномерных текстур, то есть размера 1 х N, однако это всегда надо указывать, задавая в качестве значения target константу GL_TEXTURE_1D. Одномерные текстуры используются достаточно редко, поэтому не будем останавливаться на этом подробно. При использовании в сцене нескольких текстур, в OpenGL применяется подход, напоминающий создание списков изображений (так называемые текстурные объекты). Сначала с помощью команды void glGenTextures (GLsizei n, GLuint* textures) надо создать п идентификаторов текстур, которые будут записаны в массив textures. Перед началом определения свойств очередной текстуры следует сделать ее текущей («привязать» текстуру), вызвав команду void glBindTexture (GLenum target , GLuint texture) где target может принимать значения GL_TEXTURE_1D или GL_TEXTURE_2D, а параметр texture должен быть равен идентификатору той текстуры, к которой будут относиться последующие команды. Для того, чтобы в процессе рисования сделать текущей текстуру с некоторым идентификатором, достаточно опять вызвать команду glBindTextureQ с соответствующим значением target и texture. Таким образом, команда glBindTextureQ включает режим создания текстуры с идентификатором texture, если такая текстура еще не создана, либо режим ее использования, то есть делает эту текстуру текущей. Так как не всякая аппаратура может оперировать текстурами большого размера, целесообразно ограничить размеры текстуры до 256 х 256 или 512 х 512 пикселей. Отметим, что использование небольших текстур повышает эффективность программы. 6.2. Наложение текстуры на объекты 81 6.2. Наложение текстуры на объекты При наложении текстуры, как уже упоминалось, надо учитывать случай, когда размеры текстуры отличаются от оконных размеров объекта, на который она накладывается. При этом возможно как растяжение, так и сжатие изображения, и то, как будут проводиться эти преобразования, может серьезно повлиять на качество построенного изображения. Для определения положения точки на текстуре используется параметрическая система координат (s,t), причем значения s и t находятся в отрезке [0,1] (см. рисунок 6.1) (0,1) (1, 1) (0,0) (1,0) Рис. 6.1. Текстурные координаты Для изменения различных параметров текстуры применяются команды: void glTexParameter [ i f] (GLenum target , GLenum pname, GLenum param) void glTexParameter [ i f]v (GLenum target , GLenum pname, Glenum* params) Параметр target принимает значения GL_TEXTURE_1D или GL_TEXTURE_2D, pname определяет, какое свойство будем менять, а с помощью param или params устанавливается новое значение. Возможные значения pname: |