Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Problems with sprite transparency

Credits go to gnolam, LordHolNapul, Marco Radaelli, Tobias Dammers, and X-G for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
Problems with sprite transparency
Skywhy
Member #9,243
November 2007
avatar

I don't know where to put this question.. Having huge problems with anti-alised sprites.

By default allegro uses magic pink(255,0,255) as transparent color.
Ok, I have a pink background and a black anti-aliased ball on it. Nothing special BUT.. The extra bits that are antialised get mixed with the pink color and naturally that's not something I want.

Ugh.. well, a picture explains more than thousand words:
http://users.evtek.fi/~larspac/mus/transpar.bmp
There, where the arrow is pointing. The RBG values are 167,0,167, and naturally allegro shows them as a mix of pink + black... Not as a sexy anti-aliased ball like I wanted. If I don't use the anti-alies -> the ball looks really blocky. Which is not desired...

I tried reading the allegro manual about masked_blit and generally about transparency and patterned drawing but most of the manual stuff I didn't quite understand. So I'm kinda lookking for a good kick into the right direction and some hints and tips how to get this working.

EDIT #1: So far I've always drawn my sprites on bitmap buffer with draw_sprite first then blitting it to the screen. Worked fine so far... But now, since I want SMOOTH and CLEAR sprites, I've got no clue how to make them work.

Should I use some blender, draw_trans_sprite or what?

So any help is welcome. Thank you.

EDIT 2: Thanks everyone. :)

Marco Radaelli
Member #3,028
December 2002
avatar

Allegro transparency in 8 bit mode is "black or white", or "none or full". If you want to get more degrees of translucency you have to increase the bit depth.

Call set_bit_depth() before set_gfx_mode() and before any gfx-related function, like load_bitmap() etc :)

gnolam
Member #2,030
March 2002
avatar

Quote:

Should I use some blender, draw_trans_sprite or what?

Yes. For alpha transparency you need to 1) load bitmap files that actually have an alpha channel (vanilla Allegro only handles TGA, but most of us use PNG via loadpng) and 2) draw your sprites with draw_trans_sprite() after setting the alpha channel blender mode: set_alpha_blender()

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Skywhy
Member #9,243
November 2007
avatar

Here is my code:

1#include <allegro.h>
2#include <stdlib.h>
3 
4int main(void)
5{
6 int ret;
7
8 allegro_init();
9 install_keyboard();
10 
11 set_color_depth(32);
12 ret = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0);
13
14 BITMAP *image;
15 BITMAP *buffer;
16 buffer = create_bitmap(800, 600);
17 
18 image = load_bitmap("ball.bmp", NULL);
19
20 draw_sprite(buffer, image, 0, 0);
21 blit(buffer, screen, 0, 0, 0, 0, 800, 600);
22 
23 //wait for keypress
24 while(!key[KEY_ESC]);
25 
26 //end program
27 allegro_exit();
28 return 0;
29}
30 
31END_OF_MAIN()

Okay, currently at work so I can't try it out. But basically *.BMP files don't have alpha channel?

And ALL I need to do is start using the loadpng, make my gfx's in PNG format, and use the draw_trans_sprite to draw my sprites?

Sounds bit.. well, now that I think about it sounds pretty simple. I don't know. Going to try it out later today. But anyway, thanks for the help already, I'll report back tomorrow or later today. :)

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

Okay, currently at work so I can't try it out. But basically *.BMP files don't have alpha channel?

No. They don't. BMP supports 8 bpp paletted images, and 24 bpp true-color. There's no room for alpha.

Quote:

And ALL I need to do is start using the loadpng, make my gfx's in PNG format, and use the draw_trans_sprite to draw my sprites?

Almost. Don't forget to set the alpha blender before drawing. Oh, and make sure you use a suitable color conversion mode when loading the PNGs, that is, one that doesn't convert 32 bpp to anything else (COLORCONV_NONE should work just fine).
If you use TGA instead of PNG, you don't even need loadpng.

And, just to confuse you, there IS a way to do it in 8bpp, but it's hacky and requires a lot of tweaking and tuning. It works OK for some graphical styles, but not for others.
The idea is to assign each palette entry an alpha value (you can use the padding byte in allegro's RGB struct for this), then set up a blending table taking these alpha values into account, and finally use the blending table and draw_trans_sprite() to pseudo-alpha-blend the sprite. Since the alpha values are probably hard-coded and not per-pixel, but per-color, you'll have to manage your palettes manually, which can be quite painful. And, as with all 8bpp blending, the results aren't going to be great - but it does work.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

X-G
Member #856
December 2000
avatar

Quote:

No. They don't. BMP supports 8 bpp paletted images, and 24 bpp true-color. There's no room for alpha.

False. Later versions of the BMP format, beginning with the release of Windows XP, support 32-bit BMPs complete with alpha channel. Photoshop 7 and higher can save them, too. I don't know if Allegro can load them, though.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Tobias Dammers
Member #2,604
August 2002
avatar

I don't suppose allegro's BMP loader has been re-written since the introduction of XP, so allegro probably can't load them. Last time I checked the source it couldn't, in any case.
But seeing that uncompressed formats are far from optimal for 32 bpp image data, I'd suggest PNG anyway.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

LordHolNapul
Member #3,619
June 2003
avatar

I use TGA files in my videogame... TGA 32 bit exactly.
Why wasting your time with BITMAP... ? True Image TGA are better.
ciao;D

Skywhy
Member #9,243
November 2007
avatar

More or less interesting, this is what I thought might happen...

I downloaded the libpng, loadpng and zlib and still can't get this to work. Now I'm struggling with the actual compiler. I'm getting all these neat linker errors, which basically means I've got the files pooply linked...

Downloaded them through Dev-cpp's package downloader. Was the easiest way to find and install them I guess.

Like I said, I have a new problem. Tried to run the example program from loadpng examples (which come with the zip file when you download it from http://tjaden.strangesoft.net/loadpng/ ) and I get linker errors:

Compile log said:

Compiler: Default compiler
Building Makefile: "C:\Progs\Dev-Cpp\Harjotukset\Kokeiluja\PNG Try\Makefile.win"
Executing make...
make.exe -f "C:\Progs\Dev-Cpp\Harjotukset\Kokeiluja\PNG Try\Makefile.win" all
gcc.exe loadpng.o regpng.o savepng.o exalpha.o -o "png_allegro_test.exe" -L"C:/Progs/Dev-Cpp/lib" -mwindows -lalleg

loadpng.o(.text+0x70):loadpng.c: undefined reference to `png_get_io_ptr'
loadpng.o(.text+0xa4):loadpng.c: undefined reference to `png_error'
loadpng.o(.text+0xef):loadpng.c: undefined reference to `png_sig_cmp'
loadpng.o(.text+0x132):loadpng.c: undefined reference to `png_read_info'
loadpng.o(.text+0x186):loadpng.c: undefined reference to `png_get_IHDR'

loadpng.o(.text+0x191):loadpng.c: undefined reference to `png_set_packing'
loadpng.o(.text+0x1ae):loadpng.c: undefined reference to `png_set_expand'
loadpng.o(.text+0x1c8):loadpng.c: undefined reference to `png_get_valid'
loadpng.o(.text+0x1d7):loadpng.c: undefined reference to `png_set_tRNS_to_alpha'
loadpng.o(.text+0x1f5):loadpng.c: undefined reference to `png_set_strip_16'

loadpng.o(.text+0x214):loadpng.c: undefined reference to `png_set_gray_to_rgb'

loadpng.o(.text+0x253):loadpng.c: undefined reference to `png_get_sRGB'
loadpng.o(.text+0x276):loadpng.c: undefined reference to `png_set_gamma'
loadpng.o(.text+0x294):loadpng.c: undefined reference to `png_get_gAMA'
loadpng.o(.text+0x2b7):loadpng.c: undefined reference to `png_set_gamma'
loadpng.o(.text+0x2d8):loadpng.c: undefined reference to `png_set_gamma'

loadpng.o(.text+0x2e3):loadpng.c: undefined reference to `png_set_interlace_handling'
loadpng.o(.text+0x2fb):loadpng.c: undefined reference to `png_read_update_info'
loadpng.o(.text+0x341):loadpng.c: undefined reference to `png_get_PLTE'
loadpng.o(.text+0x47b):loadpng.c: undefined reference to `png_get_rowbytes'
loadpng.o(.text+0x57a):loadpng.c: undefined reference to `png_set_bgr'
loadpng.o(.text+0x5ce):loadpng.c: undefined reference to `png_read_row'
loadpng.o(.text+0x621):loadpng.c: undefined reference to `png_read_end'
loadpng.o(.text+0x6ca):loadpng.c: undefined reference to `png_create_read_struct'
loadpng.o(.text+0x6ea):loadpng.c: undefined reference to `png_create_info_struct'
loadpng.o(.text+0x70e):loadpng.c: undefined reference to `png_destroy_read_struct'
loadpng.o(.text+0x743):loadpng.c: undefined reference to `png_destroy_read_struct'
loadpng.o(.text+0x766):loadpng.c: undefined reference to `png_set_read_fn'
loadpng.o(.text+0x779):loadpng.c: undefined reference to `png_set_sig_bytes'

loadpng.o(.text+0x7af):loadpng.c: undefined reference to `png_destroy_read_struct'
loadpng.o(.text+0x7cb):loadpng.c: undefined reference to `png_get_io_ptr'
loadpng.o(.text+0x7f4):loadpng.c: undefined reference to `png_error'
loadpng.o(.text+0x84d):loadpng.c: undefined reference to `png_sig_cmp'
loadpng.o(.text+0x8c1):loadpng.c: undefined reference to `png_create_read_struct'

loadpng.o(.text+0x8e1):loadpng.c: undefined reference to `png_create_info_struct'
loadpng.o(.text+0x905):loadpng.c: undefined reference to `png_destroy_read_struct'
loadpng.o(.text+0x93a):loadpng.c: undefined reference to `png_destroy_read_struct'
loadpng.o(.text+0x970):loadpng.c: undefined reference to `png_set_read_fn'
loadpng.o(.text+0x983):loadpng.c: undefined reference to `png_set_sig_bytes'
loadpng.o(.text+0x9b9):loadpng.c: undefined reference to `png_destroy_read_struct'
savepng.o(.text+0xd):savepng.c: undefined reference to `png_get_io_ptr'
savepng.o(.text+0x41):savepng.c: undefined reference to `png_error'
savepng.o(.text+0x89):savepng.c: undefined reference to `png_write_row'

savepng.o(.text+0x12b):savepng.c: undefined reference to `png_write_row'
savepng.o(.text+0x337):savepng.c: undefined reference to `png_write_row'
savepng.o(.text+0x44d):savepng.c: undefined reference to `png_write_row'
savepng.o(.text+0x4d7):savepng.c: undefined reference to `png_create_write_struct'
savepng.o(.text+0x4f0):savepng.c: undefined reference to `png_create_info_struct'
savepng.o(.text+0x534):savepng.c: undefined reference to `png_set_write_fn'
savepng.o(.text+0x56d):savepng.c: undefined reference to `png_set_compression_level'
savepng.o(.text+0x5b9):savepng.c: undefined reference to `png_set_IHDR'
savepng.o(.text+0x6b4):savepng.c: undefined reference to `png_set_PLTE'
savepng.o(.text+0x6c6):savepng.c: undefined reference to `png_write_info'
savepng.o(.text+0x748):savepng.c: undefined reference to `png_write_end'
savepng.o(.text+0x75a):savepng.c: undefined reference to `png_destroy_write_struct'
savepng.o(.text+0x784):savepng.c: undefined reference to `png_destroy_write_struct'
savepng.o(.text+0x799):savepng.c: undefined reference to `png_destroy_write_struct'
collect2: ld returned 1 exit status
make.exe: *** [png_allegro_test.exe] Error 1

Execution terminated

( EDIT #1: if it matters.. I'm trying to run the exalpha.c example, I added it to my project file along with loadpng.c, loadpng.h, regpng.c, savepng.c. )

gasp That's loads of errors.
I've set up the project as a C-project, allegro is dynamically linked... "Naturally" linking allegro statically doesn't change a thing.

I'm throwing rocks at the project linking thingie, I guess I have to add more stuff into the project->project options->parameters part...
Currently only thing sitting there is:
-lalleg

But unfortunately I can't find the info needed to fix this from the readme files.
Help? gulp

X-G
Member #856
December 2000
avatar

... what happened to libpng? (and libz?)

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Skywhy
Member #9,243
November 2007
avatar

:3 ?

Mika said:

I downloaded the libpng, loadpng and zlib and still can't get this to work.

I got them but ... errh... should I "somehow" link them to my project? Through the project->project options->parameters, I'm guessing but..

I'm really confused WHAT I should add there, there are like one gazillion(yeah, I admit it, I made this one up) files in the /lib folder. Tried peekking into other folders too...

EDIT #1:
HALLELUJA! Finally! Somehow... I knew I was after the right thing but swearing and cursing!

Anyway, like I guessed, I was missing the certain libraries from my project. And now, it's solved. The library problem I mean. Tried out dozen of different libraries and finally found the right ones :D

Added to project now:

Project->Project Options->Parameters said:

-lalleg
../../../lib/zlib.lib
../../../lib/libpng.lib

Let's see about this transparency thing now... I'll report back again when I'm done with this, did I succeed or not. And again, thanks for the patience and help.

EDIT #2:
Ok, after playing around with few images. I just basically replaced the alpha.png image in the exalpha.c file to see how it showed off my shiny gfx and well.. It shows them as I wan't them to be shown. But noticed ONE minor thing. The pink is no longer "transparent" color, not that it matters but just wondering. The magic pink shows as black now. How come?

Now when I leave the sprite background TRANSPARENT .. they really are transparent, so pretty.

Hmm, so my question is, is this a problem?

In my game the "anti-aliased graphics" are a must. I don't want to see my sprites with any jawtooth/jagged or what ever edges. I need them to be smooth. Is this the way to go? I suppose it doesn't matter if I draw the sprites with PINK background or just plain transparent? If transparent is now TRANSPARENT with these settings, I'm just going to use transparent backgrounds... and since I haven't started doing any serious spriting yet so I guess it doesn't matter, right?

X-G
Member #856
December 2000
avatar

Magic magenta is only used in modes that do not have alpha channels.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Skywhy
Member #9,243
November 2007
avatar

Ah ok, I'm some what confused with all the alpha channel and yada yada stuff. Need to dig the internet for more on this matter. I feel like I'm missing out something since I don't completely "get" it.

But heyh, thanks everyone.
If there's no REAL problems with this, I guess I can start doing my sprites in PNG and with real transparent backgrounds heh. Anyway, credited every single one of you. Thought you guys deserver it.

Again, thank you. And further tips or such are always welcome if something happens to pop into mind. :) Since I really don't want to start doing all this coding and in the end after 5000 rows of code notice that this really ain't the way to do things :)

Tobias Dammers
Member #2,604
August 2002
avatar

The value in the alpha channel tells you how transparent the pixel is. If the alpha value for a given pixel is at its max (255), the destination pixel is completely overwritten; if alpha is zero, the destination remains completely intact, just like with magic pink in masked blitting. Values between the two 'mix' the two colors channel-wise, i.e. the resulting red becomes src_red * alpha + dst_red * (1-alpha), and similar for green and blue.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Skywhy
Member #9,243
November 2007
avatar

Well now, facing with sprite rotating.. hmm... I'm kinda having problems with this. What's the best way to rotate those alpha channel sprites(PNG).

I did a search and found this thread in the forum: http://www.allegro.cc/forums/thread/591315/670806#target

Decent enough, but is there a better way?

- Mika

Evert
Member #794
November 2000
avatar

Quote:

I don't suppose allegro's BMP loader has been re-written since the introduction of XP, so allegro probably can't load them.

I vaguely recall making a fix to the effect that it can some time ago. I don't know if that means it will correctly read the alpha channel, however.

Ron Ofir
Member #2,357
May 2002
avatar

Quote:

../../../lib/zlib.lib
../../../lib/libpng.lib

I think you should use -lz and -lpng instead of doing it this way, so even if you move your source files, it would still work. Try and see if it works, because I'm not sure I got the parameters right. Oh, and I think the correct order is -lalleg -lpng -lz.

Elias
Member #358
May 2000

About sprite rotation, I think kazzmir proposed a function allowing that for 4.4 - not sure what became of it.

An alternative would be using OpenGL rendering instead of the software primitives, with the added benefit of proper interpolation and anti-aliasing for your rotated sprites.

--
"Either help out or stop whining" - Evert

Skywhy
Member #9,243
November 2007
avatar

Well opengl is a bit over my head at the moment. I'm just trying to figure out how to rotate these darn things ... mrrh, BMP sprites I can rotate easily but these PNG sprites only show as black boxes after I've rotated the sprite and try to blit it to screen...

Tried doing it the way it was mentioned in the other thread and having problems with that style too :/

I guess I'll have to figure out something. I think I need to rotate those darn sprites in graphics editor and then load them up or something :( Sounds like a really BAD thing... pfft

Oh and thanks Ron Ofir, fixed that.

Paul whoknows
Member #5,081
September 2004
avatar

I "solved" the problem of rotating alpha sprites without OGL/D3D using pre-rendered sprites. See it.
Or just wait the release of Allegro 5 in December.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

Fladimir da Gorf
Member #1,565
October 2001
avatar

You could always try OpenLayer (see link below) ;)

And nice to see more Finnish developers around!

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Skywhy
Member #9,243
November 2007
avatar

Heh, thanks everyone for suggestions. Anyway, here is the code.

1int main(void)
2{
3 BITMAP *image;
4 BITMAP *rot_image;
5 BITMAP *buffer;
6 int depth = 16;
7 
8 allegro_init();
9 install_keyboard();
10 
11 set_color_depth(depth);
12 if ((set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) < 0) &&
13 (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) < 0)) {
14 allegro_message("Unable to set video mode (640x480x%d).\n", depth);
15 return 1;
16 }
17 
18 set_color_conversion(COLORCONV_NONE);
19 buffer = create_bitmap(SCREEN_W,SCREEN_H);
20 clear(buffer);
21 image = load_png("test3.png", NULL);
22 rot_image = create_bitmap(500,500);
23 clear(rot_image);
24
25 clear_to_color(rot_image,bitmap_mask_color(rot_image));
26 rotate_sprite(rot_image,image,0,0,64);
27
28 acquire_screen();
29 set_alpha_blender();
30 draw_trans_sprite(buffer, rot_image, (SCREEN_W - image->w) / 2, (SCREEN_H - image->h) / 2);
31 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
32 release_screen();
33 
34 readkey();
35 
36 return 0;
37}
38 
39END_OF_MAIN()

I didn't include the #include yada yada in the code.

Like I said, it results in a black 'rotated' sprite.. :) Oh well, I guess I'll go over the problem by using a gfx program to rotate the sprites and learn new stuff for next project. I have nothing against learning to use OpenGL along side Allegro or any other for that matter.

I'm just trying to figure this one out. I don't want to start learning TOO MUCH for this project. The game is supposed to be pretty small anyway so...

Ron Ofir
Member #2,357
May 2002
avatar

Try setting the color depth to 32. And I think that clear(rot_image) statement is pretty useless, though I guess it's taken out of context or something?

Northburns
Member #8,821
July 2007
avatar

I tried the source you posted and made a few fixes to make it show the desired image.
The angle was wrong. rotate_sprite takes a fixed-angle. While your 64 was numerically correct, it was an integer, and thus didn't work.
Paste this code after the clear(rot_image)- function call. (Added a nice rotation too, hope it helps)

1int angle=0;
2 while(!key[KEY_SPACE]) {
3 /*Took out clear-function..*/
4 rotate_sprite(rot_image,image,0,0,itofix(angle)); /* I to fix, nice one!*/
5
6 acquire_screen();
7 set_alpha_blender();
8 clear_to_color(buffer,makecol(125,125,125));
9 draw_trans_sprite(buffer, rot_image, (SCREEN_W - image->w) / 2, (SCREEN_H - image->h) / 2);
10 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
11 release_screen();
12
13 /*readkey();*/
14 angle++;
15 }
16 return 0;

And thanks Ron Ofir for pointing out the set_color_depth(), I totally missed that too.

EDIT------
Sorry, I guess I went a bit off-topic with that one.. But anyhow :)

Skywhy
Member #9,243
November 2007
avatar

What? No way!
HAHAHA! I completely over lookked the itofix for some reason... D'uh. Oh well, I don't know does it happen to anyone else, but after a while when I hit a mistake I can't clear and I become obsessed with it, I also become blind to the code. I just can't spot the mistake anymore, no matter how many times I look through it :)

Anyway, thank you guys. It worked now. And finally.. Hahah, after a long journey, I've learned something new about simple things like linking the proper librares (how else are they supposed to work with your project.. d'uh.. it's not enough if they are in the /lib folder heh) and simple things to do with the code. I don't know what I'd do without you guys :)

Oh yeah, and for further use, I'll paste the code in here once more so anyoe who might have wondered or is facing similiar problems might have some use for it...

And the clear(); is optional? I always thought it was good thing to clear before use? I guess you'll overwrite the old stuff anyway when you write in the BITMAP *whatever...

-- THANK YOU --

EDIT #1: added the whole code in one txt file to the post. if someone is having similiar problems, maybe peekking in there might help... I don't know.

EDIT #2: did what I was told to ;)

 1   2 


Go to: