Главная » Free Pascal » Отображение простейшего двумерного изображения OpenGL Free Pascal

0

В 1915 г. известный русский художник-авангардист Казимир Малевич предста- вил на выставке небольшое полотно (размером примерно 80  80  см),  бóльшую часть которого занимал черный квадрат. Тогда картина вызвала очень противоре- чивые отклики критиков. Да и в наше время можно многое услышать в адрес авто- ра от лиц как превозносящих Малевича до небес, так и считающих его не вполне здоровым. Так или иначе, но в 2002 г. один из оригиналов был куплен известным российским предпринимателем В. Потаниным за миллион долларов и передан им на хранение в Эрмитаж. На рис. 16.2 приведено изображение этой картины, кото- рое мы обнаружили в Интернете.

Рис. 16.2. Черный квадрат К. Малевича

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

   Листинг 1 6 .2 .  Отображение  черного  квадрата                                                                             

program Malevich; uses

GL,GLUT;

//———————————————————-

procedure OnRedraw; cdecl;       // процедура перерисовки сцены begin

glClear(GL_COLOR_BUFFER_BIT);  // очистка графического экрана glBegin(GL_QUADS);            // заголовок примитива "квадрат"

glColor3f(0.8, 0.75, 0.75);  // установка цвета холста

glVertex2f(-1, -1);     // 1-я вершина квадрата холста glVertex2f(-1, 1);     // 2-я вершина квадрата холста glVertex2f( 1, 1);     // 3-я вершина квадрата холста glVertex2f( 1, -1);     // 4-я вершина квадрата холста glColor3f(0.1,0.1,0.1); // установка цвета квадрата glVertex2f(-0.9, -0.9); // 1-я вершина квадрата glVertex2f(-0.9, 0.9); // 2-я вершина квадрата glVertex2f( 0.9, 0.9); // 3-я вершина квадрата glVertex2f( 0.9, -0.9); // 4-я вершина квадрата

glEnd;                   // конец описания примитива

glFlush;                 // отображение содержимого буфера end;

//——————————————————————-

procedure OnResize(w,h:Longint); cdecl; // если меняются размеры begin

glViewport(0, 0, w, h);       // изменение точки зрения

glLoadIdentity;              // сброс текущей матрицы if w>h then glScalef(h/w,1,1) // масштабирование по x else glScalef(1,w/h,1);       // масштабирование по y

end;

//—————————————————————–

begin

glutInit(@argc,argv);       // инициализация Glut glutCreateWindow(‘OpenGL: Malevich’); // создание окна glutDisplayFunc(@OnRedraw); // регистрация функции перерисовки glutReshapeFunc(@OnResize); // регистрация функции изменения w, h glMatrixMode(GL_MODELVIEW); // выбор текущей матрицы glClearColor(1,1,1,1);      // цвет для очистки экрана glutMainLoop;              // старт главного цикла GLUT

end.

Начнем комментировать программу с ее головной части. Во-первых, инициали- зация GLUT сделана самым экономным способом. Во-вторых, мы не собираемся устанавливать размеры и позицию графического окна, полагаясь на выбор пакета GLUT и операционной системы. К сожалению, при создании графического окна мы не можем использовать в его заголовке русские буквы. Затем мы сообщаем ад- реса обработчиков двух событий — программы перерисовки изображения на поле клиента (OnRedraw) и программы реакции на изменение размеров графического ок- на (OnResize). Следующая строка устанавливает в качестве текущей матрицу моде- ли изображения. Далее устанавливается белый цвет, который будет использоваться для очистки области клиента в графическом окне. Последняя строка запускает главный цикл утилит GLUT.

В начале этого цикла первой вызывается процедура OnResize. Это определяется порядком обработки событий, предусмотренным в Windows. По полученным габа- ритам создаваемого окна (параметры w и h) устанавливаются правильные размеры поля зрения. Затем происходит загрузка начального состояния в текущую матрицу аффинных преобразований и коррекция текущей матрицы, если ширина и высота оказываются разными.

После фактического создания окна запускается процедура перерисовки, в кото- рой область рисования чистится установленным цветом. Затем на ней формируется изображение двух квадратов разного цвета. Если бы не было обращения к процедуре glFlush, то в области клиента изображение квадратов не появилось бы.

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

Еще одно обстоятельство, на которое надо обратить внимание. Пакет GLUT был ориентирован на язык программирования С, поэтому в заголовках процедур обработки событий, которые должны вызываться функциями С, стоит указание cdecl. Это означает, что наши процедуры будут настроены на нужный порядок следования параметров, отличный от стандарта языка Паскаль, и по окончанию своей работы выполнят процедуры очистки стека в соответствии с правилами язы- ка С.

Таким образом, наша программа, насчитывающая примерно три десятка строк, мгновенно выполняет работу, над которой Казимир Малевич корпел несколько ме- сяцев (результат работы программы приведен на рис. 16.3).

Рис. 16.3. Электронная подделка под Малевича

Объем приведенной выше версии программы malevich.pas можно сократить еще на 8 строк, если вместо вызова процедур построения графических примитивов воспользоваться более удобной подпрограммой glRectf, отображающей прямо- угольник по координатам его противоположных вершин (листинг 16.3).

   Листинг 1 6 .3 .  Оптимизирова нное  о тобра ж е ние  ч е рного  к вад ра та                                          

program malevich_1; uses

GL,GLUT;

//—————————————————-

procedure OnRedraw; cdecl; begin

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(0.8,0.75,0.75);

glRectf(-1,-1,1,1);

glColor3f(0.1,0.1,0.1);

glRectf(-0.9,-0.9,0.9,0.9);

glFlush; end;

//—————————————————–

procedure OnReSize(W,H:integer); cdecl; begin

glViewport(0, 0, W, H); glLoadIdentity;

if W>H then glScalef(H/W,1,1) else glScalef(1,W/H,1); end;

//—————————————————–

begin

glutInit(@argc,argv); glutCreateWindow(‘OpenGL: Malevich’); glutDisplayFunc(@OnRedraw); glutReshapeFunc(@OnReSize); glMatrixMode(GL_MODELVIEW); glClearColor(1,1,1,1);

glutMainLoop; end.

Таким образом, на отображение классического полотна нам понадобилось все- го порядка 20 строк программы (не считая операторных скобок begin-end). При этом соответствующее графическое окно выполнено по всем правилам Windows. Оно сохраняет форму и пропорции изображения при изменении размеров окна, его свертывании в значок и распахивании до прежних размеров.

Источник: Кетков, Ю. Л., Свободное программное обеспечение. FREE PASCAL для студентов и школьников, Ю. Л. Кетков, А. Ю. Кетков. — СПб.: БХВ-Петербург, 2011. — 384 с.: ил. + CD-ROM — (ИиИКТ)

По теме:

  • Комментарии