Графическая библиотека OpenGL. Изображения и текстуры. Модель освещения

Страницы работы

Фрагмент текста работы

Также в OpenGL имеется функция для отображения битовых массивов.

void glBitmap(

     GLsizei width, GLsizei height,

     GLfloat xorig, GLfloat yorig,

     GLfloat xmove, GLfloat ymove,

     const GLubyte *bitmap );

Битовый массив – это последовательность байт, которая кодируют картинку из двух цветов. Соответственно, каждый байт кодирует 8 пикселов.

2. Текстуры

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

Сначала разберем создание и наложение текстур на плоскость. Затем рассмотрим наложение текстур на объекты, описанные в предыдущей работе в разделе 4.

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

·  загрузить графический файл в память;

·  создать имя-идентификатор текстуры;

·  сделать его активным;

·  создать саму текстуру в памяти;

·  установить параметры текстуры;

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

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

Первое мы уже научились делать в предыдущем разделе. Необходимо объявить следующие глобальные переменные:

unsigned int photo_tex;

AUX_RGBImageRec * photo_image;

unsigned int space_tex;

AUX_RGBImageRec * space_image;

Переменные photo_tex и space_tex будут служить идентификаторами текстур. А в photo_image и space_image будем загружать bmp-файлы. Тут нужно отметить, что текстуры в OpenGL должны иметь размер 2n x 2m, где n и m целые числа. Это сделано для ускорения работы, т.к. сжимать или растягивать такие текстуры быстрее и удобней. Можно, конечно, загрузить изображение любого другого размера, но его придется масштабировать, что не всегда является приемлемым.

Вставьте следующий код в обработчик WM_CREATE.

photo_image = auxDIBImageLoad("photo.bmp");

space_image = auxDIBImageLoad("space.bmp");

Картинки можно создать, например, в PaintBrush (желательно с размером 512x512).

Теперь нужно создать имя-идентификатор текстуры. Его нужно создавать, когда в приложении используется более одной текстуры, чтобы была возможность как-то их различать. В противном случае, когда текстура только одна, идентификатор ей не нужен.

Предположим, что нам нужно использовать несколько текстур. Функция

void glGenTextures(GLsizei n, GLuint * textures);

принимает на вход два параметра: первый указывает количество имен-идентификаторов текстур, которые нужно создать; второй параметр – указатель на массив элементов типа unsigned int. Количество элементов в массиве должно совпадать с числом, указанным в качестве первого параметра. Например, следующий код создает десять имен текстур.

unsigned int names[10];

glGenTetures(10, names);

Хранить идентификаторы текстур в массиве не всегда удобно. Такой способ подходит для хранения задних фонов или типов стен – кирпичная, каменная и т.п. В общем, в массиве хранят те элементы, между которыми есть что-то общее. В нашем случае, два изображения связаны, т.к. используются в одном приложении, поэтому можно создать два различных идентификатора. Добавьте следующий код в обработчик WM_CREATE.

glGenTextures(1, &photo_tex);

glGenTextures(1, &space_tex);

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

void glBindTexture(GLenum target, GLuint texture);

Первый параметр должен быть GL_TEXTURE_2D или GL_TEXTURE_1D. Он показывает, с одномерным или двумерным изображением будем работать. Все примеры здесь касаются двумерных текстур. Второй параметр – идентификатор, который был создан выше при помощи glGenTextures. Теперь добавьте вызов этой функции в обработчик WM_CREATE.

glBindTexture(GL_TEXTURE_2D, photo_tex);

Теперь необходимо создать саму текстуру в памяти. Массив байт в структуре AUX_RGBImageRec не является еще текстурой, потому что у текстуры много различных параметров. Создав текстуру, необходимо наделить ее определенными свойствами: указать уровень детализации, способ масштабирования и связывания текстуры с объектом. Уровень детализации нужен для наложения текстуры на меньшие объекты, т.е. когда площадь на экране меньше размеров изображения. Нулевой уровень детализации соответствует исходному изображению размером 2n x 2m, первый уровень – 2n-1 x 2m-1, k-ый уровень – 2n-k x 2m-k. Число уровней соответствует min(n, m). Для создания текстуры имеется две функции glTexImage1D/glTexImage2D и gluBuild1DMipmaps/gluBuild2DMipmaps:

void glTexImage2D(

     GLenum target,

     GLint lavel,

     GLint components,

     GLsizei width,

     GLsizei height,

     GLint border,

     GLenum format,

     GLenum type,

     const GLvoid* pixels

);

int gluBuild2DMipmaps(

     GLenum target,

     GLint components,

     GLsizei width,

     GLsizei height,

     GLenum format,

     GLenum type,

     const GLvoid* pixels

);

Основное их различие в том, что первая функция создает текстуру

Похожие материалы

Информация о работе