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

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

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

Формулу для выполнения альфа-наложения тумана однородного цвета можно записать в следующем виде:

X[i,j] = Fc[j] * alpha[i] + X[i,j] * (1 – alpha[i])

Здесь FC – цвет тумана, ах– цвет изображения, затягиваемого туманом. Запись Fctj] означает, что каждая точка тумана окрашена в один и тот же цвет, это позволяет избавиться от файла, содержащего изображение тумана. В отличие от ранее приведенных формул, в данном случае у коэффициента alpha появился индекс 1, т. е. значений alpha должно быть столько, сколько точек в основном рисунке (который затуманивается). О том, как подготовить массив значений alpha, мы поговорим после.описания программной реализации формулы.

Если у значений alpha убрать индекс i, то получится формула для наложения прозрачного цвета, которая была реализована в подпрограмме примера 7.31. Следовательно, надо несколько изменить внешний цикл этой подпрограммы, добавив в него выборку значения alpha для каждой точки изображения, что и сделано в примере 7.32. Предполагается, что затягиваемое туманом изображение находится на экране.

Перед вызовом подпрограммы в регистре di указывается адрес начала строки рисунка в видеопамяти, а в fs:si – адрес начала строки коэффициентов alpha в буфере обмена. В сх задается количество точек в строке.

Пример 7.32. Наложение строки тумана заданного цвета.

Foglin: PushReg <bx, dx>; сохранение регистров bx, dx
f og_l: push ex; сохранение счетчика повторов
lods byte ptr f s: [si]; al = alpha [i]
mov byte ptr falpha, al; falpha = al запоминаем alpha [i]
push si сохраняем содержимое si
lea si, fogcol si = адрес переменной fogcol
mov ex, 03 для обработки трех базовых цветов
f og_2: lodsb al = базовый цвет тумана (F[j])
mov Ы, es: [di] Ы = базовый цвет точки (Y[i,j]>
xor ah, ah преобразуем байт в слово
xor bh, bh преобразуем байт в слово
sub ax, bx ах = F[j] – Y[i,j]
imul falpha ах = ах * alpha [i]; dx = 0
xchg al, ah al = ax/256
add al, Ы al = al + Y[i,j]
stosb сохраняем результат в видеопамяти
loop fog 2 трехкратное повторение цикла
inc di пропуск резервного байта
jne @F › адрес в пределах текущего окна
call NxtWin установка следующего окна
@@: Pop si восстановление адреса в si
pop ex восстановление счетчика повторов
loop fog 1 управление повторами цикла
PopReg <dx, bx> восстановление регистров dx, bx
ret возврат из подпрограммы

Значения alpha изменяются от 0 до 255, для сокращения размера файла их лучше хранить в виде байтов, но при умножении коэффициент alpha должен иметь размер слова. Поэтому в примере 7.32 введена специальная переменная falpha, имеющая размер слова. Ее надо описать в разделе данных задачи, присвоив нулевое значение.

Во внешнем цикле примера 7.32, по сравнению с примером 7.31, появились три новые команды. Первая из них считывает очередное значение alpha [i] в регистр al (и увеличивает содержимое si на 1). Вторая копирует содержимое ai в младший байт переменной faipha, а третья сохраняет в стеке адрес, находящийся в регистре si. Таким образом, в результате выполнения этих трех команд получено очередное значение alpha и освобожден регистр si. Теперь в него можно записать адрес переменной, содержащей цвет тумана, для использования во внутреннем цикле, это же делалось и в примере 7.31.

После выхода из внутреннего цикла восстанавливается находившийся в si адрес, и при повторе внешнего цикла будет выбрано следующее значение alpha из буфера обмена.

Для использования описанной подпрограммы надо подготовить файл, содержащий значения коэффициентов alpha. От их расположения в файле зависит способ построения рисунка, поэтому первыми должны располагаться коэффициенты для его верхней, а последними – для нижней строки. В таком случае построение будет производиться в направлении слева направо и сверху вниз, т. е. по наиболее простой схеме. Способ чтения файла в буфер обмена зависит от количества значений alpha. Например, для затягивания туманом всего изображения при разрешении 640x480 точек файл будет содержать 307 200 байтов и его придется считывать по частям.

Следовательно, перед построением риcунка надо вычислить размер считываемой порции данных (количество строк и байтов в порции). Мы это делали неоднократно.

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