Иллюстрированный самоучитель по SVGA

Наложение рисунков и спецэффекты

Значение alpha может изменяться от 0 до 255, оно указывается в одноименной переменной, имеющей размер слова, ее надо описать в разделе данных задачи, присвоив конкретное значение, или предусмотреть возможность ввода этого значения перед наложением рисунка.

Пример 7.30. Альфа-наложение строки формата bдг, режим True Color.

alphamix: PushReg <bx,dx>; сохранение регистров bx, dx
mixpnt: push ex; сохранение счетчика повторов
mov c.x, 03; для обработки трех базовых цветов
mixcol: mov Ы, es:[di]; Ы = код базового цвета Y[i,j]
iods byte ptr fs:[si]; al = код базового цвета X[i,j]
xor ah, ah преобразуем байт в слово
xor bh, bh преобразуем байт в слово
sub ax, bx X[i,j] = X[i,j]-Y[i,j]
imul alpha ax = (X [i, j ] – Y[i, j ]) * alpha; dx = 0
xchg al, ah al = ax/256
add al, Ы Z[i,j] = (X[i,j]-Y[i,j])*alpha/256+Y[i,j]
stosb запись Z[i,j] в видеопамять
loop mixcol управление повторами цикла
inc di пропуск резервного байта
jne @F › адрес в пределах текущего окна
call NxtWin установка нового окна
@@: pop ex восстановление счетчика повторов
loop mixpnt управление повторами цикла
PopReg <dx,bx> восстановление регистров dx, bx
ret возврат из подпрограммы

Подпрограмму alphamix можно использовать при построении рисунков, хранящихся в форматах BMP (не упакованный) и PCX (упакованный). Для этого в примерах 7.25 и 7.28 достаточно просто заменить call drawiine на call alphamix. Замена возможна потому, что в обоих случаях используется одна и та же подпрограмма drawiine.

Основные действия в примере 7.30 выполняются во внутреннем цикле, имеющем метку mixcol, рассмотрим их более подробно. Две первые команды считывают в регистры ы и al коды смешиваемых базовых цветов. Перед вычитанием значения байты преобразуются в слова. Специальная команда CBW (convert byte to word) в данном случае не применима, т. к. она интерпретирует коды со значениями больше чем 127, как отрицательные числа.

В примере 7.30 просто очищаются старшие байты регистров ах и bx, после чего выполняется вычитание (ах = ах – bx). Результат вычитания может быть как положительным, так и отрицательным числом, поэтому для его умножения на значение переменной alpha используется специальная команда imui. В отличие от команды mul она интерпретирует операнды как числа со знаком.

Произведение находится в регистрах dx:ax, но поскольку модули значений операндов не превышают 255, dx будет просто очищен, а в ах будет находиться младшая часть произведения. Вместо деления результата на 256 выполняется перестановка байтов регистра ах (с таким же успехом его содержимое можно было сдвинуть на 8 разрядов вправо). Остается сложить содержимое регистров ai и ы и записать результат в видеопамять. Последняя команда loop mixcoi трижды повторяет выполнение цикла.

После выхода из внутреннего цикла адрес видеопамяти увеличивается на 1 для пропуска резервного байта в коде точки. Как обычно, проверяется принадлежность адреса установленному окну видеопамяти и, в случае необходимости, устанавливается следующее окно. Затем в регистр сх из стека выталкивается содержимое счетчика повторов, и команда loop mixpnt управляет повторами внешнего цикла.

Очевидно, что наложение рисунка будет выполняться дольше, чем его простое построение. Более точное представление о степени замедления дают результаты следующего эксперимента. Один и тот же рисунок формата BMP, размером 640x480 точек просто строился, или накладывался на изображение, уже имеющееся на экране. В обоих случаях основная подпрограмма соответствовала примеру 7.25. Компьютер был укомплектован процессором Pentium с тактовой частотой 100 МГц. Время, затрачиваемое на наложение, увеличилось, по сравнению со временем построения, примерно на 1.1 сек. Это свидетельствует о том, что альфа-наложение можно выполнять с помощью обычных команд, но лучше использовать операции ммх или функции акселератора.

Альфа-смешение – это один из популярных приемов используемых в 3D-графике для получения различных эффектов. Рассмотрим некоторые из них.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.