Qbasicnews.com

Full Version: Transparent backgrounds (tutorial 6)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i read tut 6 and got it working. What i'd like to do is load images on the screen and get them one by one (that was my previous post). i changed the background to be something that the image can never be, pink, blue, whatever. i've noticed that when the background is something other than black and i still create a mask by setting the background points to 255, it's not transparent. If the background is 0 and then the mask is 255, it works. Is there a way to avoid this or does the transparent part always have to be 0?

So with this code snippet, if i changed the data statements to be color 100 instead of 0, it won't be transparent where as now as 0 it is. Any ideas?
Code:
SCREEN 13

DIM x(13)
DIM xMask(13)

FOR y = 1 TO 5
    FOR x = 1 TO 5
        READ pixel
        PSET (x, y), pixel
    NEXT
NEXT
GET (1, 1)-(5, 5), x

FOR y = 1 TO 5
    FOR x = 1 TO 5
        READ pixel
        PSET (x, y), pixel
    NEXT
NEXT
GET (1, 1)-(5, 5), xMask

PAINT (10, 10), 4
PUT (50, 50), xMask, AND
PUT (50, 50), x, OR

DATA 2,0,0,0,2
DATA 0,2,0,2,0
DATA 0,0,2,0,0
DATA 0,2,0,2,0
DATA 2,0,0,0,2

DATA 002,255,255,255,002
DATA 255,002,255,002,255
DATA 255,255,002,255,255
DATA 255,002,255,002,255
DATA 002,255,255,255,002
Here's a tut on masking I wrote some time ago, it may be useful for you to understand why 0 and 255:

Quote:As you may have noticed, the PUT function has those parameters:

Code:
PUT (x%, y%), array%(index%)[, mode]

where mode can be either PSET, AND, XOR among others. That final parameters especifies a logical operation between the pixel data in the array and the pixel data on screen.

What is a logical operation? Well, I guess you have heard of AND and OR, and that:

Code:
1 OR x = 1
0 OR 0 = 0
0 AND x = 0
1 AND 1 = 1

where x can be either 1 or 0. You also have XOR:

Code:
x XOR x = 0
x XOR y = 1 if x<>y

Those binary operations can be applied to byte numbers, for example, 127 AND 255 will compare each bit of 127 with its correspondent bit in 255, and will build a new byte with the results:

Code:
127 = 0 1 1 1 1 1 1 1
AND
    255 = 1 1 1 1 1 1 1 1
______________________
          0 1 1 1 1 1 1 1 = 127

This is very useful when trying to avoid the ugly black bounding box around our GFX. With masking techniques, you can get rid of it.

First we need to create a mask. Imagine we want a ball. We think on which pixels will be transparent and draw it with colour #ZERO:

Code:
00 00 01 02 02 01 00 00
00 01 02 03 03 02 01 00
01 02 03 03 03 03 02 01
01 02 03 03 03 03 02 01
01 02 03 03 03 03 02 01
01 02 03 03 03 03 02 01
00 01 02 03 03 02 01 00
00 00 01 02 02 01 00 00

Now, we create the mask. We need a similar drawing, but the transparent zones have to be drawn with colour #FFh (255, the last colour, in binary 11111111b). The non-transparent zones have to be drawn with colour #00h, that is:

Code:
FF FF 00 00 00 00 FF FF
FF 00 00 00 00 00 00 FF
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
FF 00 00 00 00 00 00 FF
FF FF 00 00 00 00 FF FF

what for? well, let me explain:

To do masking, we first need to prepare screen. If we PUT the mask using "AND", the blitter will AND each pixel in our mask with its correspondent on screen. That will make that every pixel on screen that corresponds with a FF in our mask (transparent zone) will remain as it is, 'cause x AND FF = x. It will also make that every pixel on screen that corresponds with a 00 in our mask (solid zones) will be cleared to ZERO, 'cause x AND 0 = 0.

Note that this will create a black zone with the shape of our sprite on screen.

Now we PUT the sprite using "XOR". Note that x XOR 0 = x and 0 XOR x = x, so the pixels in your sprite that equal 0 (transparent zones) won't have no effect on screen (and those pixels on screen will still have the background, after the AND operation), and the pixels in your sprite different from 0 will be XORed with pixels on screen that equal zero (after the AND operation, if your mask was correctly done).

Code:
' Transparent blit using masks:
PUT (x%, y%), myMask%(0), AND
PUT (x%, y%), mySprite%(0), XOR

I can't post examples 'cause my webspace can not be accessed tonight, so I can't upload pics to show you Sad.

LATER:

I've written this piece of code as an example:

Code:
' Masking demo by Na Than Assh Antti 2003

'$DYNAMIC
DIM MySprite%(33)
DIM MyMask%(33)

SCREEN 13

' Colour #255 is by default BLACK. Let's turn it into WHITE so we can
' see the mask (for educational purposes):

OUT &H3C8, 255: OUT &H3C9, 63: OUT &H3C9, 63: OUT &H3C9, 63

' Get the sprites: [I am using ugly and stupid DATA sprites :P]

RESTORE
FOR i% = 0 TO 1

   FOR y% = 0 TO 7
      FOR x% = 0 TO 7
         READ a$
         PSET (i% * 8 + x%, y%), VAL("&H" + a$)
      NEXT x%
   NEXT y%

NEXT i%
GET (0, 0)-(7, 7), MySprite%(0)
GET (8, 0)-(15, 7), MyMask%(0)

CLS
PAINT (0, 0), 34

LOCATE 3, 5: PRINT "THIS IS THE SPRITE:"
PUT (220, 16), MySprite%(0), PSET
LOCATE 5, 5: PRINT "THIS IS THE MASK:"
PUT (220, 32), MyMask%(0), PSET
LOCATE 7, 5: PRINT "Let's see what happens if we PUT"
LOCATE 8, 5: PRINT "our mask using AND:"
PUT (156, 72), MyMask%(0), AND
LOCATE 12, 5: PRINT "Now we PUT the mask with AND and "
LOCATE 13, 5: PRINT "then the sprite with XOR:"

' Transparency:
PUT (156, 112), MyMask%(0), AND
PUT (156, 112), MySprite%(0), XOR

' DONE :D

END

' Sprite:
DATA 00,00,01,01,01,01,00,00
DATA 00,01,02,02,02,02,01,00
DATA 01,02,02,03,03,02,02,01
DATA 01,02,02,03,03,02,02,01
DATA 01,02,02,03,03,02,02,01
DATA 01,02,02,03,03,02,02,01
DATA 00,01,02,02,02,02,01,00
DATA 00,00,01,01,01,01,00,00

' Mask:
DATA FF,FF,00,00,00,00,FF,FF
DATA FF,00,00,00,00,00,00,FF
DATA 00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00
DATA FF,00,00,00,00,00,00,FF
DATA FF,FF,00,00,00,00,FF,FF
So basically the final ANDed operation has to be all 0s? Cause 0 AND 255 would set all of the bits to 0?

If that's the case, would it be safe to say that every color has the potential to have a transparent background, a different number than 255 that when ANDed with the original color would set everything to 0?
There's no need to change the transperant color to anything else. You can just use palette function to have black in another position (like number 1 instead of number 0), it will make it appear on screen as black instead of transperant. I suppose that is what you want.
The problem is i dont know when something will be black and when something will be transparent. What im doing is loading up the image and dumping it to the screen. Then looping through and GETting all of the images. i then create a mask by scanning the pixels in the image and if i found a 0, i PSET 255 instead of that color. But when scanning through, i dont know if its supposed to be black or if it's the background color. Hence me wanting to use a completely different color that i know will never be used.
You can also use black (0) in your sprite. If you read my tutorial, it is in the mask where you decide which bytes will be transparent. If you have a pixel in your sprite with "0" and that pixel in the mask is "0" as well, it will be a solid black pixel.