Уроки, алгоритмы, программы, примеры

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

У меня проблема вот с этим: gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);. Вылезает ошибка: CS1061 "object" не содержит определения "GL_COLOR_BUFFER_BIT", и не удалось найти доступный метод расширения "GL_COLOR_BUFFER_BIT",...
Большое спасибо. Единственный код который прошел без каких либо ошибок. Ура!!!
Скажите пожалуйста, подскажите алгоритм по которому по заданным точкам можно определить тип многогранника, скажем это куб или прямоугольный параллелепипед. Нашел теорию по этим фигурам: https://www.mat... https://www.mat... Акцентировать внимание...
Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Среда программирования: 
Delphi (Lazarus)

OpenGL (Open Graphics Library — открытая графическая библиотека) — спецификация, определяющая независимый от языка программирования кросс-платформенный программный интерфейс для написания приложений, использующих двумерную и трёхмерную компьютерную графику.

Включает более 250 функций для рисования сложных трёхмерных сцен из простых примитивов. Используется при создании компьютерных игр, САПР, виртуальной реальности, визуализации в научных исследованиях. На платформе Windows конкурирует с Direct3D.

Основные возможности OpenGL

Что предоставляет библиотека в распоряжение программиста? Основные возможности:

  • Геометрические и растровые примитивы. На основе геометрических и растровых примитивов строятся все объекты. Из геометрических примитивов библиотека предоставляет: точки, линии, полигоны. Из растровых: битовый массив(bitmap) и образ(image)
  • Использование В-сплайнов. B-сплайны используются для рисования кривых по опорным точкам.
  • Видовые и модельные преобразования. С помощью этих преобразований можно располагать обьекты в пространстве, вращать их, изменять форму, а также изменять положение камеры из которой ведётся наблюдение.
  • Работа с цветом. OpenGL предоставляет программисту возможность работы с цветом в режиме RGBA (красный-зелёный-синий-альфа) или используя индексный режим, где цвет выбирается из палитры.
  • Удаление невидимых линий и поверхностей. Z-буферизация.
  • Двойная буферизация. OpenGL предоставляет как одинарную так и двойную буферизацию. Двойная буферизация используется для того, чтобы устранить мерцание при мультипликации, т.е. изображение каждого кадра сначала рисуется во втором(невидимом) буфере, а потом, когда кадр полностью нарисован, весь буфер отображается на экране.
  • Наложение текстуры. Позволяет придавать объектам реалистичность. На объект, например шар, накладывается текстура(просто какое-то изображение), в результате чего наш объект теперь выглядит не просто как шар, а как разноцветный мячик.
  • Сглаживание. Сглаживание позволяет скрыть ступенчатость, свойственную растровым дисплеям. Сглаживание изменяет интенсивность и цвет пикселей около линии, при этом линия смотрится на экране без всяких зигзагов.
  • Освещение. Позволяет задавать источники света, их расположение, интенсивность, и т.д.
  • Атмосферные эффекты. Например туман, дым. Всё это также позволяет придать объектам или сцене реалистичность, а также "почувствовать" глубину сцены.
  • Прозрачность объектов.
  • Использование списков изображений.

Дополнительные библиотеки

Для OpenGL существуют так называемые вспомогательные библиотеки.

Первая из этих библиотек называется GLU. Эта библиотека уже стала стандартом и поставляется вместе с главной библиотекой OpenGL. В состав этой библиотеки вошли более сложные функции, например для того чтобы определить цилиндр или диск потребуется всего одна команда. Также в библиотеку вошли функции для работы со сплайнами, реализованы дополнительные операции над матрицами и дополнительные виды проекций.

Следующая библиотека, также широко используемая - это GLUT. Это также независимая от платформы библиотека. Она реализует не только дополнительные функции OpenGL, но и предоставляет функции для работы с окнами, клавиатурой и мышкой. Для того чтобы работать с OpenGL в конкретной операционной системе (например Windows или X Windows), надо провести некоторую предварительную настройку и эта предварительная настройка зависит от конкретной операционной системы. С библиотекой GLUT всё намного упрощается, буквально несколькими командами можно определить окно, в котором будет работать OpenGL, определить прерывание от клавиатуры или мышки и всё это не будет зависеть от операционной системы. Библиотека предоставляет также некоторые функции, с помощью которых можно определять некоторые сложные фигуры, такие как конусы, тетраэдры, и даже можно с помощью одной команды определить чайник!

Есть ещё одна библиотека похожая на GLUT, называется она GLAUX. Это библиотека разработана фирмой Microsoft для операционной системы Windows. Она во многом схожа с библиотекой GLUT, но немного отстаёт от неё по своим возможностям. И ещё один недостаток заключается в том, что библиотека GLAUX предназначена только для Windows, в то время как GLUT поддерживает очень много операционных систем.

Синтаксис команд

type glCommand_name[1 2 3 4][b s i f d ub us ui][v]
                   (type1 arg1,…,typeN argN)

Таким образом, имя состоит из нескольких частей: Gl это имя библиотеки, в которой описана эта функция: для базовых функций OpenGL, функций из библиотек GLU, GLUT, GLAUX это gl, glu, glut, glaux соответственно
Command_name - имя команды
[1 2 3 4] – число аргументов команды
[b s i f d ub us ui] – тип аргумента:
b - GLbyte байт,
s - GLshort короткое целое,
i - GLint целое,
f - GLfloat дробное,
d - GLdouble дробное с двойной точностью,
ub - GLubyte беззнаковый байт,
us - GLushort беззнаковое короткое целое,
ui - GLuint беззнаковое целое.

Полный список типов и их описание можно посмотреть в файле gl.h.
[v] – наличие этого символа показывает, что в качестве параметров функции используется указатель на массив значений.

Рисование геометрических объектов

Очистка окна.

glClearColor (clampf r, clampf g, clampf b, clampf a)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

Вершины и примитивы

Вершина является атомарным графическим примитивом OpenGL и определяет точку, конец отрезка, угол многоугольника и т.д. Все остальные примитивы формируются с помощью задания вершин, входящих в данный примитив. Например, отрезок определяется двумя вершинами, являющимися концами отрезка.

С каждой вершиной ассоциируются ее атрибуты. В число основных атрибутов входят положение вершины в пространстве, цвет вершины и вектор нормали.
Положение вершины в пространстве

Положение вершины определяются заданием ее координат в двух-, трех-, или четырехмерном пространстве (однородные координаты). Это реализуется с помощью нескольких вариантов команды glVertex*:

void glVertex[2 3 4][s i f d] (type coords)
void glVertex[2 3 4][s i f d]v (type *coords)

Каждая команда задает четыре координаты вершины: x, y, z, w. Команда glVertex2* получает значения x и y. Координата z в таком случае устанавливается по умолчанию равной 0, координата w – равной 1. Vertex3* получает координаты x, y, z и заносит в координату w значение 1. Vertex4* позволяет задать все четыре координаты.

Для ассоциации с вершинами цветов, нормалей и текстурных координат используются текущие значения соответствующих данных, что отвечает организации OpenGL как конечного автомата. Эти значения могут быть изменены в любой момент с помощью вызова соответствующих команд.

Цвет вершины

Для задания текущего цвета вершины используются команды :

void glColor[3 4][b s i f] (GLtype components)
void glColor[3 4][b s i f]v (GLtype components)

Первые три параметра задают R, G, B компоненты цвета, а последний параметр определяет коэффициент непрозрачности (так называемая альфа-компонента). Если в названии команды указан тип ‘f’ (float), то значения всех параметров должны принадлежать отрезку [0,1], при этом по умолчанию значение альфа-компоненты устанавливается равным 1.0, что соответствует полной непрозрачности. Тип ‘ub’ (unsigned byte) подразумевает, что значения должны лежать в отрезке [0,255].

Вершинам можно назначать различные цвета, и, если включен соответствующий режим, то будет проводиться линейная интерполяция цветов по поверхности примитива.

Для управления режимом интерполяции используется команда

void glShadeModel (GLenum  mode)

вызов которой с параметром GL_SMOOTH включает интерполяцию (установка по умолчанию), а с GL_FLAT – отключает.

Нормаль

Определить нормаль в вершине можно, используя команды

void glNormal3[b s i f d] (type coords) 
void glNormal3[b s i f d]v (type coords)

Для правильного расчета освещения необходимо, чтобы вектор нормали имел единичную длину. Командой glEnable(GL_NORMALIZE) можно включить специальный режим, при котором задаваемые нормали будут нормироваться автоматически.

Режим автоматической нормализации должен быть включен, если приложение использует модельные преобразования растяжения/сжатия, так как в этом случае длина нормалей изменяется при умножении на модельно-видовую матрицу.

Однако применение этого режима уменьшает скорость работы механизма визуализации OpenGL, так как нормализация векторов имеет заметную вычислительную сложность (взятие квадратного корня и т.п.). Поэтому лучше сразу задавать единичные нормали.

Отметим, что команды

void glEnable (GLenum mode)
void glDisable (GLenum mode)

производят включение и отключение того или иного режима работы конвейера OpenGL. Эти команды применяются достаточно часто, и их возможные параметры будут рассматриваться в каждом конкретном случае.

Операторные скобки glBegin / glEnd

Мы рассмотрели задание атрибутов одной вершины. Однако, чтобы задать атрибуты графического примитива, одних координат вершин недостаточно. Эти вершины надо объединить в одно целое, определив необходимые свойства. Для этого в OpenGL используются так называемые операторные скобки, являющиеся вызовами специальных команд OpenGL Определение примитива или последовательности примитивов происходит между вызовами команд

void glBegin (GLenum mode);
void glEnd (void);

Параметр mode определяет тип примитива, который задается внутри и может принимать следующие значения: GL_POINTS каждая вершина задает координаты некоторой точки.

  • GL_LINES каждая отдельная пара вершин определяет отрезок; если задано нечетное число вершин, то последняя вершина игнорируется.
  • GL_LINE_STRIP каждая следующая вершина задает отрезок вместе с предыдущей.
  • GL_LINE_LOOP отличие от предыдущего примитива только в том, что последний отрезок определяется последней и первой вершиной, образуя замкнутую ломаную.
  • GL_TRIANGLES каждая отдельная тройка вершин определяет треугольник; если задано не кратное трем число вершин, то последние вершины игнорируются.
  • GL_TRIANGLE_STRIP каждая следующая вершина задает треугольник вместе с двумя предыдущими.
  • GL_TRIANGLE_FAN треугольники задаются первой и каждой следующей парой вершин (пары не пересекаются).
  • GL_QUADS каждая отдельная четверка вершин определяет четырехугольник; если задано не кратное четырем число вершин, то последние вершины игнорируются.
  • GL_QUAD_STRIP четырехугольник с номером n определяется вершинами с номерами 2n-1, 2n, 2n+2, 2n+1.
  • GL_POLYGON последовательно задаются вершины выпуклого многоугольника.

Например, чтобы нарисовать треугольник с разными цветами в вершинах, достаточно написать:

glBegin(GL_TRIANGLES); 
glColor3f(1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); 
glColor3ub(0,255,0); glVertex3f(1.0, 0.0, 0.0); 
glColor3fv(BlueCol); glVertex3f(1.0, 1.0, 0.0); 
glEnd();

Установка пакета получения контекста устройства в Lazarus

Как и в любой среде программирования, для того чтобы начать работать с графикой, необходимо получить контекст устройства и связать его с контекстом воспроизведения библиотеки OpenGL. В Lazarus этот процесс осуществляется довольно просто, за счет использования встроенной библиотеки OpenGLContext с готовым компонентом TOpenGLControl.

Однако компонент TOpenGLControl, по — умолчанию, не установлен в среде Lazarus, поэтому необходимо установить данный компонент. Выберите пункт меню "Пакет -> Установить/Удалить пакеты" (Package -> Install/Uninstall Packages), откроется окно установки новых пакетов в среду Lazarus.

В окне установки новых пакетов, в списке неустановленных пакетов, необходимо найти пакет с именем lazopenglcontext 0.0.1, выбрать его и нажать кнопку "Установить выбранное" (Install selection). После этого необходимо нажать кнопку "Сохранить и перезапустить IDE" (Save and Rebuild IDE), для пересборки Lazarus уже с компонентом TOpenGLControl. В окне подтверждения установки нового пакета, нажмите кнопку "Продолжить" (Continue).

Если все проделано верно, то в панели инструментов появится вкладка OpenGl с компонентом TOpenGLControl.

Можно начинать работать с библиотекой.

Простейшая программа на OpenGL в Lazarus

Расположите на форме два компонента

Panel1: TPanel  
Button1: TButton

пропишите следующий код на события OnCreate и ButtonClick

unit Unit1; 
 
{$mode objfpc}{$H+}
 
interface
 
// Подключение библиотек. Для работы C OpenGL необходимы OpenGLContext, GL, GLU
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, OpenGLContext, GL, GLU;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    OpenGLControl1: TOpenGLControl; // Контекст воспроизведения OpenGL
  end; 
 
var
  Form1: TForm1; 
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
 
begin
  // Создание контекста воспроизведения OpenGL и привязка его к панели на форме
  OpenGLControl1:=TOpenGLControl.Create(Self);
  with OpenGLControl1 do begin
    Name:='OpenGLControl1';
    Align:=alClient;
    Parent:=Panel1;
  end;
 
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
 glClearColor (0, 0, 0, 0); // цвет фона
 glClear (GL_COLOR_BUFFER_BIT);      // очистка буфера цвета
 glMatrixMode(GL_MODELVIEW);  // Выбор видовой матрицы
 glLoadIdentity();   //  Установка в единичные значения
 glOrtho(0, 1, 0, 1, -1 ,1); // Установка проекции окна
 //glTranslatef(0.5,0.5,0);  // Сдвиг
 //glRotatef(10, 0, 0, 0);   // Вращение
 glBegin(GL_TRIANGLES);      // Рисование треугольника
       glColor3f(1.0,0.0,0.0);     // Красный
       glVertex3f(1,0,0 ); // Верх треугольника (Передняя)
       glColor3f(0.0,1,0.0);
       glVertex3f( 0,1,0);
       glColor3f(0,0,1);
       glVertex3f( 0,0,0);
 glEnd;
 OpenGLControl1.SwapBuffers; // Отрисовка из буффера
end;
 
end.              

Комментарии

ujif аватар
Опубликовано ujif в 4. Июнь 2015 - 8:32.

не могу понять как в этой процедуре glOrtho(0, 1, 0, 1, -1 ,1);
координаты работают, Top ставлю = 2 и треугольник выводится
с вертикальным катетом в половину меньшим
если еще Left = 2 тогда оба катета вполовину меньше
а 0 это всегда нижний левый угол ?
наглядности мало , гадать приходится, а в инете все как обычно
можно сутками сидеть и по 0

admin аватар
Опубликовано admin в 4. Июнь 2015 - 10:46.

См. следующий урок: Вращение, движение, масштабирование и проекции в OpenGL. Там как раз рассматривается что за параметры передаются в процедуру glOrtho.

ujif аватар
Опубликовано ujif в 28. Май 2015 - 17:10.

программа компилируется ,но при запуске выводится сообщение
'Class "TOpenGLControl" not found'

ujif аватар
Опубликовано ujif в 28. Май 2015 - 21:08.

непонятно почему, но перестал жаловаться на отсутствие класса
но код все равно не работал , при нажатии кнопки ничего не происходило
обратился на форум , прислали точно такой же код - никакого отличия
весь свой стер заменил на тот что прислали - заработало все ????
глюки какие то у меня наверно в лазаре

Романцова Анна аватар
Опубликовано Романцова Анна в 13. Май 2017 - 9:22.

Сейчас проверила нашла причину не запускания

// Создание контекста воспроизведения OpenGL и привязка его к панели на форме
  OpenGLControl1:=TOpenGLControl.Create(Self);
  with OpenGLControl1 do begin
    Name:='OpenGLControl1'; //вот тут поставила цифру(не 1) любую другую и запустилось