Внимание!
Данный пример основан на следующих
статьях и примерах из сети Интернет:
1) Статья с
сайта LinuxFocus.org — Программирование
GLUT: окна и анимация, автор Miguel Angel
Sepulveda.
2) Пример куба
с сайта
с примерами по OpenGL.
Ну и конечно
же, для создания проекта использовалась
среда Lazarus 1.0.8 и дистрибутив Fedora 19 Linux.
В
данном посте, на примере, показывается
использование OpenGL в Lazarus.
Для
начала нам необходимо инициализировать
OpenGL. Создадим
новый проект Lazarus.
Выбираем пункт меню File > New,
откроется окно выбора нового шаблона.
Нам нужен шаблон, который находится в
разделе Project >
Program и
нажимаем кнопку Ok,
чтобы подтвердить выбор (Смотрите
рисунок 1).
Рисунок
1. Окно выбора нового шаблона проекта
Сохраним
проект под именем ogl_p1.lpr.
Выбираем пункт
меню File > Save As
и сохраняем в домашнюю директорию
пользователя, в каталог по следующему
пути ~/Projects/lazarus/ogl_p1/,
где ~ (знак тильда) это домашний каталог
пользователя.
Теперь в редакторе исходного кода
убираем весь код кроме следующего:
program
ogl_p1;
begin
end.
Добавим
в наш исходный код секцию uses, в которой
мы перечислим модули необходимые нам
для работы с OpenGL. Первый
модуль который мы должны добавить
называется gl, это
основной модуль
OpenGL. Второй модуль называется glut, этот
модуль позволяет создавать OpenGL окно.
Таким образом, у
нас вышла строчка:
uses gl,
glut;
Ниже
секции uses, определим
переменные, константы и процедуры
необходимые нам для создания проекта.
Секция
var:
var
Cmd: array
of PChar;
CmdCount:
Integer;
ScreenWidth,
ScreenHeight: Integer;
Здесь
можно видеть переменную Cmd для
хранения имен параметров командной
строки, переменную CmdCount для хранения
количества параметров командной строки,
и две переменные ScreenWidth,
ScreenHeight для
хранения размеров экрана по ширине и
высоте, соответственно.
Секция
const:
const
AppWidth =
400;
AppHeight
= 400;
Константы
AppWidth и AppHeight содержат размер окна OpenGL.
Процедура
DrawGLScene:
Данная
процедура будет вызвана при рисование
сцены в окне OpenGL. В данной процедуре мы
очистим цветовой буфер и буфер глубины.
Далее мы создаем шесть четырехсторонних
полигона, каждый полигон состоит из
четырех вершин. И после того как сцена
нарисована мы переключаем буфер для её
отображения.
procedure
DrawGLScene; cdecl;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
glNormal3f( 0.0, 0.0, 1.0);
glVertex3f( 0.5, 0.5, 0.5); glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5,-0.5, 0.5); glVertex3f( 0.5,-0.5, 0.5);
glNormal3f( 0.0, 0.0,-1.0);
glVertex3f(-0.5,-0.5,-0.5); glVertex3f(-0.5, 0.5,-0.5);
glVertex3f( 0.5, 0.5,-0.5); glVertex3f( 0.5,-0.5,-0.5);
glNormal3f( 0.0, 1.0, 0.0);
glVertex3f( 0.5, 0.5, 0.5); glVertex3f( 0.5, 0.5,-0.5);
glVertex3f(-0.5, 0.5,-0.5); glVertex3f(-0.5, 0.5, 0.5);
glNormal3f( 0.0,-1.0, 0.0);
glVertex3f(-0.5,-0.5,-0.5); glVertex3f( 0.5,-0.5,-0.5);
glVertex3f( 0.5,-0.5, 0.5); glVertex3f(-0.5,-0.5, 0.5);
glNormal3f( 1.0, 0.0, 0.0);
glVertex3f( 0.5, 0.5, 0.5); glVertex3f( 0.5,-0.5, 0.5);
glVertex3f( 0.5,-0.5,-0.5); glVertex3f( 0.5, 0.5,-0.5);
glNormal3f(-1.0, 0.0, 0.0);
glVertex3f(-0.5,-0.5,-0.5); glVertex3f(-0.5,-0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5); glVertex3f(-0.5, 0.5,-0.5);
glEnd();
glutSwapBuffers;
end;
Процедура
ReSizeGLScene:
Данная
процедура вызывается каждый раз когда
изменяются размеры окна. В данной
процедуре мы перестраиваем сцену под
измененный размер окна.
procedure
ReSizeGLScene(Width, Height: Integer); cdecl;
begin
glViewport(0,
0, Width, Height);
end;
Процедура
GLKeyboard:
Вызывается
каждый раз при нажатие на любую клавишу
клавиатуры. В данном случае проверяется
нажата ли клавиша Esc, код которой 27, если
нажата, то программа завершает свою
работу.
procedure
GLKeyboard(Key: Byte; X, Y: Longint); cdecl;
begin
if Key =
27 then
Halt(0);
end;
Процедура
InitializeGL:
В
данном проекте используется для начальной
инициализации сцены OpenGL. В
данном случае здесь устанавливается
точка обзора сцены, подключается световой
источник.
procedure
InitializeGL;
begin
glMatrixMode(GL_PROJECTION);
glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, -2.0);
glRotatef(30.0, 1.0, 0.0, 0.0);
glRotatef(30.0, 0.0, 1.0, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
end;
Теперь
перейдем к описанию кода внутри главных
операторных скобок.
Сначала
мы присвоим переменной CmdCount значение
1, оно говорит о том что программа будет
иметь один параметр командной строки.
Далее мы устанавливаем длину массива
Cmd на хранения одной строки SetLength(Cmd,
CmdCount), это строка является параметром,
который содержит имя программы. Заносим
в массив Cmd единственный параметр имя
программы Cmd[CmdCount-1] := Pchar(ParamStr(CmdCount-1)):
CmdCount :=
1;
SetLength(Cmd,
CmdCount);
Cmd[CmdCount-1]
:= PChar(ParamStr(CmdCount-1));
Проведем
инициализацию GLUT.
glutInit(@CmdCount,
@Cmd);
Выбор
режима, двойной буфер, RGB палитра и буфер
глубины
glutInitDisplayMode(GLUT_DOUBLE
or GLUT_RGB or GLUT_DEPTH);
Задаем размер окна OpenGL и позицию окна на экране.
Задаем размер окна OpenGL и позицию окна на экране.
glutInitWindowSize(AppWidth,
AppHeight);
ScreenWidth
:= glutGet(GLUT_SCREEN_WIDTH);
ScreenHeight
:= glutGet(GLUT_SCREEN_HEIGHT);
glutInitWindowPosition((ScreenWidth
- AppWidth) div 2,
(ScreenHeight - AppHeight) div 2);
Создаем
окно с заголовком ogl_p1:
glutCreateWindow('ogl_p1');
Инициализация
сцены:
InitializeGL;
Регистрация
вызываемых процедур:
glutDisplayFunc(@DrawGLScene);
glutReshapeFunc(@ReSizeGLScene);
glutKeyboardFunc(@GLKeyboard);
Запуск
механизма обработки событий:
glutMainLoop;
На
рисунке 2 показан результат работы
программы.
Рисунок
2. Результат запуска приложения
Ниже показан весь код проекта:
program ogl_p1; uses gl, glut; var Cmd: array of PChar; CmdCount: Integer; ScreenWidth, ScreenHeight: Integer; const AppWidth = 400; AppHeight = 400; procedure DrawGLScene; cdecl; begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glBegin(GL_QUADS); glNormal3f( 0.0, 0.0, 1.0); glVertex3f( 0.5, 0.5, 0.5); glVertex3f(-0.5, 0.5, 0.5); glVertex3f(-0.5,-0.5, 0.5); glVertex3f( 0.5,-0.5, 0.5); glNormal3f( 0.0, 0.0,-1.0); glVertex3f(-0.5,-0.5,-0.5); glVertex3f(-0.5, 0.5,-0.5); glVertex3f( 0.5, 0.5,-0.5); glVertex3f( 0.5,-0.5,-0.5); glNormal3f( 0.0, 1.0, 0.0); glVertex3f( 0.5, 0.5, 0.5); glVertex3f( 0.5, 0.5,-0.5); glVertex3f(-0.5, 0.5,-0.5); glVertex3f(-0.5, 0.5, 0.5); glNormal3f( 0.0,-1.0, 0.0); glVertex3f(-0.5,-0.5,-0.5); glVertex3f( 0.5,-0.5,-0.5); glVertex3f( 0.5,-0.5, 0.5); glVertex3f(-0.5,-0.5, 0.5); glNormal3f( 1.0, 0.0, 0.0); glVertex3f( 0.5, 0.5, 0.5); glVertex3f( 0.5,-0.5, 0.5); glVertex3f( 0.5,-0.5,-0.5); glVertex3f( 0.5, 0.5,-0.5); glNormal3f(-1.0, 0.0, 0.0); glVertex3f(-0.5,-0.5,-0.5); glVertex3f(-0.5,-0.5, 0.5); glVertex3f(-0.5, 0.5, 0.5); glVertex3f(-0.5, 0.5,-0.5); glEnd(); glutSwapBuffers; end; procedure ReSizeGLScene(Width, Height: Integer); cdecl; begin glViewport(0, 0, Width, Height); end; procedure GLKeyboard(Key: Byte; X, Y: Longint); cdecl; begin if Key = 27 then Halt(0); end; procedure InitializeGL; begin glMatrixMode(GL_PROJECTION); glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0, 0.0, -2.0); glRotatef(30.0, 1.0, 0.0, 0.0); glRotatef(30.0, 0.0, 1.0, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); end; begin CmdCount := 1; SetLength(Cmd, CmdCount); Cmd[CmdCount-1] := PChar(ParamStr(CmdCount-1)); glutInit(@CmdCount, @Cmd);
glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
glutInitWindowSize(AppWidth, AppHeight); ScreenWidth := glutGet(GLUT_SCREEN_WIDTH); ScreenHeight := glutGet(GLUT_SCREEN_HEIGHT); glutInitWindowPosition((ScreenWidth - AppWidth) div 2, (ScreenHeight - AppHeight) div 2); glutCreateWindow('ogl_p1'); InitializeGL; glutDisplayFunc(@DrawGLScene); glutReshapeFunc(@ReSizeGLScene); glutKeyboardFunc(@GLKeyboard); glutMainLoop; end.
syntax highlighted by Code2HTML, v. 0.9.1
для инициации достаточно написать
ОтветитьУдалитьglutInit(@argc,argv); вместо glutInit(@CmdCount, @Cmd);
поэтому первые три строки в теле программы
(после Begin) не нужны
Спасибо за комментарий. Да, действительно, можно обойтись одной строчкой инициализации библиотеки GLUT.
Удалить