CodeNet / Приложения / Графика / Open GL
Использование библиотеки OpenGL в Delphi
Примеры: 3d_1.rar
Содержание
Эта достаточно большая статья посвящена обзору библиотеки расширения OpenGL написанная Ricardo Sarmiento. Все примеры приведенные ниже написаны с использованием этой библиотеки - точнее я нашел примеры и написал статью. Cтатья скорее обзор возможностей технологии OpenGL, чем руководство к программированию. Хотя некоторые функции и процедуры Вы можете использовать и для своих приложений - например чтение файлов DXF.
Хочу разъяснить ситуацию со всевозможными версиями библиотек и заголовочных файлов OpenGL.
Начиная с Delphi 3 в каталоге Source можно найти файл OpenGL.pas - это и есть оригинальная версия заголовков библиотеки OpenGL. Она получена трансляцией файлов Gl.h и Glu.h, соответственно с языка C.
Существует еще одно практически стандартное расширение - Glut. В оригинале Glut.h и ее трансляция на Delphi Glut.pas. Это расширение создано для более быстрого построения различных объектов OpenGL и набор полезных процедур.
Все остальные версии библиотек и заголовков OpenGL являются расширениями стандартной версии и пишутся сторонними производителями. Как и та, о которой пойдет речь ниже.
Призываю использовать стандартную библиотеку OpenGL. Во первых вы получите
наибольшую быстроту исполнения кода, и совместимость. Но в статье я использую
обзор библиотеки расширения OpenGL, почему? Дело в том, что новичку порой
сложно разобраться в дебрях программирования, а расширение стандартной
библиотеки позволяет быстро написать код и получить зрелищный результат.
Именно результат может подтолкнуть вас на дальнейшее изучение библиотеки
OpenGL.
Итак начнем. Приведу иерархию объектов, использованных в данной библиотеке:

Введение
Пример 1
В этом примере рассмотрены следующие вопросы :
Создание сцены TSceneGL
... Scene:TSceneGL; ... Scene:=TSceneGL.create; // Создаем новую сцену ....
Создание объекта TEntity - куб, задание его с помощью TFace, установка цвета и добавление на сцену.
.... cube:Tentity; Face:TFace; .... Cube:=TEntity.create; // Создаем пустой объект TEntity Cube.SetColor(90,200,150); // Инициируем цвета R,G,B Face:=cube.addFace; // Создаем 1-й face в исходном кубе всего 6 граней ( в кубе ) Face.AddVertex(1.0, 1.0, 1.0,0.0, 0.0, 1.0); // добавляем 1-й vertex Face.AddVertex(-1.0, 1.0, 1.0,0.0, 0.0, 1.0); // добавляем 2-й vertex Face.AddVertex(-1.0, -1.0, 1.0,0.0, 0.0, 1.0);// добавляем 3-й vertex Face.AddVertex(1.0, -1.0, 1.0,0.0, 0.0, 1.0);// добавляем 4-й vertex .... Scene.Entities.add(cube);// добавим куб на сцену
Задание источника света Tlight и добавление на сцену.
light:=Tlight.create(1); // создадим источник света и добавим его на сцену Scene.lights.add(light);
Инициализация сцены
// передадим Handle Panel1 нашей сцене, на ней будет происходить рендеринг Scene.InitRC(panel1.handle); Scene.UpdateArea(panel1.width,panel1.height);
Простейший поворот объекта
procedure TForm1.Timer1Timer(Sender: TObject); begin // изменяем rx, ry,rz .... Tentity(Scene.Entities.Items[0]).Rotate(rx,ry,rz); // повернем куб Scene.Redraw; // ... и обновим сцену end;

Пример 2
Отличия от предыдущего примера: Оъекта TEntity - дельфин задается не через TFace, а грузится из DXF файла - что очень упрощает жизнь.
...
Dolphin:=TEntity.create;
Dolphin.SetColor(100,100,160);
Dolphin.LoadDXF('..Dolphin.dxf',true);
with dolphin do
begin
move(0,0,-15); // переместим немного назад
rotate(-30,-30,-30); // и повернем
end;
Scene.entities.add(dolphin); // добавим дельфина на сцену
...

Пример 3
Изменения: У объекта Dolphin ищутся нормали к TFace, при этом получается эффект объемного пространства:
.... Dolphin.CalcNormals; // высчитываем нормали векторов объекта Dolphin.Center; ....

Пример 4
Добавили класс T3DMouse - теперь можно манипулировать объектами.
procedure TForm1.FormCreate(Sender: TObject); .... Mouse:=T3DMouse.create(dolphin); // Создаем T3DMouse для нашего объекта Mouse.scale(1,1,0.1,1,1,1); // задаем скорость перемещения и поворота ....
Перемещение объекта можно осуществить:
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Mouse.move(x,y,shift); // обновляем объект - дельфин в новых координатах Scene.Redraw; // перерисуем сцену end;
Можно установить блокировку на перемещение :
... Mouse.Block(4,TspeedButton(sender).down); // блокировка поворота rx ...

Пример 5
Добавим управление отображением :
....
case dolphin.wireframe of
0:begin
speedbutton5.caption:='Линии';
dolphin.wireframe:=1;
end;
1:begin
speedbutton5.caption:='Заливка';
dolphin.wireframe:=2;
end;
2:begin
speedbutton5.caption:='Точки';
dolphin.wireframe:=0;
end;
end;
Scene.Redraw; // обновим сцену
...

Пример 6
Соберем все в один пример, добавим возможность печати и покажем FPS при повороте.

Ну вот, самая основа должна стать Вам понятна. Если у Вас не запускаются примеры, проверьте наличие библиотек Opengl32.dll и Glu32.dll. Исходники примеров находятся в каталогах Demo1-XXX.
Текстуры
Эта глава посвящена текстурированию объектов в OpenGL. В каждом примере я даю пояснения только к новому. По этому лучше посмотреть сначала пример 1 потом 2, а не начинать с примера 5. В этой главе описаны примеры использующие фильтрации текстур, и при использовании GL_linear нужен 3D ускоритель, иначе будет работать ОЧЕНЬ медленно.
Пример 1
Закрашиваем полигоны
....
point:TVertex;
....
begin
// Получаем выбранный полигон при нажатии на панель Panel1
mouse.FindVertex(x,panel1.height-y,Scene,point);
for i:=1 to numFound do // Для всех полигонов найденных по Mouse.FindVertex
begin
poly:=VertexHits[i] shr 16;
vert:=VertexHits[i] mod 65536;
If (poly "

Пример 2
Формат DXF является очень неудобным для записи т.к. имеет большие размеры.
Для этого автор создает другой формат записи. Добавлена функция чтения-записи.

Пример 3
Наложение текстур на объект
thing.CreateTexture; // добавим текстуры на объект
thing.texture.LoadTexture('texture.bmp');
thing.texture.automatic:=False;
...
// а далее идет рутинный процесс задания вершин для текстур у каждой поверхности объекта
with thing do
begin
vertex:=Tvertex(Tface(thing.faces.items[1]).vertices.items[0]);// x,y,z =0,0,0
vertex.tx:=1;
vertex.tz:=0;
...
end;
Да в качестве эксперимента вы можете убрать все начиная с with thing do
..... end (задания точек для текстур ) и переписать thing.texture.automatic:=true.
Использование типов фильтрации текстур
thing.Texture.MagFilter:=GL_linear;
или
thing.Texture.MagFilter:=GL_nearest;

Пример 4
Установка прозрачности у текстур (альфа каналов)
thing.texture.EnvironmentMode:=GL_decal; // Установка transparent texturing
thing.texture.envblendcolor[3]:=scrollbar1.position; // Значение 0 - 255
При запуске программы сначала создается сцена с освещением, но объект
создается только после установки, по выполнению процедуры FormCreate_partII.

Пример 5
Программная текстура :) Процесс прост - при нажатии на кнопки с цифрами мы
создаем TBitmap и через его Canvas пишем эти цифры. Далее сохраняем этот
ТBitmap в файл 'texture.bmp'. Удаляем с экрана компа старую текстуру и
загружаем новую из ранее созданного 'texture.bmp'.

Исходные тексты всех примеров находятся в каталогах Demo2-XXX
Освещение
Пример 1
В этом примеры показано как задать параметры источника. Ранее источник
света задавался по умолчанию. Создадим источник типа прожектор
(CLspot). Light:=Tlight.create(1);
Light.LightType:=CLspot;
Light.CutOffAngle:=5;
Light.SpotExponent:=100;
Параметр CutOffAngle - угол расхождения луча.
SpotExponent - параметр затухания источника.
Light.SetOrientation(0,-1,0);
Light.Source.SetPosition(0,5,-20);
Грубо говоря это коэфициент показывающий как далеко пройдет свет. Если
SpotExponent=0, то пучек света уходит в бесконечность. Идем далее :
Задаем ориентацию прожектора и его положение в системе координат.
При изменении позиций полос прокрутки просто меняем компоненты цвета в
источнике. Например для Ambient :
SBlightRed.position:=round(Light.Fambient[0] * 100);
SBlightGreen.position:=round(Light.Fambient[1] * 100);
SBlightBlue.position:=round(Light.Fambient[2] * 100);

Пример 2
Наиболее полно контролируем параметры освещения и даже перемещем источник в
пространстве.

Все, исходные тексты всех примеров этой главы вы найдете в каталогах
Demo3-XXX
Туман
Пример 1
Установить поддержку тумана в сцене очень просто :
scene:TSceneGL;
...
scene.fogEnabled:=True;
Все остальное в примере это установка параметров тумана :
Тип тумана может быть :
fogType:=Gl_Linear;
fogType:=GL_exp;
fogType:=GL_exp2;
Минимальная и максимальная дистанция :
- fogMaxDist
- fogMinDist
Интенсивность :
- fogDensity
Цвет для каждой компоненты RGB :
- scene.fogcolor[0]; R
- scene.fogcolor[1]; G
- scene.fogcolor[2]; B
После каждого изменения параметров не забывайте вызывать Redraw. Для нормального эффекта тумана очень важно подобрать правильный цвет фона и самого тумана. Они должны примерно совпадать /см картинку /.

Примеры находятся в каталоге Demo4-XXX.
Оставить комментарий
Оставлять комментарии могут только зарегистрированные пользователи.
Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.
Комментарии
1. korolga78 / 06 февраля 2011, 10:32:51

Помогите, я не согу добавить компоненты, он выдает ошибку


2. SeruF / 15 декабря 2010, 23:52:11

Скажите, как загрузить в вашу программу другой dfx файл? странно как-то, вписываю,допустим, passjet.dxf, и не работает, там привязка или параметр какой особенный?


3. Новичёк / 16 октября 2004, 16:24:41

Осень Осень хорошие экзамплы

Первый пример (1-1) сделан очень грамотно. Если не помучаешся не компилится - мудрое решение, а то развелись всякие способные программировать методом копи-пасте
Но всё же файл GLDRIVER.INC который можно редактировать чего-то потерялся.
