Библиотека OpenGL считается стандартной для многих современных операционных систем, в том числе и для операционных систем семейства Windows. Она представляет собой не отдельную программу, а некоторую часть операционной системы. В состав стандартной поставки среды программирования Borland Delphi входит заголовочный файл OpenGL.pas, позволяющий строить приложения с использованием библиотеки OpenGL, а также справочный файл по командам этой библиотеки. Однако, на наш взгляд, новичку сразу разобраться в деталях программирования с использованием OpenGL достаточно сложно. Поэтому кратко рассмотрим в качестве примера следующий небольшой программный модуль, в котором на экран выводится фонтан. unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL, ExtCtrls, StdCtrls;
type
TfrmGL = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure Timer1Timer(Sender: TObject);
private
DC : HDC;
hrc: HGLRC;
protected
procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
end;
var
frmGL: TfrmGL;
implementation
{$R *.DFM}
const
POINT_COUNT = 3000;
var
points: array [0..POINT_COUNT - 1] of TGLArrayf3;
motion: array [0..POINT_COUNT - 1] of TGLArrayf3;
{Процедура формирования фонтана}
procedure UpdatePOINT(i: Word);
begin
points[i][0] := points[i][0] + motion[i][0];
points[i][1] := points[i][1] + motion[i][1];
if points[i][1] < -0.9 then begin
points[i][0] := 0.0;
points[i][1] := -0.6;
motion[i][0] := (Random - 0.5) / 20;
motion[i][1] := Random / 7 + 0.02;
end
else motion[i][1] := motion[i][1] - 0.01;
end;
{Процедура перерисовки окна}
procedure TfrmGL.WMPaint(var Msg: TWMPaint);
var
ps: TPaintStruct;
i : GLUint;
begin
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
for i := 0 to POINT_COUNT - 1 do begin
UpdatePOINT(i);
glVertex3fv(@points[i]);
end;
glEnd;
SwapBuffers(DC);
end;
{Процедура установки формата пикселя}
procedure SetDCPixelFormat(hdc: HDC);
var
pfd : TPixelFormatDescriptor;
nPixelFormat: Integer;
begin
FillChar(pfd, SizeOf(pfd), 0);
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
nPixelFormat := ChoosePixelFormat(hdc, @pfd);
SetPixelFormat(hdc, nPixelFormat, @pfd);
end;
{Процедура создания формы}
procedure TfrmGL.FormCreate(Sender: TObject);
begin
DC := GetDC(Handle);
SetDCPixelFormat(DC);
hrc := wglCreateContext(DC);
wglMakeCurrent(DC, hrc);
glPointSize(1);
glColor3f(0, 0.7, 0.9);
end;
{Процедура завершения работы приложения}
procedure TfrmGL.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0, 0);
wglDeleteContext(hrc);
ReleaseDC(Handle, DC);
DeleteDC(DC);
end;
{Процедура нажатия клавиши ESC}
procedure TfrmGL.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If Key = VK_ESCAPE then Close;
end;
{Процедура обработки событий таймера}
procedure TfrmGL.Timer1Timer(Sender: TObject);
begin
InvalidateRect(Handle, nil, False);
end;
end.
В списке uses расположен необходимый для работы приложения модуль OpenGL.pas. Количество точек (капелек, из которых состоит фонтан) определяется константой POINT_COUNT. Изучение программы начнем с процедуры создания формы FormCreate. Вывод изображения фонтана на поверхность формы начинается с команд: DC := GetDC(Handle);SetDCPixelFormat; hrc := wglCreateContext(DC); wglMakeCurrent(DC, hrc); Первым аргументом функции, расположенной в последней строке, является ссылка на контекст устройства (величина DC типа HDC), на который будет осуществляться вывод. В нашем случае это окно формы (DC := GetDC(Handle)). Для получения контекста необходима величина hrc типа HGLRC (hrc := wglCreateContext(DC)). Затем строка glPointSize(1) задает размер точек (в нашем случае это один пиксель), а строка glColor3f(0, 0.7, 0.9) указывает их цвет. Процедура SetDCPixelFormat задает формат пикселя, который определяет конфигурацию буфера цвета и вспомогательных буферов. Сначала полям структуры присваиваются нужные значения: FillChar(pfd, SizeOf(pfd), 0);pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; Иными словами, системе сообщается, что вывод будет осуществляться в окно (PFD_DRAW_TO_WINDOW), что библиотека OpenGL поддерживается (PFD_SUPPORT_OPENGL) и что будет использоваться двойная буферизация (PFD_DOUBLEBUFFER).
Затем функция ChoosePixelFormat(hdc, @pfd) возвращает формат пикселя, который нужен в качестве аргумента функции SetPixelFormat(hdc, nPixelFormat, @pfd).
В процедуре WMPaint cтрока glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) очищает экран и окрашивает его заданным цветом. Строка glBegin(GL_POINTS), как говорят, открывает командную скобку, а строка glEnd закрывает ее. Строки, расположенные между ними, задают область вывода на экран графических примитивов (в нашем случае точек, так как используется константа GL_POINTS). Причем создание формы фонтана происходит в специальной процедуре UpdatePOINT. Команда SwapBuffers(DC) используется в режиме двойной буферизации для вывода на экран содержимого заднего буфера. Обработка событий таймера заключается в том, что двадцать раз в секунду перерисовывается окно программы (строка InvalidateRect(Handle, nil, False)). При завершении работы программы вызывается процедура FormDestroy, с помощью которой освобождается и удаляется контекст устройства. Выход из программы может осуществляться при нажатии на клавишу ESC, что описано в процедуре FormKeyDown. Результат работы программы представлен в видеофрагменте. |