Наложение рисунков и спецэффекты
Значение 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-графике для получения различных эффектов. Рассмотрим некоторые из них.