19.5.5. Управление палитрой

We use cookies. Read the Privacy and Cookie Policy

19.5.5.1. Палитра и ее анализ. Максимальный набор цветов, поддерживаемых одновременно BGI-драйвером, называется палитрой и может состоять из 16 цветов, пронумерованных от 0 до 15 (так будет, например, для графических адаптеров EGA, VGA). Эти шестнадцать цветов используются по умолчанию в режимах 640x480 для VGA, 640x350, 640x200 и 320x200 для EGA как в текстовом, так и в графическом режимах.

Стандартная палитра режима 320x200 адаптера GGA (палитра С0) состоит из всего лишь четырех цветов:

0 — черный;

1 — синий;

2 — малиновый;

3 — белый.

А для того же адаптера CGA в режиме CGAHi (640x200) и для Hercules палитра состоит только из двух цветов: черного (0) и белого (1).

Числа от 0 до 15, которые используются для обозначения цветов, определяют цветовые атрибуты или, как их еще называют, «программные» цвета. Каждому программному цвету присваивается «аппаратный» цвет из так называемой полной палитры. Например, для адаптера EGA, выводящего одновременно до 16 цветов, программные цвета выбираются из полной палитры в 64 цвета, имеющейся в этом адаптере. А в адаптере VGA аппаратная палитра содержит 256 цветов. Для адаптеров класса CGA полная палитра составляет 16 аппаратных цветов, но одновременно на экране могут появиться тишь максимум четыре цвета одной из четырех программных палитр (C0...C3). У адаптеров Hercules и РС3270 полная и программная палитры состоят из двух цветов.

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

Рассмотрим процедуры, с помощью которых можно получить системную информацию о ней. В модуле Graph определен тип для описания палитры:

- 444 -

CONST

MaxColors*15; { максимальный программный номер цвета }

TYPE

PaletteType=RECORD

Size : Byte; { размер программной палитры}

Colors: Array [0..MaxColors] of ShortInt;

END;

Поле Size содержит количество цветов в палитре, а поле Colors содержит действующие цвета в первых Size элементах массива. Процедуры GetPalette и GetDefaultPalette возвращают в фактических параметрах значение типа PaletteType:

GetDefaultPalette( VAR Palette : PaletteType );

GetPalette( VAR Palette : PaletteType )

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

GetPaletteSize : Word

возвращает результат типа Word, который показывает, какое количество цветов входит в текущую программную палитру. В принципе, эта функция возвращает значение, равное GetMaxColor+1.

19.5.5.2. Установка палитры. Для установки палитры в модуле Graph представлены три процедуры разной сложности. Процедура

SetPalette( ColorNum : Word; Color : ShortInt )

управляет только одним цветом в палитре. ColorNum — это номер программного цвета, Color — номер аппаратного цвета, который будет под ним пониматься. Например, вызов SetPalette( 0, Red ) делает красный цвет первым цветом палитры. Параметр Color может превышать максимальный программный номер цвета, но только на адаптерах EGA (0..63) и VGA. При некорректном вызове процедуры функция GraphResult вернет значение grError. Процедура

SetAllPalette( VAR Palette )

позволяет самостоятельно производить «перетасовку» всей палитры сразу и назначать соответствие между программными и аппаратными цветами. Параметр Palette является бестиповым, переменной длины. Первый его байт должен содержать количество цветов N в устанавливаемой палитре, следующие N байтов должны содержать цвета

- 445 -

из аппаратной палитры, которые будут использоваться в дальнейшем. Каждый из этих байтов может принимать значения от -1 до максимального аппаратного, причем диапазон чисел от 0 и выше представляет устанавливаемые цвета, а число -1 задается в том случае, если соответствующий цвет остается без изменений. Параметр Palette удобно представлять типом PaletteType, так как он имеет именно такую структуру. Пример смены палитры приведен на рис. 19.24.

(* ТОЛЬКО ДЛЯ АДАПТЕРОВ EGA ИЛИ VGA*)

USES Graph, CRT; { подключены Graph и CRT }

{$I initgraf.pas} { процедура инициализации }

VAR

palette : PaletteType; { переменная для палитры }

i, j, MaxC : Integer; { счетчики; максимальный цвет }

BEGIN

GrInit; { инициализация графики }

palette.size:=GetPaletteSlze; { размер текущей палитры }

MaxC := Pred(palette.size); { макс, программный цвет }

for i:=0 to MaxC do

{ Рисование вложенных разно- }

begin { цветных прямоугольников }

SetFillStyle( SolidFill, i );

Bar(i*10, i*10, GetMaxX-i*10, GetMaxY-i*10)

end;

for i:=0 to 63-MaxC do

{ цикл по аппаратным цветам }

begin

{ Сдвиг программных цветов относительно аппаратных: }

for j:=0 to MaxC do

palette.colors[j] := j + i ;

SetAllPalette(palette); { назначение новой палитры }

Delay( 100 ) { пауза в 100 мс }

end;

ReadLn; { пауза до нажатия ввода }

GetDefaultPalette(palette); { берется исходная палитра }

SetAllPalette(palette); {и восстанавливается }

CloseGraph { закрытие графики }

END.

Рис. 19.24

Заменяя палитры, можно «оживлять» изображения на экране при условии, что все его «кадры» находятся в поле экрана и не пересекают друг друга. Допустим, есть 15 кадров. Тогда назначается палитра со всеми цветами, равными фоновому. Далее рисуются все 15 кадров, причем первый кадр выводится первым цветом програм-

- 446 -

мной палитры, второй — вторым и т.д. После вывода 15-го кадра цветом номер 15 все кадры на экране будут «невидимы». Теперь достаточно с нужной задержкой устанавливать один из цветов палитры видимым, и мгновенно будет «проявляться» очередной кадр.

Для удобства работы со стандартными цветами адаптера EGA в модуле Graph введены 16 констант со значениями аппаратных цветов, соответствующими стартовой программной палитре:

CONST

EGABlack = 0; EGABlue = 1; EGAGreen = 2;

EGACyan = 3; EGARed = 4; EGAMagenta = 5;

EGABrown = 20; EGALightgray = 7; EGADarkgray = 56;

EGALightblue = 57; EGALightgreen = 58; EGALightcyan = 59;

EGALightred = 60; EGALightmagenta = 61; EGAYellow = 62;

EGAWhite= 63;

Более сложная процедура

SetRGBPalette( ColorNum,

RedValue, GreenValue, BlueValue : Integer )

позволяет манипулировать цветовыми сочетаниями развитых графических адаптеров VGA и IBM8514. Параметр программного цвета ColorNum должен быть в диапазоне 0..15 для VGA и 0..255 для IBM8514. Последние три параметра показывают смешение красного, зеленого и синего цветов. Хотя они объявлены как Integer, BGI-драйвером воспринимается в них только младший байт, в котором, в свою очередь, значащими являются только шесть битов, с 0-го по 5-й (т.е. значения в диапазоне 0..63). Это сделано для совместимости со стандартом EGA.

На практике применение этой процедуры проблематично из-за сложности представления «аппаратных» цветов. Кроме того, не на всех модификациях адаптера VGA процедура работает одинаково. Для переносимости программ мы не рекомендуем пользоваться этой процедурой.

19.5.5.3. Низкоуровневое управление палитрой EGA/VGA. В графическом режиме нет проблем поменять палитру (если, конечно, в ПЭВМ стоит плата EGA, VGA или IBM8514). Но это невозможно сделать в текстовом режиме, поскольку рассмотренные выше процедуры работают только после инициализации графики. Можно напрямую изменять программную палитру, даже в текстовом режиме, используя функцию 10H прерывания 10H. Надо только правильно закодировать аппаратный цвет. Структура байта, представляющего собой один аппаратный цвет (составляемый смешением компонентов), показана на рис. 19.25.

- 447 -

-- Бит → Компонент цвета

0 -- B → синий, интенсивность 2/3

1 -- G → зелёный, интенсивность 2/3

2 -- R → красный, интенсивность 2/3

3 -- b → синий, интенсивность 1/3

4 -- g → зелёный, интенсивность 1/3

5 -- r → красный, интенсивность 1/3

6 -- не используется

7 -- не используется

Рис. 19.25

Как видно, для каждого чистого цвета R, G и В имеется возможность получить три градации яркости: 1/3 интенсивности, 2/3 интенсивности и 1/3+2/3=1 интенсивности. Кроме того, возможны различные комбинации битов в регистрах. Возможное количество цветов равно двум в степени шесть (это 64 — от 0 до 63).

Как заменить программный цвет номер ColorNum на аппаратный RGBrgb, построенный по схеме рис. 19.25, показано на рис. 19.26. Для вызова прерывания требуется подключение модуля DOS.

| USES DOS; { необходим модуль DOS }

| PROCEDURE SetPalColor( ColorNum, RGBrgb : ShortInt );

| VAR

| Regs : Registers; { нужна для вызова DOS.Intr() }

| BEGIN

| with Regs do begin

| { действия с полями Regs }

| AX := $1000; { AL=$00, AH=$10 }

| BL := ColorNum; { номер изменяемого цвета }

| BH := RGBrgb { присваиваемое ему значение }

| end; {with}

| Intr( $10, Regs ) { прерывание 10H - сервис EGA }

| END;

Рис. 19.26

- 448 -