GP32 Mr Mirko Sdk - Blitting


pea

developer
Joined
Oct 3, 2004
Messages
1,089
Age
45
Location
New Zealand
Website
www.projectitis.com
Hi guys,

Is it possible using Mr Mirkos SDK to blit a sprite to the screen using another sprite (black and white for eg) as a transparency mask? Either on or off I mean, not transparency levels....

Cheers
 
Please read the SDK doc.
There is only a standrad 50% alpha blitting, no alpha masks (yet)
feel free to write some functions...
 
Hi all,

Next job is to get transparency working (for transparent GIFs etc - so only on/off type transparency). Unfortunately I can't use a fast method of blitting such as memcpy because each pixel needs to be processed individually.

My idea is as follows:
1) On loading the gif, create a transparency mask (0 or 65535 for 16bpp colour) and store it with the gif itself. This will increase the mem, but hopefully the speed increase will override this.
2) Go through each pixel with the following formula which uses an add and a few bitwise operations, but NO mult or division:
D = Destination pixel (currently on screen)
S = Source pixel (from GIF)
M = Mask pixel (either 000..0 or 111...1)
Code:
/* psuedo code */
for (each pixel){
  D = (S & M) + (D & (M &/ M));
}

What this does is:
(S & M)
This will AND the source pixel and the mask. If the image is transparent at this point (mask = 0) then the result will be 0, otherwise S. If the result is S, the result of the second part will always be 0.

(M &/ M)
The bitwise operator &/ is NAND. All this does is invert the mask (if it was 0 it becomes 65535, if it was 65535 it becomes 0)

(D & (M &/ M))
This will AND the dest pixel and the inverted mask. If the image is transparent at this point, then the result will be D, otherwise 0. If the result is D, the result of the first part will always be 0.

example
Code:
S=10; D=20; M=true;
(S & M) = 10;
(S & !M) = 0;
result = 10; // show source pixel

S=10; D=20; M=false;
(S & M) = 0;
(S & !M) = 20;
result = 20; // show dest pixel

Does anyone see any reason why this won't work, or see a faster way of doing it? I want to avoid all conditional statements (if...then) and all mult and div.
 
hmm..
1. running throug all pixels is slow, maybe just memcopy the pixels between two transparent pixels?

2. GIF itself can have a transparency color, just read it out of the pallette with no need for the extra data (only for pixel perfect collision...)
 
Hi Synkro,

Both good ideas, some problems are:

running through all pixels is slow, maybe just memcopy the pixels between two transparent pixels?
Great idea! I'll definately give it a go, but I think that this may be slow if there are lots of transparent pixels, and the data between them has to be copied in small chunks.

Also, to find the start and end of each 'run' between transparent pixels you have to step through every single pixel anyway and do a comparison to see if it is equal to the transparent colour or not! (comparison = many clock cycles = very slow).
- This could be done just once when the graphic is loaded, and a list of start-end pairs saved alongside the image. This is sort of like the blit mask, but should be less data in most cases.

GIF itself can have a transparency color, just read it out of the pallette with no need for the extra data (only for pixel perfect collision...)

This is exactly what I do - I extract the transparent colour from the GIF and use this. The reason I build a mask and not just compare against the transparent colour is because a mask allows me to completely cut out comparisons, and only use relatively inexpensive bitwise operations and additions.
 
I wonder what the pros use ...
well... I guess that a special sprite format would help to gain max speed:

1.) RLE
2.) not store a complete bitmap but a list of pixel strips (only the pixels to be drawn) and the distance (the distance is the number of transparent pixels) to the next pixel strip

-> less data, no transparency check on pixel basis, just copy the pixel strips with the given offset

maybe we should check out how the pros used transparency on other platforms as SNES, Amiga or PSone and how they stored their data and what algorithms they used .... IMHO GIF or any other plain bitmap is not sufficient for transparency speedwise. Choose a data structure/container that is optimized for the given task. more calculations have to be done during the creation of the sprite to reduce render time ...

Great idea! I'll definately give it a go, but I think that this may be slow if there are lots of transparent pixels, and the data between them has to be copied in small chunks.

if there are large areas of transparency in your sprite -> then you can decompose it to 2 or more smaller sprites
 
The format of the sprite (whether it be GIF or anything else) is immaterial because once it is loaded it is stored as an array of pixel color values anyway.

RLE encoding a graphic would be much slower IMO than raw data. With raw data you can simply use memcpy to very efficiently copy chunks of data from one place to another. With RLE encoded data you can't do this because you need to decode it first.

The pixel strips is a good idea, although all you are doing is RLE encoding the transparent pixels only :) It could work ok though.

Some of these ideas will work, but only if the sprite is 100% visible. As soon as the sprite leaves the screen area slightly and needs to be cropped, you will have problems because the data is not nicely in a raw array format, which is easy and fast to 'crop'
 
ah right, didn't think of that... hmm... I will have a look in net, there must be somewhere some resources about proper sprite handling... some people have already thought about it ...
 
Back
Top