Page 1 of 2
Помогите написать игру )
Posted: Mon Sep 07, 2009 6:08 pm
by chaykin
Очень хочу написать игру с кучей класных эффектов но уже давно мучаясь и пришол к выводу что неопходимый код я написать не смогу.
А именно что мне нужно : берётся два изображения одно чёрно-белое другое цветное в итоге получается такая вещь
цветное изображение становится прозрачным в зависимости от интенсивности белого на чёрно-белом изображении то есть чветное изображение становится градиентно-прозрачным

надеюсь меня поняли и дадут пару советов или строчек кода

ЗАРАНЕЕ СПАСИБО!
p.s. пишу под колибри исключительно на assembler'е
Re: Помогите написать игру )
Posted: Mon Sep 07, 2009 7:15 pm
by IgorA
Code: Select all
;input:
; edx = transparent color
; edi = background color
;output:
; edx = combine color
ColSm:
push eax bx cx si
mov bx,0x0100 ;---get transparent---
rol edx,8
sub bl,dl ;256-pro
xor ch,ch
mov cl,dl ;pro
xor dl,dl
rol edi,16 ;---red---
rol edx,8
xor ah,ah
mov al,dl
imul ax,bx
mov si,di
and si,0xff
imul si,cx
add ax,si
;shr ax,8
mov dl,ah
rol edi,8 ;---green---
rol edx,8
xor ah,ah
mov al,dl
imul ax,bx
mov si,di
and si,0xff
imul si,cx
add ax,si
mov dl,ah
rol edi,8 ;---blye---
rol edx,8
xor ah,ah
mov al,dl
imul ax,bx
mov si,di
and si,0xff
imul si,cx
add ax,si
mov dl,ah
pop si cx bx eax
ret
может это поможет
Re: Помогите написать игру )
Posted: Tue Sep 08, 2009 1:50 pm
by chaykin
Спасибо большое

, но если не сложно , ты мог бы дать пару коментариев по поводу того как это получается. Просто я никогда не мог понять механизм прозрачности,

и в любом случае встраивая код в прогу мне придётся его подправить под неё .
Re: Помогите написать игру )
Posted: Tue Sep 08, 2009 7:45 pm
by Rock_maniak_forever
chaykin wrote:Спасибо большое

, но если не сложно , ты мог бы дать пару коментариев по поводу того как это получается. Просто я никогда не мог понять механизм прозрачности,

и в любом случае встраивая код в прогу мне придётся его подправить под неё .
Да, да. Мне тоже интересно. Желательно побольше комментариев, если можно.
Re: Помогите написать игру )
Posted: Tue Sep 08, 2009 9:04 pm
by Mario
Вообщето вывод с помощью Альфа канала немного сложнее чем в предложенном коде. Приходится смешивать фоновую точку с точкой выводимой картинки, учитывая значение Альфа канала для точки.
А вообще смешивание производится по цветам (семплам) - точка в случае вывода функциями 7 и 65 (esi=24), выглядит разложенной в памяти так (от младщего байта к старшему):
Code: Select all
pixel1:
.blue db 0xFF
.green db 0xFF
.red db 0xFF
Итого имея три числа: B (Background - фон), S (Sample - семпл цвета) и T (Transparency - прозрачность или Альфа канал), вычисляем конечное значение по формуле:
St = S*T + (1-T)*B
St - получившийся семпл
Соответственно для каждой точки нужно выполнить три таких вычисления.
З.Ы. Поскольку выполнять умножение каждого семпла очень расточительная вещь в плане производительности (команды mul и dev выполняются много тактов), то ее можно попытаться заменить сдвиговыми операциями shl, shr, rol, ror (если это возможно). Или придумать еще что-нибудь. Но оптимизация это уже отдельный разговор.
Re: Помогите написать игру )
Posted: Wed Sep 09, 2009 8:44 am
by IgorA
Функция принимает 2 цвета, в edx содержится основной цвет + альфа канал, в edi цвет фона. Хотя это условно, главное что есть 2 цвета и в результате они смешиваются в указанной пропорции.
Code: Select all
;input:
; edx = transparent color
; edi = background color
;output:
; edx = combine color
Немного дальше функция извлекает альфа канал (прозрачность, в данном случае 1 байт - значения от 0 до 255)
Code: Select all
mov bx,0x0100 ;---get transparent---
rol edx,8
sub bl,dl ;256-pro
xor ch,ch
mov cl,dl ;pro
xor dl,dl
А дальше идет смешивание цветов в указанной пропорции, для каждого цвета (R,G,B) отдельно
Code: Select all
rol edi,16 ;---red---
rol edx,8
xor ah,ah
mov al,dl
imul ax,bx
mov si,di
and si,0xff
imul si,cx
add ax,si
;shr ax,8
mov dl,ah
...
Формула для смешивания в общем виде такая:
cn=(c0*pro+c1*(max-pro))/max
c0 и
c1 смешиваемые цвета
cn новый высчитанный цвет
pro в какой пропорции смешивать цвета
max максимальное значение для пропорции
Возьмем крайние значения:
pro = 0 тогда цвет будет
(c0*0+c1*(max-0))/max = с0*0/max+с1*max/max=c1
или
pro = max тода
(c0*max+c1*(max-max))/max = c0*max/max+c1*0/max = c0
И еще пояснения
bx = max-pro
cx = pro
mov dl,ah - равносильно формуле dl = ax / 256
Re: Помогите написать игру )
Posted: Wed Sep 09, 2009 9:51 am
by Mario
IgorA wrote:Функция принимает 2 цвета, в edx содержится основной цвет + альфа канал, в edi цвет фона. Хотя это условно, главное что есть 2 цвета и в результате они смешиваются в указанной пропорции.
Да, похоже я проглядел - не увидел данных на входе, вот и решил что без Альфа канала.
Формулу, которую я привел, взял из официальной спецификации PNG.
У тебя формула сложней, а дает тот-же результат по сути. ИМХО надо стремиться к оптимизации.
Re: Помогите написать игру )
Posted: Wed Sep 09, 2009 3:34 pm
by IgorA
заметил один недостаток в функции, правда он почему-то особо не мешал работе программы. Было так:
Code: Select all
mov bx,0x0100 ;---get transparent---
rol edx,8
sub bl,dl ;256-pro
xor ch,ch
mov cl,dl ;pro
xor dl,dl
Желательно сделать так:
Code: Select all
mov bx,0x00ff ;---get transparent---
rol edx,8
sub bl,dl ;255-pro
xor ch,ch
mov cl,dl ;pro
xor dl,dl
Mario wrote:У тебя формула сложней, а дает тот-же результат по сути. ИМХО надо стремиться к оптимизации.
Дело в том что это одна и та же самая формула, просто обозначения разные.
St = S*T + (1-T)*B
При оптимизации желательно избавится от операций с дробными числами, вот здесь
1-T, потому лучше всего все числа привести к целочисленным, допустим умножить все и разделить на 256.
Re: Помогите написать игру )
Posted: Thu Sep 10, 2009 1:21 am
by Rock_maniak_forever
IgorA,
Mario
--------------------
Очень полезная и нужная инфа. Большое спасибо.
-----------------------------------------------------------------------------------------
So far, so good, so what ...
-----------------------------------------------------------------------------------------
Re: Помогите написать игру )
Posted: Thu Sep 10, 2009 12:36 pm
by Rock_maniak_forever
Вот написал кусок кода по формуле Mario, так как она попроще. Вродебы всё правильно, но я не уверен. С матиматикой и программированием, у меня туго, поэтому если не трудно, кто ни-будь проверьте и поправьте. Вообщем как сказали великие Beatles, в одной из своих песен - " Help, i need some body help".
Code: Select all
; Функция получения прозрачности для одного сэмпла.
;input:
; eax = transparent color
; edi = background color
;output:
; edx = combine color
GetPixTransp: xor edx,edx ; edx=0
inc edx ; edx=1
sub edx,eax ; (1-T)
and edx,edi ; (1-T)*B
rol eax,8 ; S*T
or edx,eax ; S*T + (1-T)*B ; ST = edx
.
---------------------------------------------------------------------------------------------------------------------------------------------
I am android. In my head creazy chip. My head fetch down... fetch down... fetch down... over...
---------------------------------------------------------------------------------------------------------------------------------------------
Re: Помогите написать игру )
Posted: Thu Sep 10, 2009 12:48 pm
by Mario
Rock_maniak_forever
1) для quote= и code= все что после знака равенство надо в кавычки ""
2) нельзя рассчитывать сразу весь пиксел - надо рассичтывать отдельные составляющие (семплы).
2)Констркуция:
Code: Select all
xor edx,edx ; edx=0
inc edx ; edx=1
sub edx,eax ; (1-T)
Замечательно заменяется на:
4) Дальше:
Code: Select all
rol eax,8 ; S*T
or edx,eax ; S*T + (1-T)*B ; ST = edx
вообще не в тему.
Re: Помогите написать игру )
Posted: Thu Sep 10, 2009 12:54 pm
by Rock_maniak_forever
Я это и имел ввиду, просто описался.
На счёт neg eax - это вопрос оптимизации, поэтому это не сильно важно, но нужно. Я оптимизирую во вторую очередь.
Mario wrote:4) Дальше:
Code: Select all
rol eax,8 ; S*T
or edx,eax ; S*T + (1-T)*B ; ST = edx
вообще не в тему.
А как?
Re: Помогите написать игру )
Posted: Thu Sep 10, 2009 1:12 pm
by Mario
Приблизительно так (ниже) для вычисления единичного семпла. Для трех семплов надо три раза вызвать, для обработки всего пикселя.
Code: Select all
;input
;al = sample front color
;ah = transparent
;bl = sample background color
;output
;cl = combine sample
mov bh,ah
xor ecx,ecx
mov cl,al
shr ax,8
imul cx,ax
xor edx,edx
mov dl,bl
shr bx,8
neg bx
imul dx,bx
add cx,dx
За 100% работоспособность не ручаюсь - не проверял работу.
Re: Помогите написать игру )
Posted: Thu Sep 10, 2009 1:15 pm
by Rock_maniak_forever
Большое спасибо, буду разбираться.

Re: Помогите написать игру )
Posted: Sun Sep 13, 2009 10:07 am
by Yaskhan
Мoжно использовать MMX:
4. Канал прозрачности (alpha blending) [далее ab] – одно изображение плавно появляется или растворяется поверх другого (также очень часто применяется при работе с видео).
Формула ab: a = b + (a - b) * alpha
Где: a – основное изображение
b – изображение которое накладывается
alpha – количество градаций(позиций) ab - обычно хватает 0...255.
переведем это все в MMX-команды:
a) инициализация регистров
биты 31...24 23...16 15...8 7...0
eax = alpha alpha alpha alpha
movd mm4,eax ; переносим данных из eax в mm4
punpcklwd mm4,mm4 ; создаем четыре cлова alpha-канала
psrlw mm4,8 ; переносим старшую часть слов в младшую
pxor mm7,mm7 ; обнуляем mm7
б) основная процедура
movd mm0,[esi] ; загрузить в mm1 четыре байта накладываемого изображения
movd mm1,[edx] ; загрузить в mm0 четыре байта основного изображения
punpcklbw mm0,mm7
punpcklbw mm1,mm7
psubw mm0,mm1 ; вычитаем из накладываемого, основное изображение
psllw mm1,8 ; переносим младшую часть слов регистра mm1 в cтаршую
pmullw mm0,mm4 ; умножаем накладываемое изображение на alpha-канал
paddw mm1,mm0 ; складываем его с основным
psrlw mm1,8 ; переносим результат из старшей части слова в младшую
packuswb mm1,mm1 ; и переводим его в 32 бита
movd [edi],mm1 ; кладем полученное изображение на экран (в видеобуфер)
add esi,4
add edx,4
add edi,4
В данном примере используется быстрое 16-битное MMX-умножение, которое и дает максимальное ускорение нашей процедуре. Плюс - уже ставшая традицией – обработка сразу четырех байт...