Этот урок предполагает, что вы почти или совсем не знакомы с графическим интерфейсом OpenGL, но имеете определённые навыки программирования в среде Delphi. В этом примере рассмотрятся азы работы с этой графической системой. Для компиляции использовалась Delphi7 и модуль dglOpenGL.pas, который можно легко найти в интеренете и прописать в uses. (пример вложен)
Итак, создадим новый проект с формой. Это и будет поле вывода. У формы есть объект Canvas, отвечающий за отрисовку. Фактически он оперирует с контекстом устройства HDC. Этому самому HDC мы сначала должны установить подходящий для OpenGL формат пикселей. Этим займётся следующая процедура:
Code
[b]procedure[/b] SetDCPixelFormat(hdc : HDC);
[b]var[/b]
pfd : TPixelFormatDescriptor;
nPixelFormat : Integer;
[b]begin[/b]
FillChar (pfd, SizeOf (pfd), 0);
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
pfd.iPixelType:=PFD_TYPE_RGBA;
pfd.cColorBits:=32;
nPixelFormat:=ChoosePixelFormat(hdc, @pfd);
SetPixelFormat(hdc, nPixelFormat, @pfd);
hrc:= wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
[b]end;[/b]
[b]procedure[/b] TForm1.FormCreate(Sender: TObject);
[b]begin[/b]
SetDCPixelFormat(Canvas.Handle);
[b]end;[/b]
, причём переменная hrc: HGLRC должна быть глобальной, она потребуется для удаления контекста OGL. Вот, пока не забыл, сразу процедура удаления:
Code
[b]procedure[/b] TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
[b]begin[/b]
wglDeleteContext(hrc);
wglMakeCurrent(0,0);
[b]end;[/b]
Теперь этот контекст нужно активировать, чтобы выводить графику. Создадим процедуру отрисовки. Она большая, поэтому рассмотрим её по частям:
Code
[b]procedure[/b] TForm1.Draw;
[b]var[/b] i: integer;
a: single;
[b]begin[/b]
glViewport(0,0,ClientWidth,ClientHeight);
glClear(GL_COLOR_BUFFER_BIT);
glViewport устанавливает область вывода, в данном случае это вся клиентская область формы.
glClear необходимо вызывать каждый раз перед отрисовкой чтобы очистить старый буфер кадра. Все операции, за редким исключением, в OGL так или иначе находятся под влиянием матриц. Матрица в целом указывает текущую систему координат. В данном случае мы чуть позже будем использовать поворот, а пока что просто зададим модельную матрицу как единичную(identity):
Code
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
Теперь поворот. Он производится процедурой glRotate[f/d...], где 1-й параметр - угол в градусах, а остальные 3 - ось вращения, в данном случае - ось Z "от экрана".
Code
glRotatef(DegToRad(angle)*2,0,0,1);
, тут angle - глобальная переменная, изменяющаяся на 1 по таймеру, думаю приводить этот код не нужно, в конце концоа для этого прикреплён исходник ;-) Нарисуем же наконец что -нибудь!
Code
glBegin(GL_QUADS);
glColor3f(Abs(sin(Angle/10)),0,0);
glVertex2f(5,5);
glVertex2f(5,-5);
glColor3f(Abs(cos(Scale)),0,sin(Angle/10));
glVertex2f(-5,-5);
glVertex2f(-5,5);
glEnd;
Тут надо разобраться... Сначала указывается своего рода "блоках" glBegin..glEnd , где параметр у glBegin указывает тип рисуемого примитива (у нас - четырёхугольник). Внутри блока OGL передаются вершины(glVertex2f(x,y)) и цвета в этих вершинах (glColor3f(r,g,b), где r,g,b [0..1]). Далее продолжение рисования, но уже рисуем треугольники, предварительно увеличив масштаб сцены процедурой glScalef(x,y,z)
Code
glScalef(2,2,2);
for i:=0 to 2 do begin
glRotatef(-15-sin(DegToRad(angle))*6,0,0,1);
glBegin(GL_TRIANGLES);
glColor3f(sin(DegToRad(angle+i*10)),0.0,0.0);
glVertex2f(cos(DegToRad(angle)),sin(DegToRad(angle)));
glColor3f(Abs(cos(DegToRad(angle-i*2))),sin(DegToRad(angle+i*2)),0.0);
glVertex2f(0,0);
glColor3f(0.0,0.0,1.0);
glVertex2f(cos(DegToRad(angle+60)),sin(DegToRad(angle+60)));
glColor3f(1.0,0.0,0.0);
glVertex2f(-cos(DegToRad(angle)),-sin(DegToRad(angle)));
glColor3f(0.0,1.0,0.0);
glVertex2f(0,0);
glColor3f(0.0,0.0,1.0);
glVertex2f(-cos(DegToRad(angle+60)),-sin(DegToRad(angle+60)));
glEnd;
end;
Для полного кайфа можно ещё нарисовать окружность из последовательности треугольников, включив смешивание цветов и поиграв с аргементами этого смешивания =):
Code
glColor3f(1,1,1);
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR,GL_ONE);
glLoadIdentity;
glRotatef(2*angle,0,0,1);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(0,0);
a:=0;
while a <= 2*pi do begin
a:=a+2*pi/360;
glColor3f(cos(a*2),1,sin(a*2));
glVertex2f(cos(a)/2,sin(a)/2);
end;
glEnd;
тут glEnable(GL_BLEND); включает опцию смешивания(может быть и другая опция - в параметре константа)
glBlendFunc(GL_DST_COLOR,GL_ONE); регулирует аргументы смешивания. И наконец, не забываем сменить задний и передний буфер, чтобы вывести изображение:
Code
SwapBuffers(Canvas.Handle);
Рисовать это можно, например, в тике таймера.
Результат должен быть похожим на это:
Вот и всё, так нетрудно начать что-то писать под OpenGL =) Конечно, это только основы основ: ещё 3d, текстурирование, матричные преобразования, но для этого советую почитать, скажем, книгу Краснова про Delphi+OpenGL. И ещё кое-что: учите математику))) пригодится ;-)
Скачать можно с этой странички.
Добавлено (05.12.2009, 00:03)
---------------------------------------------
С вложенными тегами в коде ерунда какая-то (procedure), не пинайте)