[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: MiniTiv2008  
Форум » Создание игр » Программирование » OpenGL в Delphi для начинающих (Небольшой пример вывода графики на плоскость в OpenGL)
OpenGL в Delphi для начинающих
MolchДата: Суббота, 05.12.2009, 00:03 | Сообщение # 1
Сержант
Группа: Пользователь
Сообщений: 12
Награды: 0
Репутация: 5
Статус:
Этот урок предполагает, что вы почти или совсем не знакомы с графическим интерфейсом 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), не пинайте)

Прикрепления: 0023650.jpg (165.9 Kb)
 
Форум » Создание игр » Программирование » OpenGL в Delphi для начинающих (Небольшой пример вывода графики на плоскость в OpenGL)
  • Страница 1 из 1
  • 1
Поиск: