Автор работы: Пользователь скрыл имя, 10 Марта 2010 в 00:12, Не определен
Структура и применение OpenGl
Основные библиотеки, используемые при создании приложений
Массивы вершин и списки изображений (назначение и команды для их описания)
Преобразование проецирования, задание ортографической и перспективной проекции
Задание и исходный код
Рисунок
Использованные источники
Для
определения элементов матрицы
текущего типа вызывается команда
void
glLoadMatrix[f d](GLtype *m)
где
m указывает на массив из 16 элементов
типа float или double в соответствии с названием
команды, при этом сначала в нем должен
быть записан первый столбец матрицы,
затем второй, третий и четвертый.
Команда
void
glLoadIdentity(void)
заменяет
текущую матрицу на единичную. Часто
нужно сохранить содержимое текущей матрицы
для дальнейшего использования, для чего
используют команды
void glPushMatrix(void)
void
glPopMatrix(void)
Они записывают и восстанавливают текущую матрицу из стека, причем для каждого типа матриц стек свой. Для видовых матриц его глубина равна как минимум 32, а для двух оставшихся типов как минимум 2.
Для
умножения текущей матрицы
void
glMultMatrix[f d](GLtype *m)
где m должен задавать матрицу размером 4x4 в виде массива с описанным расположением данных. Однако обычно для изменения матрицы того или иного типа удобно использовать специальные команды, которые по значениям своих параметров создают нужную матрицу и перемножают ее с текущей. Чтобы сделать текущей созданную матрицу, надо перед вызовом этой команды вызвать glLoadIdentity().
В целом, для отображения трехмерных объектов сцены в окно приложения используется следующая последовательность действий:
Координаты
объекта => Видовые координаты => Усеченные
координаты => Нормализованные координаты => Оконные
координаты
В
OpenGL существуют ортографическая
(параллельная) и перспективная проекция.
Первый тип проекции может быть задан
командами
void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
void
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble
top)
Первая
команда создает матрицу
Во второй команде, в отличие от первой, значения near и far устанавливаются равными –1 и 1 соответственно.
Перспективная
проекция определяется командой
void
gluPerspective(GLdouble angley, GLdouble aspect, GLdouble znear, GLdouble
zfar)
которая
задает усеченный конус видимости в левосторонней
системе координат. Параметр angley определяет
угол видимости в градусах по оси у и должен
находиться в диапазоне от 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
// Шесть сторон куба
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_
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
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);