Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
KG / КГ_10глава.doc
Скачиваний:
115
Добавлен:
26.05.2014
Размер:
584.19 Кб
Скачать

10.5. Стандартные объемные формы

В OpenGL предусмотрены некоторые стандартные, наиболее часто исполь­зуемые трехмерные объекты. Набор таких форм представлен в библиотеке GLU (Utility Library), которая реализована в виде модуля giu32.dll и являет­ся неотъемлемой частью OpenGL. Она включает в себя несколько функций управления проекциями (одну из которых — gluPerspective мы уже исполь­зовали), функции работы с полигонами, кривыми и поверхностями типа В-сплайнов и другие функции.

Рассмотрим функции gluCylinder, gluSphere, gluDisk И gluPartialDisk (рис. 10.4—10.7).

Перечисленные объекты названы "quadric objects". Параметры slices и stacks определяют количество плоских граней, используемых для аппрокси­мации поверхности. Для того чтобы нарисовать подобный объект, необхо-

Рис. 10.4. Цилиндр

Рис. 10.5. Шар

Рис. 10.6. Диск

Рис. 10.7. Часть диска

димо вызвать функцию giuNewQuadric, а после рисования освободить память ВЫЗОВОМ функции gluDeleteQuadric.

По умолчанию каждый объект рисуется со сплошным заполнением. Изме­нить СТИЛЬ показа МОЖНО ВЫЗОВОМ функции gluQuadricDrawStyle. МОЖНО за-

дать такие стили показа — в виде точек, расположенных в вершинах много­угольника, каркасное изображение, сплошное заполнение и силуэт (разно­видность каркасного). Например, вызов

дает каркасное изображение.

Объекты данного типа располагаются в пространстве в центре координат (0, 0, 0) с учетом матрицы glmodelview. Поэтому, чтобы нарисовать изобра­жение объекта в требуемом месте, нужно соответствующим образом изме­нить эту матрицу, например, С ПОМОЩЬЮ функций glTranslate И glRotate.

Нижеприведенный пример иллюстрирует показ объектов типа "quadric

objects".

Файл studex53. срр:

Т); , 40);

tion);

Изображение в окне программы studex53 приведено на рис. 10.8.

Рис. 10.8. Цилиндры, шар и диск

При подготовке этого рисунка к печати был изменен цвет фона на белый. Однако на экране монитора синий цвет выглядит значительно лучше (в тек­сте программы: giciearColor(0, 0, 0.5, l.0f)).

10.6. Текстура

В OpenGL имеется достаточно полный набор средств для построения тексту-рированных изображений.

В качестве текстуры можно использовать растровое изображение. Оно может быть одномерным или двумерным. Для наложения текстуры необходимо вы­полнить несколько операций.

1. Сначала открыть в памяти массив, в котором будет храниться растр тек­стуры. Число байт массива рассчитывается исходя из количества бит на пиксел текстуры. Размеры растра текстуры обязательно должны быть равны степени двойки (плюс несколько пикселов на бордюр). Это требо­вание создает некоторые неудобства для программиста, особенно в слу­чае, когда текстура может быть прочитана из произвольного растрового файла. Впрочем, это не является неразрешимой проблемой — любой растр текстуры можно либо обрезать, либо растянуть (сжать) до требуемых раз­меров.

2. Заполнить массив текстуры. Здесь следует учитывать то, в каком формате представлен растр текстуры. Если пикселы текстуры представляются в формате RGB (24 бита на пиксел), то байты в массиве должны распола­гаться в виде троек (R, G, В). Заметим, что в массивах DIB Windows API цветовые компоненты располагаются в обратном порядке, то есть (В, G, R).

3. После того как массив открыт, нужно передать OpenGL адрес массива и другие его параметры. Делается это вызовом функции giTeximage2D для двумерной текстуры и giTeximageiD для одномерной

4. Затем можно задать параметры фильтрации текстуры (вызовом функции glTexParameter) для качественного отображения объектов различных раз­меров.

5. Перед непосредственным рисованием объектов необходимо устано­вить режим использования текстуры. Делается это вызовом функции giEnable(GL_TEXTURE_2D). Для объектов типа "quadric objects" (шар, цилиндр, диск) нужно также вызвать еще и функцию

gluQuadricTexture(quadricObj, GL_TRUE).

6. При выводе полигональных граней (gljtriangles, gl_quads и им подоб­ных) необходимо указывать соответствие текстурных координат и коор­динат в пространстве объектов. Сделать это можно вызовом функций из семейства giTexCoord. Так, например, функция giTexCoord2f (s,t) указы­вает на точку с текстурными координатами s и t. Последующий вызов функции givertex3f (x,y, z) одновременно с заданием координат грани также ставит в соответствие координаты (s,t) координатам (x,y,z). На рис. 10.9 показан пример отображения координат четырехугольной грани.

Рис. 10.9. Координаты текстуры (s, t) и координаты вершин (Р1—РА)

Запрограммировать такое отображение текстуры можно таким образом:

Рассмотрим пример использования текстуры в следующей программе.

Файл studex54. срр:

Результат работы программы studex54 показан на рис. 10.10.

Рис. 10.10. Пример синтетической текстуры

Можно предположить, что хозяин этого замка решил покрыть плиткой сте­ны, дабы уберечь свою недвижимость от разрушительного воздействия аг­рессивной окружающей среды. Так это было или нет, но здесь мы еще раз использовали шахматный узор — уже для текстуры. Растр текстуры генери­руется здесь "на лету" и сохраняется в массиве pixels. Это пример синтети­ческой-текстуры, узор создается простейшим алгоритмом. Для создания реа­листичных изображений в качестве текстур обычно используются цифровые фотографии.

В общем случае, текстуры удобнее хранить в файлах на диске. Это могут быть достаточно сложные изображения, изготовленные заблаговременно. В программах для Windows растры можно создавать в виде ресурсов, кото­рые после компиляции записываются в выполняемые файлы, например, в файлы ЕХЕ. А можно использовать и отдельные файлы стандартных фор­матов. В последнем случае текстуры удобно многократно редактировать.

Рассмотрим, как можно использовать текстуры, записанные в файлах BMP. Такие файлы хранят растр в формате DIB (Device Independent Bitmap). Фор­мат DIB похож на формат текстуры OpenGL, однако есть некоторые отличия, Так, в DIB используется выравнивание строк на границу двойного слова. Иными словами, количество байт в строке растра всегда должно быть кратно четырем — если это не так, то добавляют лишние байты. В нашем случае благоприятным фактором является то, что размеры текстур OpenGL должны быть равны степени двойки. Начиная с размеров по горизонтали, равных че­тырем, 24-битные растры DIB автоматически располагаются в памяти так же, как и текстуры OpenGL — выравнивание отсутствует.

Если использовать 24-битную глубину цвета, то более существенным отли­чием DIB от формата текстур OpenGL является порядок расположения бай­тов R, G и В. Для массивов текстур OpenGL должно быть R-G-B, в то время как в DIB наоборот: B-G-R. Поэтому после чтения файла необходимо пере­ставлять байты R и В.

Наша следующая программа (studex55) иллюстрирует чтение текстуры из файла BMP. Эта программа является модификацией предыдущей программы (studex54). Изменения коснулись только функции initMyTexture. В ее тело встроена функция чтения файлов BMP, которая названа ReadTextureBMP.

Текстура здесь читается из файла "filename.bmp".

В этой программе текстура загружается в массив всякий раз при создании, кадра. В данном примере это вполне допустимо, однако в других случаях та­кой подход может быть плохим по быстродействию. Поскольку дисковые операции являются медленными (особенно при чтении нескольких различ­ных файлов больших размеров), то чтение файлов текстур нужно стараться делать как можно реже. Например, при построении кадров "облета замка" — to есть при "показе одних и тех же объектов с разных ракурсов, текстуры лучше всего загружать перед началом цикла показа. Если используются не­сколько текстур, то для каждой можно создать в памяти отдельный массив.

На рис. 10. 11 показан результат работы studex55.

Возможно, в этом замке мало дверей и окон. Но их несложно добавить в тек­стуру с помощью любого растрового графического редактора, не так ли? Хотя, вероятно, понадобится использовать уже несколько текстур для разных стен.

Следует отметить, что приведенная выше функция ReadTextureBMP не являет­ся универсальной— она не рассчитана на другие разновидности формата файлов BMP. Эту функцию необходимо существенно видоизменить, если предусматривается чтение, например, и 256-цветных растров. Такие растры читать несколько сложнее, поскольку требуется загружать и устанавливать палитру. В качестве универсального решения для чтения файлов формата BMP можно порекомендовать использовать функцию auxDiBimageLoad из библиотеки glaux.

Рис. 10.11. Использование текстуры из файла

Соседние файлы в папке KG