Open GL in Delphi
Материал из DRKB
Первая программа с использованием OpenGL
Часть 1. Первые полигоны[править | править код]
OpenGL ... Вам потребуется Borland DELPHI v.3-5 и OPENGl32.DLL
Начнём, пожалуй! Для начала скачайте пример ... и посмотрите на его работу... Если Вы видели ВРАЩАЮЩИЙСЯ КУБ, то я Вас поздравляю! Вы только-что запустили Вашу первую программу на OpenGL!!.
А теперь самое интересное начнём разбор полётов...
Нет, если Вы скачали пример, то бросать это не стоит. ЗДЕСЬ ВСЁ ПРОСТО. Откройте новый проект: File -> New -> Application; У Вас успехи (шутка). Теперь в директиву "uses" добавьте "OpenGL" вот так:
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, OpenGL, // Подключаем OpenGL32.dll,
dglut; // модуль для рисования правильных объектов одной строкой кода
Прекрасно!
Создайте обработку таких процедур в Object Inspector - > Events (я, надеюсь, что вы знакомы с Delphi):
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
А теперь в разделе private сделайте следующее
private
DC: HDC; // переменные для получения контекста воспроизведения
hrc: HGLRC; //
Angle: GLfloat; // угол, на который будет поворачиваться куб
procedure InitSvet;
procedure SetPixFormat; // формат пикселя
procedure Draww;
protected
procedure WMPaint(var Msg: TWMPaint); message WM_PAINT; // похожа на OnPaint, сообщение от OnPaint
просто вот так всё и пишите, компилятор не обидится!!
В качестве константы объявим:
const
MaterialColor: array [0..3] of GLfloat = (0.3, 0.4, 1.0, 1.0);
Оформим процедурки:
procedure TForm1.FormCreate(Sender: TObject);
begin
Angle := 0;
DC := GetDC(Handle); // получить окно
SetPixFormat; // установим формат пикселя
hrc := wglCreateContext(DC);
wglMakeCurrent(DC, hrc); // сделаем "текущим контекст воспроизведения
InitSvet; // включим свет
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , @MaterialColor);
glMatrixMode(GL_MODELVIEW);
Timer1.Enabled := True; // включим таймер
GLShadeModel(GL_SMOOTH);
end;
// СВЕТ
procedure TForm1.InitSvet;
const
fogColor: array [0..3] of GLfloat = (0.7, 0.7, 0.7, 2.0);
var
fogMode: GLint;
begin
glEnable(GL_DEPTH_TEST); // разрешить тест глубины
glEnable(GL_LIGHTING); // разрешить освещённость
glEnable(GL_LIGHT0); // включить нулевую лампу
end;
procedure TForm1.SetPixFormat;
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;
cDepthBits := 32;
iLayerType := PFD_MAIN_PLANE;
end;
nPixelFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, nPixelFormat, @pfd);
end;
procedure TForm1.WMPaint(var Msg: TWMPaint);
var
ps: TPaintStruct;
begin
BeginPaint(Handle, ps);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // очистить цветовой буфер, и буфер глубины
glClearColor(0.7, 0.7, 0.7, 0.0); // очищать экран серым цветом
glLoadIdentity; // загрузить матрицу
glTranslatef(0.0, 0.0, -9.0);
glRotatef(Angle / (Random(1) + 1), 1.0, 0.0, 0.0);
glRotatef(Angle, 0.0, 0.0, 1.0); //
glpushmatrix; // сохраним текущую систему координат
glutsolidcube(2); // нарисуем куб с ребром 2
glpopmatrix; // восстановим систему координат
SwapBuffers(DC); // перевернём передний и задний буферы
EndPaint(Handle, ps);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Angle := Angle + 1.0; // увеличиваем угол
if (Angle >= 360.0) then Angle := 0.0; // если совершён полный оборот, то вернуть в 0
InvalidateRect(Handle, nil, False); // перерисовать окно
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION); // модель матрицы проекционная
glLoadIdentity; // загрузить матрицу
gluPerspective(60.0, Width / Height, 1.0, 10.0);
glViewport(0, 0, Width, Height); // область вывода весь экран
glMatrixMode(GL_MODELVIEW); // модель матрицы перспективная
InvalidateRect(Handle, nil, False); // перерисовать всё окно
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Timer1.Enabled := False;
wglMakeCurrent(0, 0); // сделать контекст "текущим"
wglDeleteContext(hrc); // удалить контекст воспроизведения
ReleaseDC(Handle, DC); // удалить окно
end;
А теперь запускаем!!!!
Часть 2. Туман[править | править код]
Мы сегодня будем работать с туманом... Во всех предыдущих примерах использовался туман, но его действия вы наверное не замечали, но теперь вы это ощутите.
Объявим константу
const
fogColor: array[0..3] of GLfloat = (0.7, 0.7, 0.7, 2.0); // цвет тумана
Циферки в конце устанавливают следующее: (0.7, 0.7, 0.7, 2.0) 1-ая - красный, 2-ая - синий, 3-ая - зелёный, ну а четвёртая - альфа-канал
Далее переменные:
var
fogMode: GLint;
Перед тем как юзать, его надо включить:
glEnable(GL_FOG);
fogMode := GL_EXP;
glFogi(GL_FOG_MODE, fogMode);
glFogfv(GL_FOG_COLOR, @fogColor); // устанавливаем цвет см "const" вверху
glFogf(GL_FOG_DENSITY,
0.10 //плотность тумана
);
glHint(GL_FOG_HINT, GL_DONT_CARE);
Часть 3. Quadric - объекты[править | править код]
В разделе переменных укажим:
var
quadObj: NewQuadricObj;
а далее пишем следующее (я просто прокомментирую код WMPaint):
quadObj := gluNewQuadric; // новый объект
glRotate(5.0, 0.0, 1.0, 0.0); // повернём
glPushMatrix; // перейдём к новым координатам, сохранив старые
glRotated(-90, 1.0, 0.0, 0.0); // ещё раз повернём
gluSphere(quadObj, 1.3, 20, 20); // а теперь нарисуем сферу "1.3 - радиус",
// а 20 и 20 - это количество разбиений
glPopMatrix; // перейдём к старым координатам
gluDeleteQuadric(quadObj); // эта функция сделает "чёрную" работу
quadObj := gluNewQuadric;
glRotate(9.0, 0.0, 7.0, 0.0);
glPushMatrix;
glRotated(-270, 1.0, 0.0, 0.0);
gluCylinder(quadObj, 0.5, 0.5, 2.9, 30, 30); // 0.5- радиус, 0.5 - радиус, 2.9 - высота
glPopMatrix;
gluDeleteQuadric(quadObj);
Часть 4. Сглаживание[править | править код]
Сглаживание позволяет получить более красивую картинку. По умолчанию сглаживание включено. За включение/выключение этого самого сглаживания отвечает процедура glShadeModel. Параметры у неё следующие:
- GL_SMOOTH - установлено по-умолчанию
- GL_FLAT - отключение режима сглаживания
Кстати интерполяция цветов происходит ТОЛЬКО при включённом сглаживании! Как в этой демке
Существенные различия в работе процедуры с разными параметрами видны невооружонным глазом:
Часть 5. GLAux[править | править код]
До этого мы писали программы с использованием OpenGL и GLUT. Но SGI* приготовила программистам ещё одну библиотеку. GLAUX - библиотека, где есть всё для работы с OpenGL (чтение файла растра, наложение текстуры, построение примитивов...). Правда одно маленькое замечание: в разделе Инструмент вы найдёте glaux.dll в архиве RAR (~160kb), но в распакованном виде она "весит" !1.32 Mb!, и вам придётся "таскать" этот файл вместе со своей программой. Так же в разделе Инструмент вы найдёте заголовки Этой библиотеки для DELPHI и для C++.
!!!ВНИМАНИЕ!!! Кто может "конвертнуть" заголовки из С++ в DELPHI, тот сделает благородное дело для себя и ОСТАЛЬНЫХ!
А теперь поговорим про программировании с этой библиотекой. Откройте новый проект: File -> New -> Application
Теперь в дириктиву "uses" добавьте "glaux" вот так (файл GLAUX.pas должен быть у вас):
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, ExtCtrls, Dialogs, glaux // Подключаем Glaux.pas
Далее в процедуре TForm1.draww, после того как переведём камеру в нужную точку функцией
glTranslatef(0.0, 0.0, -7.0);
можно рисовать всё, что угодно.
procedure TForm1.Draww;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glClearColor(0.7, 0.7, 0.7, 0.0);
glLoadIdentity;
glTranslatef(0.0, 0.0, -7.0);
{}
auxSolidSphere(2.0);
{}
SwapBuffers(DC);
end;
Вот список того, что можно построить:
auxWireSphere(1);
auxSolidSphere(1);
auxWireCube(1);
auxSolidCube(1);
auxWireBox(1, 2, 3);
auxSolidBox(1, 2, 3);
auxWireTorus(1, 2);
auxSolidTorus(1, 2);
auxWireCylinder(1, 2);
auxSolidCylinder(1, 2);
auxWireIcosahedron(1);
auxSolidIcosahedron(1);
auxWireOctahedron(1);
auxSolidOctahedron(1);
auxWireTetrahedron(1);
auxSolidTetrahedron(1);
auxWireDodecahedron(1);
auxSolidDodecahedron(1);
auxWireCone(1, 0.5);
auxSolidCone(1, 0.5);
auxWireTeapot(1);
auxSolidTeapot(1);
Вот и всё!
Source: http://www.ogldelphi.km.ru/about.html
ID: 03944
ID: 03945
ID: 03946
ID: 03947
ID: 03948