Главная » Free Pascal » Графические средства языка Free Pascal

0

В этой главе описывается набор процедур и функций, унаследованный языком Free Pascal от ранней графической библиотеки BGI (Borland Graphics Interface). Он практически повторяет набор графических подпрограмм, реализованных в систе- мах Turbo Pascal и Borland Pascal, с единственным расширением, позволяющим более полно использовать разрешение современных дисплеев. Дополнительной особенностью графики системы Free Pascal является выделение консольному при- ложению двух окон (рис. 15.1).

Рис. 15.1. Главное и графическое окна приложения

В главном окне реализуются обычные интерфейсные взаимодействия между пользователем и приложением (ввод/вывод по операторам read/readln, write/writeln, readkey, keypressed), в дополнительном окне выполняются по- строения графических фигур и отображение пояснительных подписей с помощью процедур BGI.

Основные характеристики графического окна
Система координат

Рабочее поле графического окна, расположенное под заголовком окна, снабже- но системой координат, начало которой находится в левом верхнем углу. При этом ось y направлена вниз, а ось x — вправо. В качестве единиц измерения приня- ты пикселы экрана. Если традиционные дисплеи поддерживали довольно много режимов разрешения, при которых размер пикселов мог меняться в достаточно широком диапазоне, то современные плоские мониторы (плазменные и жидкокри- сталлические) обычно поддерживают один-два варианта разрешения. Как правило, основной рабочий режим современного монитора устанавливается под управлени- ем операционной системы и выбирается из соображений максимальной четкости изображений. Поэтому то, что раньше подразумевалось под разрешением экрана и было связано с изменением геометрических размеров пиксела, сегодня свелось к изменению размеров графического окна при сохранении физического размера пик- села. Таким образом, среди основных характеристик графического окна присутст- вуют два параметра, задающие ширину (MaxX) и высоту (MaxY) рабочего поля в пик- селах. Используя стандартные средства управления размерами окна, вы можете во время работы приложения изменить местоположение и габариты графического эк- рана, но параметры MaxX и MaxY, установленные при создании графического окна, при этом сохраняют свои первоначальные значения.

Графический курсор

Ряд графических процедур наряду с абсолютными координатами использует и относительные координаты, которые задаются в виде смещений (dx, dy) относи- тельно позиции текущей точки CP (от англ. Current Point). При создании графиче- ского окна текущая точка помещается в начало координат. Ее последующие пере- мещения зависят от выполняемых графических операций. Например, при построении отрезка прямой текущая точка переводится в конец отображаемого от- резка. При построении окружности положение текущей точки не изменяется. Те- кущую точку обычно называют графическим курсором, который в отличие от по- стоянно мигающего текстового курсора не изображается в графическом окне, чтобы не исказить выводимую картинку. Координаты текущей точки программа может опросить с помощью функций GetX и GetY.

Буфер графического окна

Все, что представлено на рабочем поле графического окна, является отображе- нием некоторого участка видеопамяти — буфера графического окна. Основным содержанием буфера являются коды цветности, в которые окрашен каждый пиксел рабочего поля. Для хранения кода цветности каждого пиксела в видеопамяти выде- ляется до 24 двоичных разрядов. В соответствии с этим изображение в графиче- ском окне может быть монохромным или цветным с более или менее насыщенной цветовой палитрой (16, 64, 256, 256 тыс. или 16 млн оттенков). Код цветности обычно представляет собой комбинацию интенсивностей трех базовых цветов — красного (R — Red), зеленого (G — Green) и синего (B — Blue).

В каждый конкретный момент графическая система имеет дело с двумя ранее установленными цветами — цветом рисования или цветом переднего плана (fore- ground color) и цветом фона или цветом заднего плана (background color). Цвету фона всегда соответствует нулевой программный код. На самом деле, это не ком- бинация цветов RGB, а номер специального регистра видеокарты, в котором нахо- дится настоящая комбинация базовых цветов. Так что цвет фона не всегда является только черным. Изменение содержимого указанного регистра производится с по- мощью процедуры SetBackgroundColor и сказывается только в тот момент време- ни, когда программа обращается к процедуре очистки графического экрана (Clear- Device).

В отличие от этого, изменение цвета переднего плана, осуществляемое с помо-

щью процедуры SetColor, в процедурах рисования сказывается мгновенно в мо- мент записи нового цвета пиксела в соответствующий участок видеопамяти. Ви- деокарта позволяет сформировать новый цвет пиксела с учетом его предыдущей окраски. Новый код цветности может заменить старый (простое вытеснение) или над обоими кодами может быть выполнена одна из логических операций — AND, OR или XOR. Обратите особое внимание на операцию исключающего "ИЛИ" (XOR), ко- торая используется для стирания или "проявления" изображений. Если на код цвета пиксела накладывается такой же двоичный код по операции XOR, то результат будет нулевым, что соответствует цвету фона или стиранию ранее окрашенной точки. Если на нулевой код цветности наложить прежний цвет пиксела, то точка на экране "проявится". Этой возможностью часто пользуются при анимации изображений.

Еще одна возможность быстрой смены изображений на экране обеспечивается наличием нескольких графических буферов. При достаточно большом объеме ви- деопамяти под хранение изображений может быть выделено две или более графи- ческих страниц (буферов). Одна из таких страниц объявляется видимой (Visual Page), и ее содержимое отображается в графическом окне, а другая — активной (Active Page). По умолчанию графическая страница с нулевым номером является одновременно и активной, и видимой. Поэтому результат действия процедур, вос- производящих тот или иной графический примитив, немедленно отображается на графическом экране. Мы можем объявить другую страницу активной:

SetActivePage(1);

После этой операции все графические процедуры будут заносить свои измене- ния в невидимое окно, а на экране по-прежнему будет отображаться содержимое нулевой страницы. Спустя некоторое время мы можем объявить первую страницу видимой:

SetVisualPage(1);

И тогда ее содержимое мгновенно покажется на графическом экране. Так как время записи в активную страницу совмещено со временем отображения видимой страницы, то их переключение приводит к практически мгновенной смене кадров.

Создание графического окна

Создание графического окна и переход в режим выполнения графических опе- раций напоминает подготовку к работе с файлами. В жаргоне программистов бы- тует термин "открыть графику", и это надо сделать прежде, чем вы обратитесь к любой графической процедуре. Выполняется эта операция с помощью процедуры InitGraph:

InitGraph(gd,gm,”);

Два первых ее аргумента — имена переменных типа SmallInt. Переменная gd символизирует номер, под которым система FP хранит одну из служебных про- грамм, реализующих операции обмена с графическим экраном. Программы такого рода принято называть графическими драйверами (graphics driver). Переменная gm предназначена для хранения числового кода, определяющего режим, который дол- жен поддерживать графический драйвер (graphics mode). Приведенные имена пе- ременных являются аббревиатурами соответствующих английских терминов (но вы можете использовать и любые другие имена). Третий аргумент процедуры In- itGraph, представленный пустой строкой, должен указывать путь к каталогу, в ко- тором находится драйвер. Отсутствие значения этого параметра говорит о том, что компилятор должен сам найти нужную программу.

Что касается значения переменной gd, то ее обычно задают равной нулю. Это означает, что система FP должна сама опросить параметры графического оборудо- вания компьютера и выбрать подходящие значения переменных gd и gm. В даль- нейшем программист этими переменными не пользуется, но и не должен затирать их значения.

Опытный программист, часто имеющий дело с графическими режимами, пе- ред открытием графики может сам задать нужные ему значения переменных gd, gm. Для их выбора можно прибегнуть к услугам табл. 15.1 и 15.2 или файлам по- мощи.

Таблица 15.1

Условное обозна- чение драйвера

Числовой код

Примечание

D1bit

11

Монохромный режим

D2bit

12

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

D4bit

13

Вспомогательный режим для IBM PC

D6bit

14

Для ПК Amiga (полутоновый режим, 64 цвета)

D8bit

15

Основной режим для IBM PC

D12bit

16

Для ПК Amiga (цветной режим, 4096 цветов)

D15bit

17

D16bit

18

D24bit

19

В версии 2.2.4 пока не поддерживается

D32bit

20

В версии 2.2.4 пока не поддерживается

D64bit

21

В версии 2.2.4 пока не поддерживается

Таблица 15.2

Условное обозна- чение режима

Числовой код

Примечание

detectMode

30000

Автоматическое определение режима

m320x200

30001

m320x256

30002

Для ПК Amiga (режим PAL)

m320x400

30003

Для ПК Amiga или Atari

m512x384

30004

Для ПК Macintosh

m640x200

30005

Для IBM PC (режимы EGA, VGA)

m640x256

30006

Для ПК Amiga (режим PAL)

m640x350

30007

Для IBM PC (режимы EGA, VGA)

m640x400

30008

Для IBM PC (режимы VGA, SVGA)

m640x480

30009

Для IBM PC (режимы VGA, SVGA)

m800x600

30010

Для IBM PC (режимы VGA, SVGA)

m832x624

30011

Для ПК Macintosh

Таблица 15.2 (окончание)

Условное обозна- чение режима

Числовой код

Примечание

m1024x768

30012

Для IBM PC (режимы SVGA)

m1280x1024

30013

Для IBM PC (режимы SVGA)

m1600x1200

30014

Для IBM PC (режимы SVGA)

m2048x1536

30015

Для IBM PC (режимы SVGA)

Выбор драйвера фактически означает выбор цветовой палитры, используемой при выполнении графических процедур. Для пользователей IBM PC авторы версии Free Pascal 2.2.4 пока ограничились 8-битной глубиной цвета. В этом режиме мож- но определить цветовую палитру, содержащую  256  оттенков,  выбранных  из 256 000 всевозможных цветовых комбинаций. Поддержка режима TrueColor (глу- бина цвета — 24 или 32 бита) еще не реализована.

Выбор графического режима фактически регламентирует размер рабочего поля графического окна приложения. В тех случаях, когда параметры процедуры Init- Graph принимают значения gd=0, gm=0 или gm=30000, размер графического окна совпадает с полным экраном. Габариты графического окна не могут превышать физическое разрешение монитора.

После обращения к процедуре InitGraph целесообразно удостовериться, что операция открытия графики прошла успешно. Оценить это можно по значению системной переменной GraphResult, которое должно быть нулевым (равным мне- монической константе GrOK):

var

gd,gm: SmallInt; err: Integer;

begin

InitGraph(gd,gm,”);

err:=GraphResult;           // опрос GraphResult

if err <> GrOK then begin   // анализ завершения операции writeln(‘Графика не открылась’);

halt(1);   // останов, если графика не открылась

end; end.

Несовместимая  комбинация  значений  gd и  gm,  как  правило,  приводит  к

Graphresult=-10, после чего выполнение графических операций невозможно.

Завершая работу с графической системой, программа должна "закрыть графи-

ку", обратившись к процедуре CloseGraph: var

gd,gm: SmallInt;

err:Integer;

begin

InitGraph(gd,gm,”); // инициализация графики (выделение ресурсов) circle(100,100,20); // построение окружности

readln;

closegraph;         // освобождение ресурсов

end.

В состав  группы  подпрограмм,  связанных  с  инициализацией  графики (табл. 15.3), входит 17 процедур и функций, к большинству из которых пользовате- лю приходится обращаться крайне редко. В некоторых случаях речь идет об уста- ревших характеристиках вроде aspect ratio (соотношение сторон). На мониторах типа EGA (Enhanced Graphics Adapter), которые сейчас можно увидеть только в музеях, пикселы экрана представляли прямоугольник, вытянутый по оси y. Поэто- му на них окружности рисовались как эллипсы, а квадраты как прямоугольники. Для восстановления правильных пропорций использовался поправочный коэффи- циент aspect ratio. На современных мониторах пиксел имеет форму квадрата, и не- обходимость во введении поправочных коэффициентов отпала. Абсолютно ника- кой информации для пользователя не несут ни имя драйвера, ни имя текущего графического процесса. За исключением очень продвинутых программистов нико- му не приходится добавлять новые драйверы и регистрировать их в системе FP.

Таблица 15.3

Имя подпрограммы

Назначение

ClearDevice

Очистка графического экрана

CloseGraph

Завершение работы в графическом режиме, передача управления главному "текстовому" окну

DetectGraph

Определение (опрос) графического режима

GetAspectRatio

Опрос коэффициентов aspect ratio

GetModeRange

Опрос допустимого диапазона графических режимов для текущего драйвера

GraphDefaults

Восстановление параметров графической системы по умолчанию

GetDriverName

Опрос имени графического драйвера

GetGraphMode

Опрос текущего или последнего использованного графического режима

GetMaxMode

Опрос максимального номера графического режима для текущего драйвера

GetModeName

Опрос имени текущего графического режима

Таблица 15.3 (окончание)

Имя подпрограммы

Назначение

GraphErrorMsg

Символьное сообщение, соответствующее ошибочному значению GraphResult

GraphResult

Признак завершения последней графической операции

InitGraph

Инициализация графических драйверов

InstallUserDriver

Установка нового графического драйвера

RegisterBGIDriver

Регистрация нового графического драйвера

RestoreCRTMode

Возврат в текстовый режим

SetGraphMode

Установка графического режима

К упомянутым ранее обязательным процедурам раздела инициализации доба- вим следующие — очистку графического экрана (ClearDevice), переключения ме- жду основным и графическим окнами (RestoreCRTMode и SetGraphMode). Для воз- врата в ранее установленный графический режим обращение к последней процедуре должно выглядеть следующим образом:

SetGraphMode(GetGraphMode);

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

writeln(GraphErrorMsg(GraphResult));

Помните, что первое же обращение к системной переменной GraphResult сбра- сывает ее в ноль. Если вы хотите использовать ее несколько раз, то предварительно нужно скопировать ее значение в промежуточную переменную:

err:=GraphResult;

if err<>GrOK then begin writeln(GraphErrormsg(err)); exit(1);

end;

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

По теме:

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