
LRP2
.pdfкарты, то регистр будет маскировать определенные битовые плоскости таким образом, что будет воспроизведен требуемый цвет.
Приведенное выше обсуждение касалось одновременного вывода восьми точек. Ну а как вывести меньшее количество точек? В этом случае, конечно, необходимо сохранить существующие данные для некоторых точек, а чтобы это было возможно, текущее содержимое данного адреса сохраняется в регистрах задвижки. Затем используется регистр маски битов для маскирования тех точек, которые не должны изменяться. Если бит этого регистра сброшен в 0, то данные, получаемые от процессора для этого бита, игнорируются и вмес-
то них используются данные, хранящиеся в регистрах задвижки. Заполнение регистров-задвижек меняется при ненулевом значении регистра разрешения цвета( регистр 01H блока графического адаптера ) , разряды 0-3 которого разрешают заполнение байта выбранных битовых плоскостей значениями из соответствующих разрядов регистра цвета ( регистр 00H блока графического адаптера ). В этом случае значения данных процессора ( маски карты игнорируются).
3.2.4.2. Режим записи 1.
Режим записи 1 предназначен для специальных приложений. В этом режиме текущее содержимое регистра задвижки записывается по указанному адресу. Напоминаем, что регистры задвижки заполняются операцией чтения. Этот режим очень полезен для быстрого переноса данных при операциях сдвига экрана. Регистр маски битов и регистр маски карты не влияют на эту операцию. Не имеет значения также, какие данные посылает процессор - содержимое регистров задвижки записывается в память без изменений.
3.2.4.3. Режим записи 2.
Режим записи 2 представляет альтернативный способ установки отдельных точек. Процессор посылает данные, у которых имеют значение только 4 младших бита, рассматриваемые как цвет (индекс регистра палитры). Можно сказать, что эта цепочка битов вставляется поперек плоскостей. Цепочка дублируется на все восемь точек, относящихся к данному адресу, до тех пор, пока регистр маски битов не предохраняет определенные точки от изменения. Регистр мас-
ки карты активен, как и в режиме записи 0. Конечно, процессор должен послать полный байт, но только младшие 4 бита существенны.
3.2.4.4. Режим чтения 0.
Процессор осуществляет чтение данных (8 точек ) из регистра задвижки той плоскости, которая разрешена регистром выбора плос-
61
кости для чтения (разряды 0-2 регистра 04H блока графического контроллера).Для чтения цветов (кодов регистра палитры) всех 4 битовых плоскостей необходимо последовательно разрешить чтение и прочитать все плоскости по одному адресу.
3.2.4.5. Режим чтения 1.
В результате выполнения операции чтения в 1 будут установлены только те биты в байте,для которых цвет совпадает с цветом,заданным в битах 0-3 регистра сравнения цвета (регистр 02H блока графического адаптера ).
3.2.5. Программирование регистров.
Каждая из микросхем адаптера обладает адресным регистром и несколькими регистрами данных. Адресный регистр используется в качестве указателя на тот или иной регистр данных. Адресный регистр является регистром типа "только запись" в который процессор при помощи команды OUT может быть помещен индекс выбранного регистра данных.
Регистры данных каждой микросхемы адаптера доступны через соответствующий порт ввода/вывода. Доступ к различным регистрам данных осуществляется путем предварительного занесения в адресный регистр индекса требуемого регистра данных с последующей выдачей команды OUT со стороны процессора для занесения в него необходимого значения. Отличие имеют регистры контроллера атрибутов,где адресный регистр и регистр данных имеют один порт с адресом 3C0H.
Внутри контроллера адресация организована таким образом,
что каждый раз после записи в порт 3COH, производится переключение: адресный регистр -> регистр данных, соответствующий значению адресного регистра и наоборот. Для инициализации процесса переключения адресный регистр - регистр данных (вначале доступ к адресному регистру, а потом к регистру данных и т.д.) необходимо выполнить операцию чтения из порта с адресом 3BAH или 3DAH. После выполнения операции чтения, первый доступ к порту 3C0H будет обращением к адресному регистру контроллера атрибутов. После загрузки адресного регистра, следующая команда вывода в порт 3C0H приведет к записи требуемого значения в соответствующий регистр данных контроллера атрибутов. Выполнение этой команды снова делает адресный регистр доступным для записи и процесс может быть продолжен.
После записи данных в регистры контроллера атрибутов необходимо установить 5 бит адресного регистра контроллера в 1 ( разрешение вывода), т.е. послать в порт 3C0H значение 20H.
EGA поддерживает стандартные графические функции BIOS.Можно вывести точку с помощью функции CH прерывания 10H, так же как для
62
цветного дисплея или PCjr.При входе DX должен содержать номер строки, а CX -номер столбца, и то и другое отсчитывается от 0. Код цвета помещается в AL.Содержимое AX меняется при выполнении прерывания.
4.Порядок выполнения работы
4.1. Написать программу вывода на экран в графическом режиме, которая выполняет следующие действия:
4.1.1.Переводит видео систему в графический режим 10H с помощью прерывания 10.
4.1.2.Устанавливает заданный цвет фона путем программирования регистра 00H палитры.
4.1.3.Выводит 16 строк точек при различных значениях регистров адаптера. Начальный адрес i-й строки видеобуфера вычисляется в режиме 10H по выражению
adp=A000:0000+80*i
4.1.4.Повторяет вывод следующих 16 строк с теми же параметрами что и предыдущие, но с учетом сдвига данных в регистре вращения.
4.1.5.Повторяет вывод следующих 16 строк с |
теми |
же |
|
параметрами, но с учетом логической операции. |
|
|
|
4.1.6.Оставшуюся |
часть экрана после полученного |
изображения |
|
с помощью режима записи 1 заполняет байтом, номер строки |
и |
||
столбца в полученном |
выше изображении соответствует номеру |
студен- |
та в журнале.
4.1.7.В полученном изображении "потушить" цвет первой строки путем занесения кода фона в соответствующий регистр палитры.
4.1.8.Выполнить аппаратный горизонтальный сдвиг экрана путем изменения начального адреса.
4.1.9.Вернуться в текстовый режим.
4.2.Написать,отладить и сохранить для выполнения работ 16,17,18 процедуру put_pix чтения байта и вывода за одно обращение к памяти до 8 точек с заданными параметрами
put_pix(x,y,color,bit_m,log_op)
где:x,y -координаты байта видеопамяти
63
colorкод цвета bit_m-значение битовой маски
log_op-код логической операции с прочитанным значением, который задается в регистре вращения.
5.Особенности программирования.
5.1.На языке Турбо-Паскаль.
5.1.1.Для обращения к видеопамяти применяется предопределенный массив Mem . Например, для чтения байта по адресу A000:0000H используется выражение b:=Mem[$a000:$0000] (b переменная типа byte).
5.1.2.Для обращения к портам ПЭВМ применяются предопределенный массив Port. Например, для записи значения 3dH в порт 3c0H используется выражение Port[$3c0]:=$3d; для чтения из порта 3daH используется выражение data:=Port[$3da], где data - переменная типа byte.
5.2. На языке Турбо-Си.
5.2.1.Для обращения к видеопамяти используются дальние указатели,которые объявляются в программе следующим образом:
char far * uk;-для работы с байтами.
Для чтения байта по адресу A000H:FFF5H используется выражение uk=( char far * ) 0xA0000000;
b=* uk; где b-переменная типа char;
5.2.2. Для обращения к портам ПЭВМ применяются функции чтения и записи порта,которые хранятся в библиотеке < dos.h>. Библиотека подключается командой
#include < dos.h>
после чего, например, для записи значения 3dH в порт 3c0H используется выражение:
outportb(0x3c0,0x3d);
Для чтения из порта 3daH используется выражение: data=intportb(0x3da),где dataпеременная типа char;
6.Индивидуальное задание.
6.1.По 2 цифре номера по журналу выбрать параметры из табли-
цы 6.
64
Таблица 6 ╔══════════════════╦═══════════════════════════════════════╗
║ |
Параметры ║ |
Номер в журнале |
║ |
║ |
║ 0 1 2 3 4 5 6 7 8 9 ║ |
║══════════════════╬═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╣
║ Номер начальной |
║100│140│200│ 80│120│150│ 60│180│210│ |
40║ |
||||||||||
║ строки |
║ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
|
║ |
║ Цвет фона |
║ 1A│ 23│ 31│ 18│ 2B│ 35│ 13│ 2F│ 39│ |
1D║ |
||||||||||
║ Цвет 1-й строки |
║ A │ 1 │ B │ 3 │ C │ 5 │ 6 │ D │ 9 │ |
8 |
║ |
|||||||||
║ Приращение цвета |
║ 1 │ 2 │ 4 │ 5 │ 8 │ 7 │ 9 │ 6 │ 3 │ |
A ║ |
||||||||||
║ i-й строки |
║ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
|
║ |
║ Маска видимых |
║ 61│ 63│ 67│ 82│ 86│ 8E│ 72│ 76│ 7E│ |
E2║ |
||||||||||
║ точек |
║ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
│ |
|
║ |
║Сдвиг данных ║ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 1 │ 2 │ 3 ║
║Логическая ║AND│OR │XOR│AND│OR │XOR│AND│OR │XOR│AND║
║операция ║ │ │ │ │ │ │ │ │ │ ║ ╚══════════════════╩═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
7.Содержание отчета.
7.1.Тема лабораторной работы. 7.2.Цель работы.
7.3.Порядок выполнения. 7.4.Индивидуальное задание. 7.5.Текст программы. 7.6.Результаты работы программы. 7.7.Выводы.
Лабораторная работа N 16
ИЗОБРАЖЕНИЕ ЛИНИЙ, ЗАТУШЕВЫВАНИЕ
1. Цель работы Приобретение практических навыков создания рисунков.
2. Темы для предварительной проработки 2.1.Изображение точки в графическом режиме.
3.Описание работы.
Функции вычерчивания линий являются основными подпрограммами графики и используются для отображения линий в заданном цвете путем
65
задания ее начальных и конечных координат. В то время, как изображение вертикальных и горизонтальных линий не представляет особого труда, более трудной задачей является создание функций, которые рисуют линии вдоль диагоналей. Например, какие точки составляют линию, вычерчиваемую от точки с координатами 0,0 до точки с координа-
тами 80,120?
Один из подходов к разработке функций вычерчивания линий использует отношение между смещением по координатам X и Y. Чтобы показать этот подход в действии, проведем линию между точками с координатами 0,0 и 5,10. Смещение по X равно 5, а по Y - 10. Отношение равно 1/2. Оно будет использоваться при определении коэффициента зависимости, по которому должны меняться координаты X и Y при изображении линий. В данном случае это означает, что приращение координаты Х составляет половину величины изменения координаты Y. Начинающий программист часто использует этот метод при разработке функций вычерчивания линий. Хотя подход математически верен и прост для понимания, для его правильной работы и для того, чтобы избежать серьезных ошибок округления, необходимо использовать математические операции с числами с плавающей точкой. Это означает резкое снижение быстродействия,если в систему не будет включен математический сопроцессор. По этой причине этот метод используется довольно редко.
Наиболее общий метод изображения линий включает использование алгоритма Брезенхейма. Хотя основой в нем служит также отношение между расстояниями по координатам X и Y, в данном случае не требуется выполнять деление или вычисление чисел с плавающей точкой. Вместо этого, отношение между значениями координат Х и Y представляется косвенным образом через серии сложений и вычитаний. Основной идеей алгоритма Брезенхейма, является регистрация средних значений погрешностей между идеальным положением каждой точки и той позицией на экране дисплея, в которой она действительно отображается. Погрешность между идеальным и действительным положением точки возникает ввиду ограниченных возможностей технических средств. Фактически не существует дисплеев с бесконечно большой разрешающей способностью, и, следовательно, действительное положение каждой точки на линии требует наилучшей аппроксимации. В каждой итерации цикла вычерчивания линии вызываются две переменные xerr и yerr, которые увеличиваются в зависимости от изменения величин координат Х и Y соответственно. Когда значение погрешности достигает определенного значения, оно вновь устанавливается в исходное положение, а соответствующий счетчик координат увеличивается. Этот процесс продолжается до тех пор, пока линия не будет полностью вычерчена. Функция
66
line_m(), приведенная ниже, реализует этот метод. Вы должны изучать ее до тех пор, пока не поймете механизма выполнения всех ее операций. Заметим, что в ней используется функция put_pix() с с заданными координатами x,y и цветом color для отображения точки на экране терминала.
┌──────────────────┐ │ line_m │ └────────┬─────────┘ ┌────────┴─────────┐
│ x_err = |
0 |
│ |
│ y_err = |
0 |
│ |
│ D_x = EX - BX |
│ |
|
│ D_y = EY - BY |
│ |
└────────┬─────────┘
┌────────┴─────────┐
│inc_x = sign(D_x)│
│inc_y = sign(D_y)│ └────────┬─────────┘ ┌────────┴─────────┐
│ D_x = abs(D_x) |
│ |
│ D_y = abs(D_y) |
│ |
└────────┬─────────┘ |
да |
|
|
нет |
|
┌──── |
|
D_x > D_y |
─────┐ |
|
┌────────┴───────┐ |
|
┌────────┴────────┐ |
||
│ dist = D_x |
│ |
|
│ dist = D_y |
│ |
└────────┬───────┘ |
|
└────────┬────────┘ |
└────────────┬──────────────┘ |
|
|
||
|
────────┴──────── |
|
|
|
┌─────────────> |
t = 0..dist |
─────────────────────┐ |
|
|
│ |
────────┬──────── |
|
│ |
|
│ |
╓───────┴────────╖ |
┌──────┴───────┐ |
||
│ |
║put_pix(BX,BY,c)║ |
│ |
return |
│ |
│ |
╙───────┬────────╜ |
└──────────────┘ |
||
│ |
┌───────┴────────┐ |
|
|
|
│ |
│x_err= x_err+D_x│ |
|
|
|
│ |
│y_err= y_err+D_y│ |
|
|
|
│ |
└───────┬────────┘ |
|
|
|
|
67 |
|
|
|
|
|
да |
|
│ |
x_err > dist |
──────────────────┐ |
|
│ |
|
┌──────────┴────────────┐ |
|
│ |
|
│ x_err = x_err - dist |
│ |
│ |
│ |
│ BX = BX + inc_x |
│ |
│ |
│ |
└──────────┬────────────┘ |
|
│ |
├<─────────────────────────┘ |
|
|
│ |
|
|
|
│ |
|
да |
|
│ |
y_err > dist |
──────────────────┐ |
|
│ |
|
┌──────────┴────────────┐ |
|
│ |
|
│ y_err = y_err - dist |
│ |
│ |
│ |
│ BY = BY + inc_y |
│ |
│ |
│ |
└──────────┬────────────┘ |
|
│ |
├<─────────────────────────┘ |
|
|
│ |
│ |
|
|
└─────────────────────────┘
рис.16
В данном алгоритме приняты следующие обозначения: BX,BYкоординаты начальной точки.
EX,EYкоординаты конечной точки.
D_X,D_Yмаксимальное расстояние на соответствующей координате. с- цвет выводной точки.
incx,incy-направление движения по соответствующей координате.
Как видно из алгоритма,при движении по большей координате (dist) приращение по этой координате и изображение точки выполняется всегда, в то время как по другой координате только при выполне-
нии условия -err>=dist.
Если у вас есть функции вычерчивания линий, то не составит особого труда создать функции вычерчивания прямоугольников. Пример, приведенный здесь, вычерчивает прямоугольники в заданном цвете путем создания координат двух противоположных углов.
/* вычерчивание прямоугольника */
void box(startx,starty,endx,endy,color_code) int startx,starty,endx,endy,color_code;
68
{
line(startx,starty,endx,starty,color_code); line(startx,starty,startx,endy,color_code); line(startx,endy,endx,endy,color_code); line(endx,starty,endx,endy,color_code);
}
Для того, чтобы закрасить прямоугольник, требуется выполнить запись в каждую точку растра внутри прямоугольника.При этом необходимо в цикле рисовать заданным цветом ряд горизонтальных линий,смещенных на единицу по координате y.
Тщательное продумывание позволяет исключить излишнюю медлительность, свойственную многим программам заполнения областей для графического экрана. Когда заполнение основано на простых вычислениях, которые действуют по очереди для каждой точки, требуется расходующие много времени битовые операции. Более экономичный код может определять, все ли битовые позиции определенного байта видеобуфера должны иметь один и тот же цвет, и когда это условие выполняется, этому байту присваивается заранее заготовленное значение, которое устанавливает все точки в правильный цвет. При этом нет необходимости повторять операции над одним и тем же байтом, каждый раз устанавливая биты только для одной из точек, информацию о которой содержит данный байт.
При заполнении прямоугольника линиями только первый и последний байт каждой строки может быть неполным ( если BX или EX не кратен 8). При затушевывании горизонтальными линиями нет смысла использовать процедуру line_m(), реализующую алгоритм Брезенхейма, необходимо просто определять адрес байта в видеопамяти,который соответствует в данный момент 8 выводимым точкам с начальными координатами x и y, причем x кратен 8.
adr=A000:0000H + X/8 +Y*80;
В работе N 9 объяснено, как создать описание символа в виде матрицы 8*8 точек, имеющего требуемый вам вид. Хотя такие символы могут выводиться только в стандартные символьные позиции, их использование может существенно облегчить заполнение графиков. Образец, высвечивающий все 8*8 точек можно вывести в интервале несколько строк и столбцов, заполняя область намного быстрее, чем это достигается при поточечной зарисовке.
При затушевывании прямоугольника в центральной части желательно использовать символы псевдографики с кодами ASCII 219,220,221,222, 223,которые заполняют все, знакоместо (219), ниж-
69
нюю половину (220), левую(221), правую (222) и верхнюю (223). При изображении прямоугольника тоже нет смысла применять алгоритм Брезенхейма, так как он состоит из горизонтальных и вертикальных отрезков.Изображение горизонтальных отрезков выполняется аналогично рассмотренному выше способу затушевывания горизонтальными линиями, а изображение вертикальных отрезков сводится к выводу в цикле одного байта с заданной частной (при текущей линии в 1 пиксель маска содержит одну 1 ) и приращение адреса на 80-переход на следующую строку. Модификация изображения наклонной линии.
При работе алгоритма Брезенхейма в случае D_X > D_Y в каждой строке выводится несколько точек.Если перед блоком 9 в алгоритме анализировать значение BX при неизменном BY и дописывать 1 в битовую маску. Тогда при использовании разработанной в лабораторной работе, процедура вывода байта с заданной маской обращение к ней выполняется только в случае кратности 8 значения BX (переход на следующий адрес видеопамяти ) или изменения BY ( переход на следующую строку ). В случае если D_Y > D_X и толщина линии составляет 2, 3, и т.д. пикселя за одно обращение к put_pix() можно выводить соответствующее число точек ( если они относятся к одному адресу видеопамяти ).
4.Порядок выполнения работы.
4.1. Написать программу ,которая использует разработанную в лаб.8 процедуру put_pix() и выполняет следующие действия :
4.1.1.Переводит систему в графический режим 10H.
4.1.2.Вычерчивает прямоугольник с параметрами соответствующими индивидуальному заданию.( rest_m())
4.1.3.Закрашивает прямоугольную область с параметрами соответствующими индивидуальному заданию.(bar_m())
4.1.4.Рисует наклонную линию,используя модификацию алгоритма Брезенхейма с параметрами,соответствующими индивидуальному зада-
нию.(line_m()).
4.1.5.Возвращает систему в текстовый режим.
70