Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Question about sprites and masking

This thread is locked; no one can reply to it. rss feed Print
Question about sprites and masking
FreeCastle
Member #7,724
September 2006

After setting the display mode and so on, I load a bitmap with the following code:
BITMAP* tmp = load_bitmap("sprite.bmp",NULL);
This bitmap is a very simple one, which is just a red circle with the magic pink all around. If I try to draw this image through a normal blit I see the whole bitmap as expected on my screen (also with the magic pink).
But when I try to draw this as a sprite I get just a grey box instead of my circle.
Here is the code for it ( I also tried it with masked_blit):
draw_sprite(screen,tmp,0,0);

Then I did a forum search and found a thread with a similar problem. So I changed my code to something like this:

set_color_conversion(COLORCONV_TOTAL | COLORCONV_KEEP_TRANS);

BITMAP* tmp = load_bitmap("sprite.bmp",NULL);
BITMAP* image = create_video_bitmap(tmp->w,tmp->h);
int c = bitmap_mask_color(tmp);
clear_to_color(image,c);
blit(tmp,image,0,0,0,0,tmp->w,tmp->h);
destroy_bitmap(tmp);

draw_sprite(screen,image,0,0);

With exactly these lines it works as it should. But I want to know why ? ;) I used Allegro time ago and I remember that I didn't have to do something like this at that time. Maybe there are also other ways ?

Another Question: Is it good to create the sprites in video memory as I did in the above code or should I create them in normal memory ?

P.S. Do you know why I can't reply on my other started topic ? http://www.allegro.cc/forums/thread/587370
I wanted to add something but I can't :(

Richard Phipps
Member #1,632
November 2001
avatar

The reason that video memory is being used is that some gfx cards can blit from video memory to video memory very fast, gaining a considerable speed boost over normal memory. From the manual:

Quote:

If the GFX_HW_VRAM_BLIT_MASKED bit in the gfx_capabilities flag is set, the current driver supports hardware accelerated sprite drawing when the source image is a video memory bitmap or a sub-bitmap of the screen. This is extremely fast, so when this flag is set it may be worth storing some of your more frequently used sprites in an offscreen portion of the video memory.

Warning: if the hardware acceleration flag is not set, draw_sprite() will not work correctly when used with a sprite image in system or video memory so the latter must be a memory bitmap.

It sounds like your grey problems were due to the sprite and the screen being different colour depths. draw_sprite doesn't do proper colour conversion, whereas the blit in the code you posted above does. See the manual for draw_sprite:

draw_sprite

Don Freeman
Member #5,110
October 2004
avatar

When do you call set_color_depth()? I use the following and it works fine for me:

1 //////////////////////////////////////////////////////////////////////////////////////////////
2 allegro_init();
3 set_color_depth(32);
4 set_gfx_mode(GFX_DIRECTX_WIN,500,500,0,0);
5 set_color_conversion(COLORCONV_TOTAL);
6 //////////////////////////////////////////////////////////////////////////////////////////////
7 install_timer();
8 install_keyboard();
9 install_mouse();
10 //////////////////////////////////////////////////////////////////////////////////////////////
11 BITMAP *bmp = create_bitmap(SCREEN_W,SCREEN_H);
12 BITMAP *sprite = load_bitmap("Sprite.bmp",NULL);
13 //////////////////////////////////////////////////////////////////////////////////////////////
14 while ( !keypressed() )
15 {
16 draw_sprite(bmp,sprite,x,y);
17 blit(bmp,screen,0,0,0,0,bmp->w,bmp->h);
18 clear_bitmap(bmp);
19 }
20 //////////////////////////////////////////////////////////////////////////////////////////////
21 destroy_bitmap(bmp);
22 destroy_bitmap(sprite);
23 return 0;
24 //////////////////////////////////////////////////////////////////////////////////////////////

About memory/video bitmaps:
Depending on you harware, memory bitmaps may even be faster than video bitmaps...also, you can't do some things with video bitmaps like with memory bitmaps.

About replying:
You where the last one to post...so it won't let you. I will 'bump' so you can add something else...

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

gnolam
Member #2,030
March 2002
avatar

Quote:

set_gfx_mode(GFX_DIRECTX_WIN,500,500,0,0);

Not only are you unnecessarily using a platform-dependant driver, you are trying to set a 500x500 resolution... without error checking. Yikes.

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

FreeCastle
Member #7,724
September 2006

Quote:

It sounds like your grey problems were due to the sprite and the screen being different colour depths. draw_sprite doesn't do proper colour conversion, whereas the blit in the code you posted above does. See the manual for draw_sprite:

Yes I think this is the reason. But I don't know how to handle it. I created e.g. a simple bitmap with MS-Paint and then saved it as a 24-bit bitmap (thats the only true-color option). Then in my allegro app I also set the color depth to 24 (later 32). But I don't get the correct image represented :(
I already looked at the manual, but I didn't find a solution for that...

About that video/memory bitmap thing:
In the code that I posted I use a video bitmap to store the sprite. And thats my ONLY option! If I use a normal memory bitmap I get the same problem again. That's really shit. Maybe it's no problem on my system to put all sprites in video bitmaps, but maybe there are other systems with much lesser memory...

@Freeman
Thanks for replying

Don Freeman
Member #5,110
October 2004
avatar

gnolam:
'You're bustin' my balls here....', I was just trying to show a quick and simple way to do it...OF COURSE you would add error checking...I left it out for clarity. Have you ever read programming books? I believe they are the same way... And considering I ONLY use windows, it would be fair to assume that I would only know about WINDOWS stuff, which would be fine in this case considering HE is using windows as well... :P

FreeCastle:
Try my code sample above and see if it works for you...

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

William Labbett
Member #4,486
March 2004
avatar

sorry to hijack the thread but i've read it and it made me wonder what the difference between a system bitmap and a memory bitmap is ?

maybe others might learn seomething here too

Derezo
Member #1,666
April 2001
avatar

"He who controls the stuffing controls the Universe"

FreeCastle
Member #7,724
September 2006

Arrrr...
I changed my code according to yours Freeman.
The only difference to mine was, that I called the set_color_depth()-function after the set_gfx_mode() function and not before, like in your code. Now it works as it should :)
Maybe I am just too stupid to read the manual correctly, but I didn't see it clearly that the set_color_depth() function should be called always before the set_gfx_mode() function.
Anyway... thank you very much for your help

Evert
Member #794
November 2000
avatar

Quote:

And considering I ONLY use windows

You're aware, I hope, that GFX_AUTODETECT_WINDOWED gives you GFX_DIRECTX_WIN in Windows by default? SO even if you're only interested in Windows, there is no valid reason for not using GFX_AUTODETECT_WINDOWED.

Quote:

I didn't see it clearly that the set_color_depth() function should be called always before the set_gfx_mode() function.

man set_gfx_mode said:

The color depth of the graphic mode has to be specified before calling this function with set_color_depth().

man set_color_depth said:

Sets the pixel format to be used by subsequent calls to set_gfx_mode() and create_bitmap().

Seems pretty clear to me... ;)
It's also fairly obvious when you stop to think about it: set_gfx_mode() creates the window given some colour depth. To change that, you have to tell it to use a different one from whatever its current default is.

Go to: