Учебная работа. Реферат: Отчет по OpenGL

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...
Контрольные рефераты

Учебная работа. Реферат: Отчет по OpenGL

Оглавление

1. структура и применение OpenGl

2. Главные библиотеки, применяемые при разработке приложений

3. Массивы вершин и списки изображений (предназначение и команды для их описания)

4. Преобразование проецирования, задание ортографической и многообещающей проекции

5. Задание и начальный код

6. Набросок

7. Использованные источники


структура и применение OpenG
L

OpenGL (Open Graphics Library — открытая графическая библиотека) — спецификация, определяющая независящий от языка программирования кросс-платформенный программный интерфейс для написания приложений, использующих двумерную и трехмерную компьютерную графику (это эталон API).

Включает наиболее 250-ти функций для рисования сложных трехмерных сцен из обычных примитивов. Употребляется при разработке видео-игр, САПР, виртуальной действительности, визуализации в научных исследовательских работах. На платформе Windows соперничает с DirectX.

OpenGL ориентируется на последующие две задачки:

· скрыть трудности адаптации разных 3D-ускорителей предоставляя разрабу единый API

· скрыть различия в способностях аппаратных платформ, требуя реализации недостающей функциональности при помощи программной эмуляции

Главным принципом работы OpenGL является получение наборов векторных графических примитивов в виде точек, линий и многоугольников с следующей математической обработкой приобретенных данных и построением растровой рисунки на дисплее и/либо в памяти. Векторные трансформации и растеризация производятся графическим сборочным потоком (graphics pipeline), который, на самом деле, представляет собой дискретный автомат. Абсолютное большая часть установок OpenGL попадают в одну из 2-ух групп: или они добавляют графические примитивы на вход в сборочный поток, или изменяют сборочный поток на различное выполнение транформаций.

OpenGL является низкоуровневым процедурным API, что вынуждает программера диктовать точную последовательность шагов, чтоб выстроить результирующую растровую графику (властный подход). Это является главным различием от дескрипторных подходов, когда вся сцена передается в виде структуры данных (почаще всего дерева), которое обрабатывается и строится на дисплее. С одной стороны властный подход просит от программера глубочайшего познания законов трёхмерной графики и математических моделей, с иной стороны — даёт свободу внедрения разных нововведений. Как уже было сказано, существует реализация OpenGL для различных платформ, для чего же было комфортно поделить базисные функции графической системы и функции для отображения графической инфы и взаимодействия с юзером.

Этапы обработки данных в системе OpenGL:

· Аппроксимация кривых и поверхностей

· Обработка вершин и сборка примитивов

· Растеризация и обработка фрагментов

· Операции над пикселами

· Подготовка текстуры

· Передача данных в буфер кадра

Главные библиотеки применяемые при разработке приложений

OpenGL является на данный момент одним из самых фаворитных программных интерфейсов (API) для разработки приложений в области двумерной и 3d графики. Эталон OpenGL был разработан и утвержден в 1992 году ведущими фирмами в области разработки программного обеспечения, а его основой стала библиотека IRIS GL, разработанная Silicon Graphics.

На данный момент реализация OpenGL содержит в себе несколько библиотек. Были сделаны библиотеки для отображения инфы при помощи оконной подсистемы для операционных систем Windows и unix (WGL и GLX соответственно), также библиотеки GLAUX и GLUT, которые употребляются для сотворения так именуемых консольных приложений.

библиотека GLAUX уступает по популярности написанной несколько позднее библиотеке GLUT, хотя они предоставляют приблизительно схожие способности.

Массивы вершин и списки изображений

Предназначение и команды для их описания

Под верхушкой понимается точка в трехмерном пространстве, координаты которой можно задавать последующим образом:

void glVertex[2 3 4][s i f d](type coords)

void glVertex[2 3 4][s i f d]v(type *coords)

Координаты точки задаются максимум 4-мя значениями: x, y, z, w, при всем этом можно указывать два (x,y) либо три (x,y,z) значения, а для других переменных в этих вариантах употребляются значения по дефлоту: z=0, w=1. Как уже было сказано выше, число в заглавии команды соответствует числу очевидно задаваемых значений, а следующий знак – их типу.

Координатные оси размещены так, что точка (0,0) находится в левом нижнем углу экрана, ось x ориентирована на лево, ось y- ввысь, а ось z- из экрана. Это размещение осей мировой системы координат, в какой задаются координаты вершин объекта.

Но чтоб задать какую-нибудь фигуру одних координат вершин недостаточно, и эти верхушки нужно соединить в одно целое, определив нужные характеристики. Для этого в OpenGL употребляется понятие примитивов, к которым относятся точки, полосы, связанные либо замкнутые полосы, треугольники и так дальше. Задание примитива происходит снутри командных скобок:

void glBegin(GLenum mode)

void glEnd(void)

Параметр mode описывает тип примитива, который задается снутри и может принимать разные значения:

GL_POINTS любая верхушка задает координаты некой точки.

GL_LINES любая отдельная пара вершин описывает отрезок; если задано нечетное число вершин, то крайняя верхушка игнорируется.

GL_LINE_STRIP любая последующая верхушка задает отрезок вкупе с предшествующей.

GL_LINE_LOOP отличие от предшествующего примитива лишь в том, что крайний отрезок определяется крайней и первой верхушкой, образуя замкнутую ломаную. GL_TRIANGLES любая отдельная тройка вершин описывает треугольник; если задано не кратное трем число вершин, то крайние верхушки игнорируются.

GL_TRIANGLE_STRIP любая последующая верхушка задает треугольник вкупе с 2-мя прошлыми.

GL_TRIANGLE_FAN треугольники задаются первой и каждой последующей парой вершин (пары не пересекаются).

GL_QUADS любая отдельная четверка вершин описывает четырехугольник; если задано не кратное четырем число вершин, то крайние верхушки игнорируются.

GL_QUAD_STRIP четырехугольник с номером n определяется верхушками с номерами 2n-1, 2n, 2n+2, 2n+1.

GL_POLYGON поочередно задаются верхушки выпуклого многоугольника.

Массивы вершин

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

void glVertexPointer( GLint size, GLenum type, GLsizei stride, void *ptr )

которая описывает метод хранения и координаты вершин. При всем этом size описывает число координат верхушки (быть может равен 2, 3, 4), type описывает тип данных (быть может равен GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE). время от времени комфортно хранить в одном массиве остальные атрибуты верхушки, тогда и параметр stride задает смещение от координат одной верхушки до координат последующей; если stride равен нулю, это означает, что координаты размещены поочередно. В параметре ptr указывается адресок, где находятся данные.

Аналогично можно найти массив нормалей, цветов и неких остальных атрибутов верхушки, используя команды

void NormalPointer(GLenum type, GLsizei stride, void*pointer)

void ColorPointer(GLintsize, GLenum type, GLsizei stride, void *pointer)

Для того, чтоб эти массивы можно было применять в предстоящем, нужно вызвать команду:

void glEnableClientState(GLenum array)

с параметрами GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_COLOR_ARRAY соответственно. Опосля окончания работы с массивом лучше вызвать команду:

void glDisableClientState(GLenum array)

с подходящим значением параметра array.

Для отображения содержимого массивов употребляется команда,

void glArrayElement(GLint index)

которая передает OpenGL атрибуты верхушки, используя элементы массива с номером index. Это аналогично поочередному применению установок вида glColor..(…), glNormal..(…), glVertex..(…) c надлежащими параметрами. Но заместо нее обычно вызывается команда:

void glDrawArrays(GLenum mode, GLint first, GLsizei count)

рисующая count примитивов, определяемых параметром mode, используя элементы из массивов с индексами от first до first+count-1. Это эквивалентно вызову команды glArrayElement() с надлежащими индексами.

В случае если одна верхушка заходит в несколько примитивов, то заместо дублирования ее координат в массиве комфортно применять ее индекс.

Для этого нужно вызвать команду

void glDrawArrays(GLenum mode, GLsizei count, GLenum type, void *indices)

где indices – это массив номеров вершин, которые нужно применять для построения примитивов, type описывает тип частей этого массива: GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, а count задает их количество.

Списки изображений

Если необходимо пару раз обращаться к одной и той же группе установок, эти команды можно соединить в так именуемый перечень изображений (display list) и вызывать его по мере необходимости. Для того, чтоб сделать новейший перечень изображений нужно поместить все команды, которые должны в него войти меж командными скобками:

void glNewList(GLuint list, GLenum mode)

void glEndList()

Для различения списков употребляются целые положительные числа, задаваемые при разработке перечня значением параметра list, а параметр mode описывает режим обработки установок, входящих в перечень:

GL_COMPILE команды записываются в перечень без выполнения

GL_COMPILE_AND_EXECUTE команды поначалу производятся, а потом записываются в перечень

Опосля того, как перечень сотворен, его можно вызвать командой:

void glCallList(GLuint list)

указав в параметре list идентификатор подходящего перечня. Чтоб вызвать сходу несколько списков, можно пользоваться командой:

void glCallLists(GLsizei n, GLenum type, const GLvoid *lists)

вызывающей n списков с идентификаторами из массива lists, тип частей которого указывается в параметре type. Это могут быть типы GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_INT, GL_UNSIGNED_INT и некие остальные. Для удаления списков употребляется команда:

void glDeleteLists(GLint list, GLsizei range)

которая удаляет списки с идентификаторами ID из спектра list<=ID<= list+range-1.

Преобразование проецирования, задание ортографической и многообещающей проекции

В OpenGL употребляются как главные три системы координат: левосторонняя, правосторонняя и оконная. 1-ые две системы являются трехмерными и различаются друг от друга направлением оси z: в правосторонней она ориентирована на наблюдающего, а в левосторонней – в глубь экрана. Размещение осей x и y аналогично описанному чуть повыше. Левосторонняя система употребляется для задания значений характеристикам команды gluPerspective(), glOrtho(), а правосторонняя либо глобальная система координат во всех других вариантах. Отображение трехмерной инфы происходит в двумерную оконную систему координат.

Для задания разных преобразований объектов сцены в OpenGL употребляются операции над матрицами, при всем этом различают три типа матриц: видовая, проекций и текстуры. Они все имеют размер 4×4. Видовая матрица описывает преобразования объекта в глобальных координатах, такие как параллельный перенос, изменение масштаба и поворот. Матрица проекций задает как будут проецироваться трехмерные объекты на плоскость экрана (в оконные координаты), а матрица текстуры описывает наложение текстуры на объект.

Для того чтоб избрать, какую матрицу нужно поменять, употребляется команда

void glMatrixMode(GLenum mode)

вызов которой со значением параметра mode равным GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE включает режим работы с видовой, проекций и матрицей текстуры соответственно. Для вызова установок, задающих матрицы того либо другого типа нужно поначалу установить соответственный режим.

Для определения частей матрицы текущего типа вызывается команда

void glLoadMatrix[f d](GLtype *m)

где m показывает на массив из 16 частей типа float либо double в согласовании с заглавием команды, при всем этом поначалу в нем должен быть записан 1-ый столбец матрицы, потом 2-ой, 3-ий и 4-ый.

Команда

void glLoadIdentity(void)

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

void glPushMatrix(void)

void glPopMatrix(void)

Они записывают и восстанавливают текущую матрицу из стека, при этом для всякого типа матриц стек собственный. Для видовых матриц его глубина равна как минимум 32, а для 2-ух оставшихся типов как минимум 2.

Для умножения текущей матрицы слева на другую матрицу употребляется команда

void glMultMatrix[f d](GLtype *m)

где m должен задавать матрицу размером 4×4 в виде массива с описанным расположением данных. Но обычно для конфигурации матрицы того либо другого типа комфортно применять особые команды, которые по значениям собственных характеристик делают подходящую матрицу и перемножают ее с текущей. Чтоб создать текущей сделанную матрицу, нужно перед вызовом данной команды вызвать glLoadIdentity().

В целом, для отображения трехмерных объектов сцены в окно приложения употребляется последующая последовательность действий:

Координаты объекта => Видовые координаты => Усеченные координаты => Нормализованные координаты => Оконные координаты

В OpenGL есть ортографическая
(параллельная) и многообещающая характеристики команды задают точки (left, bottom, -near) и (right, top, -near), которые отвечают левому нижнему и правому верхнему углам окна вывода. Характеристики near и far задают расстояние до ближней и далекой плоскостей отсечения по дальности от точки (0,0,0) и могут быть отрицательными.

Во 2-ой команде, в отличие от первой, значения near и far инсталлируются равными –1 и 1 соответственно.

Многообещающая
должен находиться в спектре от 0 до 180. Угол видимости вдоль оси x задается параметром aspect, который обычно задается как отношение сторон области вывода. Характеристики zfar и znear задают расстояние от наблюдающего до плоскостей отсечения по глубине и должны быть положительными. Чем больше отношение zfar/znear, тем ужаснее в буфере глубины будут различаться расположенные поверхности, потому что по дефлоту в него будет записываться ‘сжатая’ глубина в спектре от 0 до 1.

Задание и начальный код

Задание: набросок «КУБ».

unit mgl;

interface

uses

Windows, Messages, Classes, Graphics, Forms, ExtCtrls, OpenGL, StdCtrls,

Controls, SysUtils, Spin, Menus, Dialogs;

type

TForm1 = class(TForm)

procedure FormCreate(Sender: TObject);

procedure FormResize(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure FormKeyPress(Sender: TObject; var Key: Char);

private

DC : HDC;

hrc : HGLRC;

Angle, AngleX, AngleY, AngleZ: GLfloat;

procedure DrawScene;

procedure InitializeRC;

procedure SetDCPixelFormat;

protected

// Обработка сообщения WM_Paint — аналог действия OnPaint

procedure WMPaint(var Msg: TWMPaint); Message WM_PAINT;

end;

var

Form1: TForm;

ch, c, i: integer;

s: string;

ShowHelp: boolean=true;

implementation

{$R *.DFM}

const

// массив параметров материала

MaterialColor: Array [0..3] of GLfloat = (0.5, 0.0, 1.0, 1.0);

// Процедура инициализации источника цвета

procedure TForm1.InitializeRC;

begin

glEnable(GL_DEPTH_TEST); // разрешаем тест глубины

glEnable(GL_LIGHTING); // разрешаем работу с освещенностью

glEnable(GL_LIGHT0); // включаем источник света 0

end;

// Отрисовка рисунки

procedure TForm1.DrawScene;

begin

// чистка буфера цвета и буфера глубины

glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

// трехмерность

glMatrixMode(GL_MODELVIEW);

glLoadIdentity;

glTranslatef(0.0, 0.0, -8.0); // на лево/на Право, ввысь/вниз, вспять/вперед

glRotatef(AngleX, 1.0, 0.0, 0.0); // поворот на угол X

glRotatef(AngleY, 0.0, 1.0, 0.0); // поворот на угол Y

glRotatef(AngleZ, 0.0, 0.0, 1.0); // поворот на угол Z

// 6 сторон куба

glBegin(GL_POLYGON);

glNormal3f(0.0, 0.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(-1.0, -1.0, 1.0);

glVertex3f(1.0, -1.0, 1.0);

glEnd;

glBegin(GL_POLYGON);

glNormal3f(0.0, 0.0, -1.0);

glVertex3f(1.0, 1.0, -1.0);

glVertex3f(1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(-1.0, 1.0, -1.0);

glEnd;

glBegin(GL_POLYGON);

glNormal3f(-1.0, 0.0, 0.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(-1.0, 1.0, -1.0);

glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, 1.0);

glEnd;

glBegin(GL_POLYGON);

glNormal3f(1.0, 0.0, 0.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(1.0, -1.0, 1.0);

glVertex3f(1.0, -1.0, -1.0);

glVertex3f(1.0, 1.0, -1.0);

glEnd;

glBegin(GL_POLYGON);

glNormal3f(0.0, 1.0, 0.0);

glVertex3f(-1.0, 1.0, -1.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, -1.0);

glEnd;

glBegin(GL_POLYGON);

glNormal3f(0.0, -1.0, 0.0);

glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(1.0, -1.0, -1.0);

glVertex3f(1.0, -1.0, 1.0);

glVertex3f(-1.0, -1.0, 1.0);

glEnd;

SwapBuffers(DC); // конец работы

end;

// обыденные деяния OpenGL, Создание окна

procedure TForm1.FormCreate(Sender: TObject);

begin

Angle:=0;

AngleX:=30;

AngleY:=-30;

AngleZ:=0;

c:=1;

DC:=GetDC(Handle);

SetDCPixelFormat;

hrc:=wglCreateContext(DC);

wglMakeCurrent(DC, hrc);

InitializeRC;

// характеристики материала — лицевые стороны — растерянный

// цвет материала и диффузное отражение материала — значения из массива

glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,@MaterialColor);

end;

// установка формата пикселей

procedure TForm1.SetDCPixelFormat;

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;

cColorBits:=24; // 24

cDepthBits:=32; // 32

iLayerType:= PFD_MAIN_PLANE;

end;

nPixelFormat := ChoosePixelFormat(DC, @pfd);

SetPixelFormat(DC, nPixelFormat, @pfd);

end;

// Изменение размеров окна

procedure TForm1.FormResize(Sender: TObject);

begin

glMatrixMode(GL_PROJECTION);

glLoadIdentity;

gluPerspective(30.0, Width/Height, 1.0, 10.0);

glViewport(0, 0, Width, Height);

glMatrixMode(GL_MODELVIEW);

InvalidateRect(Handle, nil, False);

end;

// Обработка сообщения WM_Paint, рисование окна

procedure TForm1.WMPaint(var Msg: TWMPaint);

var

ps: TPaintStruct;

begin

BeginPaint(Handle, ps);

DrawScene;

EndPaint(Handle, ps);

end;

// Конец работы программки

procedure TForm1.FormDestroy(Sender: TObject);

begin

wglMakeCurrent(0, 0);

wglDeleteContext(hrc);

ReleaseDC(Handle, DC);

end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

begin

if ord(key)=27 then Application.Terminate; // Esc

FormResize(nil);

end;

end.


Набросок «Куб»


Использованные источники

1. Тихомиров Ю. Программирование 3d графики. СПб., BHV 1998.

2. Visual Introduction in OpenGL, Siggraph’98.

3. The OpenGL graphics system: a Specification (version 1.1).

4. The OpenGL Utility Toolkit (GLUT) Programming Interface, API version 3, Specification.

]]>