Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Глава 15. Наложение текстур в OpenGL




Текстура в OpenGL это рисунок или битовая карта (Bitmap), которая накладывается на грани поверхностей трехмерных объектов. Текстуры создают иллюзию рельефа на поверхности и придают объектам соответствующую раскраску. Например, если на поверхность сферы наложить изображение карты мира, то получится модель земного шара. Если же рисунок изменить на чередующиеся черные и зеленые полосы, то сфера уже будет больше похожа на арбуз. Безусловно, текстуры играют важнейшую роль при моделировании трехмерных объектов.

Размеры текстуры в OpenGL по ширине и высоте в пикселах должны быть степенью двух. Это требование связано с применением оптимизированных алгоритмов рисования текстур при разложении их в растр. Максимальный размер текстуры ограничен. В каждой реализации OpenGL его можно узнать вызовом функции

 

glGetIntegerv(GL_MAX_TEXTURE_SIZE,@GLMaxTex),

 

где переменная GLMaxTex типа GLInt после вызова будет содержать значение максимального размера текстуры в пикселах. Разрешение и запрещение наложения двумерных текстур достигается командами glEnable и glDisable c параметром GL_TEXTURE_2D.

Загрузка образа текстуры

Для загрузки битовой карты в качестве текущей текстуры используется функция glTexImage2D. Эта функция загружает образ битовой карты в оперативную память с помощью указателя. Прежде чем изучать параметры этой функции рассмотрим текст пользовательской функции LoadBmpTexture, написанной на Object Pascal, которая загружает текстуру из файла на диске.

 

function LoadBmpTexture(xSize,ySize: GLInt;Name: string): pointer;

type

TRGB = record

r,g,b: GLUByte;

end;

PBits = ^TBits;

TBits = Array [0..0] of GLUbyte;

var

i, j: Integer;

bitmap: TBitmap;

Size: GLInt;

Bits: PBits;

begin

bitmap:= TBitmap.Create;

bitmap.LoadFromFile(Name); // загружаем текстуру из файла

Size:= xSize*ySize*SizeOf(TRGB);

GetMem(Bits,Size);

 

// заполнение битового массива

For i:= 0 to xSize-1 do

For j:= 0 to ySize-1 do

begin

bits[(i*xSize+j)*3+0]:= GetRValue(bitmap.Canvas.Pixels[j,xSize-1-i]);

bits[(i*xSize+j)*3+1]:= GetGValue(bitmap.Canvas.Pixels[j,xSize-1-i]);

bits[(i*xSize+j)*3+2]:= GetBValue(bitmap.Canvas.Pixels[j,xSize-1-i]);

end;

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,

xSize, ySize,// здесь задается размер текстуры

0, GL_RGB, GL_UNSIGNED_BYTE, bits);

Result:=bits;

//FreeMem(bits);

bitmap.Free;

end;//function LoadBmpTexture

 

Как видим, внутри функции LoadBmpTexture вызывается функция загрузки текстуры glTexImage2D. Особенность загрузки текстур состоит в том, что в образе битовой карты информация о пикселах хранится не в виде R-G-B, как это принято в формате изображений DIB, а наоборот B-G-R, то есть первой идет компонента синего цвета, затем зеленого и далее красного. Удобство функции LoadBmpTexture также состоит в том, что метод загрузки картинки из файла объекта TBitmap автоматически преобразует любые форматы DDB в универсальный формат DIB, так что нам остается только правильно поменять местами расположение байтов тройки RGB, что и происходит в двойном цикле:

 

For i:= 0 to xSize-1 do

For j:= 0 to ySize-1 do

begin

bits[(i*xSize+j)*3+0]:= GetRValue(bitmap.Canvas.Pixels[j,xSize-1-i]);

bits[(i*xSize+j)*3+1]:= GetGValue(bitmap.Canvas.Pixels[j,xSize-1-i]);

bits[(i*xSize+j)*3+2]:= GetBValue(bitmap.Canvas.Pixels[j,xSize-1-i]);

end;

 

Рассмотрим параметры функции glTexImage2D, как она использована в программе.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,

xSize, ySize, 0, GL_RGB,

GL_UNSIGNED_BYTE, bits

);

Первый параметр в этой функции может принимать только значение символической константы GL_TEXTURE_2D. Второй параметр указывает значение уровня детализации текстуры. Уровень детализации задает уменьшение текстуры в заданное число раз с применением алгоритмов Mipmap. По умолчанию используется значение 0. Третий параметр задает количество цветовых компонент текстуры, может быть от 1 до 4. Четвертый и пятый параметры задают ширину и высоту текстуры. Ширина должна удовлетворять выражению 2n+2 x Border, где Border = 0 или 1, ширина границы текстуры, задается в следующем, шестом параметре. Седьмой параметр задает формат пикселов, может принимать следующие значения: GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_LUMINANCE_ALPHA. Предпоследний, восьмой параметр определяет значение типа данных для каждой пиксельной компоненты: GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT. Последний параметр представляет собой указатель на начало области данных текстуры. В нашем случае это переменная bits, описана как указатель на массив байт. Возможно, вас смутил тип данных

 

TBits = Array [0..0] of GLUbyte;

 

Действительно, такое описание выглядит как ошибка в программе. Однако, это сделано специально. Данная функция должна компилироваться с выключенной опцией на проверку допустимых диапазонов {$R-}. Тогда блок памяти bits в программе мы можем рассматривать как массив байт произвольной длины, и использовать обычный синтаксис Object Pascal для доступа к его элементам. Конечно, контроль выхода за пределы области памяти такого массива мы должны полностью брать на себя.

После загрузки образа текстуры в память следует указать грань или грани трехмерных объектов, на которые будет осуществляться наложение текстуры. Здесь мы подходим к определению координат текстуры. Необходимо установить соответствие между вершинами граней трехмерного объекта и местом на текстуре, которое каждой вершине соответствует. Начало системы координат текстуры расположено в левом нижнем углу прямоугольного рисунка текстуры. Ось s, подобно оси абсцисс направлена слева направо по нижней кромке рисунка, а ось t, аналогично оси ординат направлена снизу вверх. Границы прямоугольника изображения текстуры задают диапазон изменения значений координат s и t от 0 до 1.

Рассмотрим пример создания прямоугольника в трехмерном пространстве и наложение на него изображения корабля из файла Ship.bmp размером 64х64 пиксела. Здесь используется возможность создания так называемых дисплейных списков OpenGL, которые позволяют объединить длинные последовательности команд OpenGL под одним названием и запускать их на выполнение. Дисплейные списки позволяют между командами OpenGL выполнять и другие операторы, но, в отличие от обычных процедур и функций, запоминаются в списке только команды OpenGL. При последующем выполнении команд дисплейного списка обычные операторы не выполняются.

 

 

Const

Quad: GLInt=1;//идентификатор дисплейного списка

Ship: pointer;

...

glNewList(Quad,GL_COMPILE);//создаем новый дисплейный список

Ship:= LoadBmpTexture(64,64,'Ship.bmp');//загружаем текстуру в //память

glBegin (GL_QUADS);//задаем тип примитива - четырехугольники

glTexCoord2d (0.0, 0.0);//левый нижний угол текстуры

glVertex3f (-8.0, -8.0, 15.0);

glTexCoord2d (1.0, 0.0); //правый нижний угол текстуры

glVertex3f (8.0, -8.0, 22.0);

glTexCoord2d (1.0,0.8);//верхняя часть изображения будет слегка //приплюснута

glVertex3f (8.0, 0.0, 15.0);

glTexCoord2d (0.0, 1.0);//левый верхний угол текстуры

glVertex3f (-8.0, 8.0, 15.0);

glEnd;

glEndList;//конец создания списка

 

Рисование с использованием дисплейного списка происходит с помощью команды glCallList(Quad).

В случае Quadric объектов рассмотрим пример наложения изображения корабля на сферу.

 

//устанавливаем изображение корабля в качестве текущей текстуры

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,

64, 64, //размеры текстуры

0, GL_RGB, GL_UNSIGNED_BYTE, Ship);

 

glEnable(GL_TEXTURE_2D);//разрешаем использование текстур

gluQuadricTexture(Sphere,GL_TRUE);//разрешаем наложение текстуры на //объект Sphere

 

gluQuadricDrawStyle (Sphere, GLU_FILL);//сплошная закраска сферы

gluSphere(Sphere, 15.0, 24, 24);//рисуем сферу с наложением //текстуры

 

Рисунок проецируется на сферу аналогично тому, как прямоугольная карта земного шара “заворачивала” бы глобус. То есть верхняя и нижняя кромки изображения текстуры после проецирования на сферу оказываются стянутыми в точку.





Поделиться с друзьями:


Дата добавления: 2016-10-30; Мы поможем в написании ваших работ!; просмотров: 1133 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Студенческая общага - это место, где меня научили готовить 20 блюд из макарон и 40 из доширака. А майонез - это вообще десерт. © Неизвестно
==> читать все изречения...

2372 - | 2321 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.009 с.