Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 13
На сайте нет зарегистрированных пользователей

Пользователей: 13,370
новичок: dogoco6
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование интернет магазина (Apache, Php, Html) на GPSS + Блок схема
Движение шарика в эллиптическои параболоиде на Delphi [OpenGL] + Блок схемы
Моделирование работы ЭВМ на GPSS + Пояснительная записка

Палитра VGA: управление цветом
Сергей Андрианов
21.11.2001


В прошлый раз (см. статью ) нам так и не удалось добиться для спрайта правильных цветов. Восполним этот пробел, а заодно познакомимся с новыми возможностями, предоставляемыми палитрой. Чтобы в дальнейшем не путаться в терминах, давайте договоримся, что цветом будем называть зрительное ощущение от какого-либо оттенка, а цветовыми составляющими — компоненты (в виде чисел) трех основных цветов, на которые разлагается цвет: красный, зеленый и синий. Номером цвета назовем число, хранящее в видеопамяти информацию о цвете точки (или индекс в массиве палитры, что то же самое).

Что же такое палитра?

Во времена монохромных дисплеев понятия «палитра» не существовало, и цветов было только два: черный (цвет пустого экрана) и зеленый, желтый или белый, как повезет. Имелись даже дисплеи с оранжевым свечением. Кодировался цвет очень просто — одним разрядом: 0 — темная точка, 1 — светлая. Но скоро выяснилось, что этого явно недостаточно, и в монохромном режиме добавилось управление яркостью, т. е. второй разряд. И эти два разряда обеспечивали три или четыре уровня яркости (зачастую разряд яркости не влиял на черный цвет).

С созданием цветных дисплеев картина радикально изменилась, стало отображаться гораздо больше цветов. В первом массовом цветном видеоадаптере CGA для персональных компьютеров можно было использовать до 16 цветов в текстовом режиме и до четырех в графическом, что обусловлено ограничением объема видеопамяти (всего 16 Кбайт). При 4 тыс. знакомест текстового режима этого объема хватало с избытком, а вот при 64 тыс. точек графического (разрешение 320x200 точек) для кодирования цвета каждой точки нельзя было отвести больше двух разрядов.

Достаточно просто формировались 16 цветов CGA: по одному разряду на красную, зеленую и синюю составляющую и еще один разряд для повышенной яркости. Сразу возникает вопрос: если точка может быть только одного из четырех цветов, то какие цвета следует выбрать? Для этого в CGA предусмотрено два набора взаимно контрастных цветов: в один набор входят черный, голубой, малиновый и белый, в другой — черный, зеленый, желтый и красный. Значит, появились две фиксированные палитры. Иными словами, палитра позволяет одновременно использовать только несколько цветов из гораздо большего числа доступных. Таким образом, благодаря палитре снижаются до разумных пределов требования к объему видеопамяти. Она устанавливается для всего экрана, следовательно, нельзя сделать одну его часть бело-малиновой, а другую — красно-желтой.

В видеоадаптере EGA, сменившем CGA, яркость каждой цветовой составляющей можно было устанавливать независимо, т. е. на цветовую составляющую приходилось по два разряда (четыре градации яркости). Всего было доступно 64 цвета, но на экране одновременно появлялось не больше 16 в графическом режиме. Кроме того, увеличилось число палитр CGA до 6416 (в десятичной записи — 79228162514264337593543950336): каждый из 16 номеров цвета можно было выбирать из 64 доступных. Поэтому от номеров палитры отказались, а для ее определения стали использовать массив, где указывались составляющие трех основных цветов для каждого из номеров цвета. В текстовом режиме также появилась возможность изменить цвет, соответствующий определенному номеру.

Последний стандарт видеоадаптера VGA существенно расширил диапазон допустимых цветов. Теперь на любой номер цвета выделяется по три шестиразрядных регистра, по одному на цветовую составляющую. Каждый компонент мог выводиться в 64 градациях яркости, а общее число отображаемых цветов достигло 262 144. Конечно, глупо было бы ограничиться лишь 16 цветами, и потому применили режим с глубиной цвета 8 разрядов на точку, вследствие чего число цветов возросло до 256. Нетрудно подсчитать, что это потребовало разместить внутри видеоадаптера 768 регистров для хранения компонентов цвета.

Формат массива, пригодного для занесения составляющих цвета в регистры палитры VGA, существенно отличается от формата палитры Bmp-файла. Во-первых, тем, что порядок цветов в этом массиве иной: красный, зеленый, синий. Во-вторых, у него нет резервного байта, так что длина массива составляет всего 768 байт, в то время как в файле Bmp было 1024 байт (см. «Формат Bmp-файла», листинг 1). В-третьих, в регистрах используются только младшие шесть разрядов, которые соответствуют старшим шести разрядам в байте палитры BMP. Поэтому байты, считанные из Bmp-файла перед тем, как они будут помещены в регистры палитры, надо сдвинуть на два разряда вправо. Это соответствует делению на четыре, что и нужно для того, чтобы ввести диапазон значений 0—255 в диапазон 0—63.

Появление 240 дополнительных цветов наряду с 16 прежними вывело компьютерную графику и игровую индустрию на качественно новый уровень. Если раньше мало кто задумывался о целесообразности переопределения стандартной палитры, потому что «лишних» цветов, которые можно было бы заменить другими, не было, то теперь для этого открылись широкие возможности.

Как работает палитра?

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

При работе в 256-цветном режиме нужно помнить, что все рисунки, выводимые на экран одновременно, должны иметь одинаковую палитру. Но здесь встречаются исключения, которые можно использовать, например, в игре. Для персонажей и основных элементов интерфейса выбирается одна часть палитры, для фона или ландшафта — другая. Тогда на протяжении всей игры палитра может изменяться. В любом случае нужны процедуры, позволяющие варьировать как целиком палитру, так и отдельные ее части. Модуль, реализующий эти возможности, приведен в листинге 1.

Функции SetPal и GetPal помогают задать новую палитру и прочитать установленную, применяя стандартное прерывание BIOS. Им нужны такие параметры, как первый байт массива с данными о палитре, номер первого из заданных цветов и число тех цветов, которые требуется изменить. Первые три байта массива соответствуют красной, зеленой и синей цветовым составляющим первого из изменяемых цветов, следующие три — второго и т.д. Номера цветов начинаются с 0, так что для изменения палитры целиком в качестве первого цвета следует задать 0, а число цветов указать равным 256.

Функции FadeIn и FadeOut обеспечивают плавное гашение экрана и столь же плавное «проявление» изображения из темноты.

Кроме того, модуль содержит процедуры ожидания обратного хода вертикальной развертки WaitVerticalRetrace и мгновенного гашения экрана палитрой BlackPal. Последнюю процедуру целесообразно вызывать сразу после установки видеорежима и до заполнения видеопамяти, если затем предполагается применить FadeIn. Все процедуры модуля работают как в текстовом, так и в графическом режиме, но следует помнить, что при смене видеорежима устанавливается палитра по умолчанию.

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

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

В основном цикле, где и формируется картинка вместе со спрайтами, процедура WaitVerticalRetrace ожидает обратного хода развертки. Ведь коль скоро она включена в модуль Pal, некрасиво было бы, если бы происходило иначе.

Заканчивается программа плавным гашением экрана. Конечно, можно было бы при возвращении в текстовый режим снова плавно изменить яркость, но вряд ли это будет замечено — после смены видеорежима экран пуст.

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

листинг 1
unit pal; {работа с 256-цветной палитрой}
interface

procedure SetPal(var pal:byte;nbegpal,lenpal:integer);
{установка 256-цветной палитры}
procedure GetPal(var pal:byte;nbegpal,lenpal:integer);
{чтение 256-цветной палитры}
procedure WaitVerticalRetrace;
{ожидание вертикально обратного хода луча}
procedure BlackPal; {установка <черной> палитры}
procedure FadeOut(p:array of byte);
{плавное гашение палитры}
procedure FadeIn(p:array of byte);
{плавная установка палитры}
implementation
uses dos;

{установка 256-цветной палитры}
procedure SetPal(var pal:byte;nbegpal,lenpal:integer);
var r:registers;
begin
r.ax := $1012;
r.bx := nbegpal;
r.cx := lenpal;
r.dx := ofs(pal);
r.es := seg(pal);
intr($10,r);
end;

{чтение 256-цветной палитры}
procedure GetPal(var pal:byte;nbegpal,lenpal:integer);
var r:registers;
begin
r.ax := $1017;
r.bx := nbegpal;
r.cx := lenpal;
r.dx := ofs(pal);
r.es := seg(pal);
intr($10,r);
end;

{ожидание вертикально обратного хода луча}
procedure WaitVerticalRetrace;
begin
while (port[$3da] and 8) = 0 do;
end;

{установка <черной> палитры}
procedure BlackPal;
var p : array[0..767]of byte;
begin
fillchar(p,sizeof(p),0);
SetPal(p[0],0,256);
end;

{плавная установка палитры}
procedure FadeIn(p:array of byte);
var
p1 : array[0..767]of byte;
i,j : integer;
begin
BlackPal;
for i := 0 to 63 do begin
for j := 0 to 767 do {<поднимаем> цвета до }
p1[j] := round(p[j]/63*i);{ нужной палитры }
WaitVerticalRetrace;
SetPal(p1[0],0,256);
end;
end;

{плавное гашение палитры}
procedure FadeOut(p:array of byte);
var
p1 : array[0..767]of byte;
i,j : integer;
begin
for i := 0 to 767 do
p1[i] := p[i];
for i := 63 downto 0 do begin
for j := 0 to 767 do {<опускаем> цвета}
p1[j] := round(p[j]/63*i); { до 0 }
WaitVerticalRetrace;
SetPal(p1[0],0,256);
end;
end;

end.




листинг 2

begin
GetPal(p[0],0,256);
FadeOut(p);
CreateSprite('sprt01.bmp',0,0,1,1);
r.ax := $13; { устанавливаем режим }
intr($10,r); { 320х200х256 цветов }
scr := ptr(SegA000,0);
BlackPal;
PutBackGround; {рисуем фон}
FadeIn(p);
GetBuffer; {сохраняем фон под спрайтом}
PutSprite; {и рисуем на его месте спрайт}
repeat {теперь спрайт будет двигаться по экрану}
{до тех пор, пока мы не нажмем на клавишу}
PutBuffer; {восстанавливаем фон}
CalcSpritePosition;
GetBuffer; {сохраняем фон}
PutSprite; {рисуем спрайт}
WaitVerticalRetrace;
{ожидаем обратный ход луча кадровой развертки}
until keypressed;
readkey; {чистим буфер клавиатуры}
FadeOut(p);
r.ax := $3;
intr($10,r); {возвращаемся в текстовый режим}
DestroySprite;
end.


Опубликовал Kest October 31 2008 20:17:18 · 0 Комментариев · 12510 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Encrypt Decrypt
Размещение элемен...
VksButton
Page Promoter 7.7...
MPTools
Длинный заголовок...
Аватары в комме...
Apollovcl61
Песочные часы
Карта сайта
AntiRus
PolyFlow
DCAVI
Szwavepanel
WinAmp
TmxOutlookBarPro
TelBook
ScrollCredit
База предприятий ...
C# в кратком изло...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97836
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14191
Borland Delphi ... 10291
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Отдых в Турции
УСТРОЙСТВА В GPSS
Игровой софт Волна...
3d Принтер
dll) поддерживает ...
Подтверждение реги...
Интервалы между сл...
Развлечения Starda...
Клуб вулкан — подк...
Случайные числа
Этап 6 - выделение...
Too many nested files
Как снизить затрат...
Добавление свойств...
Рекурсивные методы...
Хотя у WWI есть оф...
Кто-то уже собирал...
Конечная область п...
• Обеспечьте посто...
Вложения в электро...
Применение фреймов
Блок TERMINATE
ЛОГИЧЕСКИЕ КЛЮЧИ В...
Использование функ...
Работа с избранным...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?