Использование библиотеки OpenGL
Содержание
Введение
Использование библиотеки OpenGL - Введение
Использование библиотеки OpenGL - Текстуры
Использование библиотеки OpenGL - Освещение
Использование библиотеки OpenGL - Туман
Список ссылок
Введение
Эта достаточно большая статья посвящена обзору библиотеки расширения 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.
Итак начнем. Приведу иерархию объектов, использованных в данной библиотеке:
Использование библиотеки 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 - Текстуры
Эта глава посвящена текстурированию объектов в 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 "<" Dolphin.Faces.count) and
(vert"<"Tface(Dolphin.Faces.Items[poly]).Vertices.count)
then
begin
// получаем составляющие цвета из ColorActual
(TColor)
ir:=(ColorActual) mod 256; // R
ig:=(ColorActual shr 8) mod 256; //
G
ib:=(ColorActual shr 16) mod 256; //
B
Tvertex(Tface(Dolphin.Faces.Items[poly].
Vertices.items[vert]).point.setcolor(ir,ig,ib);
end;
end;
end; |
Пример 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
Использование библиотеки OpenGL - Освещение
Пример 1
В этом примеры показано как задать параметры источника. Ранее источник света
задавался по умолчанию. Создадим источник типа прожектор
(CLspot). Light:=Tlight.create(1);
Light.LightType:=CLspot;
Light.CutOffAngle:=5;
Light.SpotExponent:=100;
Параметр CutOffAngle - угол расхождения луча.
SpotExponent - параметр затухания источника. |
Грубо говоря это коэфициент показывающий как далеко пройдет свет. Если SpotExponent=0,
то пучек света уходит в бесконечность. Идем далее :
Light.SetOrientation(0,-1,0);
Light.Source.SetPosition(0,5,-20); |
Задаем ориентацию прожектора и его положение в системе координат.
При изменении позиций полос прокрутки просто меняем компоненты цвета в источнике.
Например для 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
Использование библиотеки OpenGL - Туман
Пример 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.
Список ссылок
Исходный код всех примеров |
|
Адрес автора библиотеки |
|
|