by Rawhed(Andrew Griffiths)/Sensory Overload - 20 May 1999
sfeist@netactive.co.za
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Right, I'm assuming you've dealt with 16bit color before, so I won't explain the
basics. A very cool thing you can do with 16bit color is layering. Yes, just
like photoshop. Layering and transparency are very cool effects, but are
actually very processor intensive as you have to separate the red, green and
blue value from each pixel color. So for example, here is a standard
transparency routine:
Yes, I know its not the best implementation, but I think it shows how you have
to split the RGB and deal with them separately. And you have to either push +
pop, or you run out of registers. Its disgusting. You could tweak this to be a
bit better, bit its still yuksei. I tried a better way.
This way I'd been thinking of for a while(ever since I started RGB color
coding), but never thought it would work for some reason. But I just tried it,
and since it works I'm writing this document :)
It is cooler because it only uses 2 registers - EAX and EBX. Nothing else, and
no stack. Its also cleaner and uses 32bit for some code. Freeing up registers is
important because then you can optimise the rest of your inner-loop A LOT.
Basically I thought that when you go:
Then why couldn't you just go:
And that would add the pixel colours together. Well, it doesn't work because
overflows occur and the blue might seep into the green, or the green seep into
the red. So you DO have to work with the R G B seperatly. So here is what I
thought of:
If you have the pixel1 color in AX, then EAX would contain zeros and then the
data. If you have the pixel2 color in BX, then EBX would contain zeros and then
the data. So if you could somehow use that zero area in the registers as a
buffer zone to spread the RGB values out across, you could add the colors
together without the red, green or blue interfeering with each other.
Understand? hehe.
Ok, here is EAX, and EBX right after you read the pixels into them:
Now, if you could get it to look like this:
Then you could just go:
And there would be no problems. Cool eh? :)
But how do you get it to be rearranged? And then surly once you've added the 2
together, you have to rearrange it back to the standard RGB format? Yes, yes
yes.
For EAX and EBX we have to perform a transformation on them. Luckily for you
I've already had to figure out the transformation(and it was fun), and here it is:
Ok, cool so now we have 2 dwords, ready to add. And they won't overflow :) So
you can either add them and then divide by 2 for transparency, or you can do a
cool thing and add them and clip their maximum range. Like:
cool, so now we have:
And we need to convert it back to normal RGB format. Which is just as easy as:
and now we just go:
So here is a complete example:
Its very speedy, very slick, and it frees up registers. I found that using this
technique I could have everything else out of the inner loop, and I just had
like 3 more instructions in the inner-loop. Anyways, lemme know what you think.
Perhaps this is oldhat :)
-Rawhed/Sensory Overload
xor eax,eax
xor ebx,ebx
mov ax,[esi] ;getpixel spritemap
mov bx,[edi] ;getpixel target for transparency layering
;--------------------------------------
rol eax,11 ;1 ;conversion 1
shr ax,11 ;2
ror eax,16 ;3
shl ax,2 ;4
shr al,2 ;5
rol eax,16 ;6
shl ax,8 ;7
rol ebx,11 ;1 ;conversion 2
shr bx,11 ;2
ror ebx,16 ;3
shl bx,2 ;4
shr bl,2 ;5
rol ebx,16 ;6
shl bx,8 ;7
;--------------------------------------
add eax,ebx ;add them together!!!
;--------------------------------------
ror eax,8
cmp al,31
jle @blue_is_cool ;check if overflow - blue?
mov al,31
@blue_is_cool:
ror eax,8
cmp al,63
jle @green_is_cool ;check if overflow - green?
mov al,63
@green_is_cool:
ror eax,8
cmp al,31
jle @red_is_cool ;check if overflow - red?
mov al,31
@red_is_cool:
;--------------------------------------
rol eax,8 ;1 ;convertback
shl al,2 ;2
rol eax,8 ;3
shl al,3 ;4
ror eax,2 ;5
shl al,2 ;6
shr eax,3 ;7
;--------------------------------------
mov [edi],ax ;putpixel
-Mailto:sfeist@netactive.co.za
-Htpp://www.surf.to/demos/
-Andrew Griffiths
-South Africa
-20-05-1999