Также в OpenGL имеется функция для отображения битовых массивов.
void glBitmap(
GLsizei width, GLsizei height,
GLfloat xorig, GLfloat yorig,
GLfloat xmove, GLfloat ymove,
const GLubyte *bitmap );
Битовый массив – это последовательность байт, которая кодируют картинку из двух цветов. Соответственно, каждый байт кодирует 8 пикселов.
Одного вывода изображений недостаточно для создания полноценных трехмерных сцен. Часто возникает потребность накладывать изображение на трехмерные объекты и поворачивать/сдвигать их. Для этих целей существуют текстуры. Кроме этого текстуры могут покрыть весь объект в виде мозаики. Скажем, когда у нас имеется кирпичная стена, то нам не надо загружать изображение с кучей кирпичей. Достаточно загрузить один кирпич и указать, что эту текстуру нужно размножить по всей плоскости.
Сначала разберем создание и наложение текстур на плоскость. Затем рассмотрим наложение текстур на объекты, описанные в предыдущей работе в разделе 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
);
Основное их различие в том, что первая функция создает текстуру
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.