Глава 4. Вывод на терминал.

Раздел 4. Вывод точечной графики.

4.4.6 Заполнение областей экрана.

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

В {4.3.4} объяснено как создать описание символа в виде матрицы 8*8 точек, имеющего требуемый Вам вид. Хотя такие символы могут выводиться только в стандартные символьные позиции, но их использование может существенно облегчить заполнение графиков. Образец высвечивающий все 8*8 точек может быть выведен в интервале нескольких строк и столбцов, заполняя область намного быстрее, чем это достигается при поточечной зарисовке. Этот тип графических символов может использоваться совместно с точечной графикой. Псевдографические символы могут использоваться также для вывода вращающихся или колеблющихся объектов.

Hизкий уровень.

Имеется много подходов к написанию процедур заполнения графических объектов. Hи один из них не является идеальным, поскольку всегда имеется конфликт между скоростью работы процедуры и сложностью фигур, которые она может обрабатывать. Любая процедура, которая заполняет область точку за точкой будет медленной, независимо от того, насколько элегантно она реализована. Имейте ввиду, что почти каждая модифицируемая точка расположена в байте, все точки которого будут изменяться в тот же самый цвет. Получение доступа к одному и тому же байту с использованием сложных процедур требует существенно больше времени, чем установка целого байта за один доступ к ячейке видеобуфера. Hапример, поточечная очистка экрана требует на IBM PC нескольких секунд при использовании функции BIOS, в то время как прямой доступ в память производит эту операцию мгновенно:
MOV AX,0B800H ;ES указывает на буфер экрана
MOV ES,AX ;
MOV CX,8192 ;заполняем все байты
MOV AX,0 ;в каждый байт пишем 0
MOV DI,0 ;DI поочередно указывает на все байты
REP STOSW ;повторяем запись 8192 раза

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

Имеется очень быстрый способ определения присутствует ли граничный цвет в данном байте видеобуфера. Предположим, что процедура ищет цвет 1 палетты в режиме умеренного разрешения с четырьмя цветами. Этому цвету соответствует код 01, поэтому сначала заполним весь байт этим кодом: 01010101. Затем используем операцию NOT для обращения каждого бита, после чего байт примет вид 10101010. Проделаем операцию XOR со значением взятым из видеобуфера; в результате получим байт, у которого оба бита, относящиеся к одной точке равны 1 только для точек, имеющих граничный цвет. Затем снова используем операцию NOT с тем, чтобы пара битов, относящихся к точке граничного цвета имела код 00. После этого используем операцию TEST для нахождения полей со значением 00. Если такое поле найдено, то граничный цвет обнаружен и процедура переходит к обычному поточечному анализу данного байта. Эту процедуру можно еще убыстрить, если использовать словные данные.
MOV AL,ES:[BX] ;берем байт из видеобуфера
XOR AL,10101010B ;устанавливаем биты для цвета границы
NOT AL ;обращаем биты
TEST AL,11000000B ;проверяем биты 7-6
JZ FOUND_BOUND ;переход если граничный цвет
TEST AL,00110000B ;проверяем биты 5-4
JZ FOUND_BOUND ;переход если граничный цвет
TEST AL,00001100B ;проверяем биты 3-2
JZ FOUND_BOUND ;переход если граничный цвет
TEST AL,00000011B ;проверяем биты 1-0
JZ FOUND_BOUND ;переход если граничный цвет
MOV AL,FILL_COLOR ;граничного цвета нет, заполняем байт
MOV ES:[BX],AL ;возвращаем байт в видеобуфер
.
.
FOUND_BOUND:

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


<~-4.4.5 Рисование линий на экране.
Содержание
4.4.7 Графический вывод с использованием символов псевдографики.-~>

Сайт управляется системой uCoz