ФЕДЕРАЛЬНОЕ АГЕНСТВО ПО ОБРАЗОВАНИЮ
Государственное образовательное учреждение высшего профессионального образования
«ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Факультет автоматики и вычислительной техники
Компьютерная графика
РЕФЕРАТ
«Применение OpenGL»
РАЗРАБОТАЛ
Студент группы 8В21 _________ Я.Е. Негрей
(ПОДПИСЬ)
__.__.____
(ДАТА)
УТВЕРЖДАЮ
Ассистент _________ А.Е. Соколов
(ПОДПИСЬ)
__.__.____
(ДАТА)
Томск – 2005
Приложение 1. OpenGL в Интернете. 13
Для ускорения выполнения этапов 3D – конвейера в ускоритель трехмерной графики должен обладать определенным наборам функций, т.е. аппаратно, без участия центрального процессора, производить операции, необходимые для построения 3D – изображения. Специальный пакет служебных команд и программ для выполнения этих функций называют интерфейсом прикладного программирования (Application Program Interface – API).
Использование API избавляет разработчика прикладной программы от трудоемкой работы по написанию низко уровневых программ, что облегчает процесс создания программ.
В настоящее время существуют различные пакеты API функций. Такие как DirectX, OpenGL. А также существуют частные разработки пакетов API функций некоторых фирм ориентированные только на свои 3D – акселераторы и Chipset.
DirectX – разработка фирмы Microsoft. Это пакет разработан в первую очередь для игровых приложений, работающих под операционной системой Windows NT/9X и более поздних версиях. Данный пакет является закрытой разработкой.
В отличии DirectX, OpenGL – это открытая разработка. Данный пакет состоит из двух частей. Первая часть – это базовый набор функций. Каждый производитель 3D – акселераторов, выпускающих свою продукцию с поддержкой OpenGL, должен их реализовать. И второй Части – функций расширения, реализующих более сложных преобразования.
OpenGL, в основном, используется в профессиональных программах или в приложениях работающих под другими операционными системами отличных от Microsoft Windows.
OpenGL это профессиональный пакет функций поэтому он может работать с различными устройствами вывода и обеспечить работу этих устройств в разных режимах. Для этого в первую очередь необходимо определить, куда нужно выводить изображения в какой форме и как должно работать устройство отображения. Рассмотрим инициализацию работы с OpenGL на следующем примере:
procedure TMainWindow.FormCreate(Sender: TObject);
begin
…
SaveDefaultMode(); // Сохранения текущих параметров экрана
SetFullscreenMode(1); // Установка нового режима работы экрана
…
SetDCPixelFormat(Canvas.Handle); // установка параметров отображения
hrc := wglCreateContext(Canvas.Handle); // создание контекста отображения
// для функций OpenGL
If hrc = 0 then begin
ShowMessage ('Ошибка получения контекста воспроизведения!');
close ;
end;
glClearColor(0.0,0.0,0.0,1.0); //
wglMakeCurrent(Canvas.Handle, hrc); // выбираем текущем нашу форму
…
end;
procedure TMainWindow.SetDCPixelFormat(DC : HDC);
var
nPixelFormat: Integer;
pfd: TPixelFormatDescriptor;
begin
FillChar(pfd, SizeOf(pfd), 0);
// устанавливаем параметры отображения пикселя
With pfd do begin
nSize := SizeOf(pfd);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER;
iPixelType:= PFD_TYPE_RGBA;
end;
nPixelFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, nPixelFormat, @pfd);
end;
Рассмотрим функции более подробнее:
С помощь функций SaveDefaultMode и SetFullscreenMode изменяют размер экрана используя функции ChangeDisplaySettings, но эта функция не из пакета OpenGL.
SetPixelFormat эта функция принудительна выставляет определенные настройки отображения пикселя и описывается эта функция следующим образом.
BOOL SetPixelFormat(HDC hdc,int iPixelFormat,CONST PIXELFORMATDESCRIPTOR * ppfd);
Здесь:
hdc – эта переменная отвечает за то к какому устройству применить установки.
iPixelFormat – номер формата пикселя, этот номер получают используя функцию ChoosePixelFormat
ppfd – это логической описания пикселя. PIXELFORMATDESCRIPTOR это специальная структура, описывающая все атрибуты выводимых пикселей. В виде основных элементов этой структуры можно выделить следующие:
· dwFlags – этот элемент описывает все свойства буфера пикселей, например такие как используется двойная буферизации или буферизация стерео изображения, или например куда выводить изображения на окно или в память в виде картинки.
· iPixelType – описывает как будет хранится информации о пикселе в буфере. Можно установить различные значения, например PFD_TYPE_RGBA или PFD_TYPE_COLORINDEX.
· cColorBits – устанавливает размер памяти отводимый под один пиксель в буфере
Как видно из кода программы мы установили двойную буферизацию, поддержку OpenGl и вывод на экан. Также установив формат хранения информации о пикселе в RGBA (Red Green Blue Alpha, где Alpha отвечает за прозрачность)
Далее необходимо создать контекст устройства отображения для OpenGL, это необходимо из-за того что OpenGL только со своим контекст и не может использовать контекст вывода Windows HDC. Данная операция осуществляется функцией wglCreateContext. В нашем случае мы создаем контекст на холст нашей формы. Но мало просто создать контекст его еще необходимо сделать текущим. Это используется для того, чтобы, создав несколько контекстов вывода, мы могли бы точно и быстро определить на какое устройство пойдет дальнейший вывод. Выбор контекста отображения осуществляется с помощью функции wglMakeCurrent.
HGLRC wglCreateContext( HDC hdc );
BOOL wglMakeCurrent( HDC hdc , HGLRC hglrc);
Для отмены выделения контекста отображения используется таже функция wglMakeCurrent, но с подачей констант NULL. А для удаления контекста отображения OpenGL необходимо использовать спезыальную функцию wglDeleteContext.
BOOL wglDeleteContext( HGLRC hglrc );
Прежде всего, для дальнейшей работы, нам необходимо определить какой будет наша игра трехмерной или двухмерной. Так как от этого зависит набор функций которые мы будем в дальнейшем использовать
Хотя на OpenGL трехмерные и двухмерные построения осуществляются с разной сложностью, но и возможности тоже различны, поэтому нужно рассмотреть плюсы и минусы более подробно.
При использовании трехмерные графики мы получаем большое количество цветовых эффектов, естественно объемное изображения, а также возможность сложной анимации. Но для реализации такой системы понадобится много времени и сил, что не всегда подходит.
При использовании двухмерной графики вся анимация и эффекты сводится к прицепу создания рисованных мультфильмов. Такая технология называется «Спрайтовой» в ней используется большая коллекция картинок, из которой выбираются различные картинки, соединяются в один кадр, затем это кадр выводится на экран. Для вывода следующего кадра необходимо повторить эту операцию, только заменив одну из картинок на другую или повернуть или сместить в другую точку на кадре. Такой вариант гораздо мене трудоемок и требую меньших затрат в программирования. Но данная технология обладает одним большим минусом, качество анимации полностью зависит от качества картинок в коллекции, поэтому для всех играх того плана требуется много памяти на жестком диске.
Так как это наш первый проект того плана, поэтому мы остановимся на варианте двухмерной графики.
Для этого нам понадобится функции вывода растрового изображения. Используя OpenGL эту проблему можно решить различными путями, например загрузить их в виде текстур а потом выводить прямоугольники с наложением на них этих текстур. Но есть способ проще в OpenGL есть специальная функция которая выводит растровое изображение в указанную точку на экране. Рассмотрим пример.
…
if ( (X >= 0) and ((Y+LibImages[N].Heigth )<= ScreenHeight)) then begin
gX:=X/(HalfScreenWidth)-1;
gY:=1-(Y+LibImages[N].Heigth)/HalfScreenHeight;
glRasterPos2f(gX, gY);
glPixelStorei(GL_UNPACK_ALIGNMENT, 0);
glDrawPixels(LibImages[N].Width,LibImages[N].Heigth,
GL_RGBA, GL_UNSIGNED_BYTE , LibImages[N].Pixels);
End
…
В нем нас интересуют только тру функции glRasterPos, glPixelStore и glDrawPixels. Рассмотрим их по порядку и поподробней.
Функция glRasterPos описывается следующим образом:
void glRasterPos[X][T](…);
Эта функции используется для работы с растром, она устанавливает координаты где потом будут в растре будут выполнятся последующие изменения или действия такие как вывод пикселя или картинки, или наоборот снятия параметров пикселя. Здесь X это количество подаваемых переменных и T это тип подаваемых переменных как описано в стандартном синтаксисе для команд OpenGL.
Функция glPixelStore определяет как хранится пиксели которые мы будит выводить на экран. Она работает следующим образом.
void glPixelStore[f,i](GLenum pname, [GLfloat | GLint] param);
Выбираем один элемент из списка GLenum для этой функции и устанавливаем его в значение поданной в param разные элементы требуют подачу как целочисленных так и вещественных чисел поэтому данная функция имеет двк формы вызова.
Функция glDrawPixels выводит растровое изображения на экран.
void glDrawPixels(GLsizei width,GLsizei height,
GLenum format,GLenum type, const GLvoid *pixels);
Как мы можем видеть данная функция требует указать размеры выводимого изображения (width и height), указать формат хранимых пикселей в нашем случае это RGBA. Далее идет указание типа переменных хранимых в массиве pixels. Здесь нет никакой ошибки именно массиве, а не матрицы. Все точки изображения записаны в массив подряд и зависимости от типа хранимых данных и от формата пикселя можно определить как происходит перевод адресации в матрицы к адресации в линейном массиве. Для режима GL_UNSIGNED_BYTE и формата GL_RGBA, адрес A[i][j] можно расписать так A[(i*width + j)*4], здесь происходит умножение на 4 т.к. при данном формате под каждую цветовую составляющую одного пикселя отводится по байту.