Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » help: memory bitmap background image causing artifacts

This thread is locked; no one can reply to it. rss feed Print
help: memory bitmap background image causing artifacts
Pho75_
Member #12,377
November 2010

Hi all,

I'm trying to use Allegro 5.2.6 on Ubuntu 20.10
Here's a test case showing the problem I'm having.
When using a memory bitmap for a background image.
If I draw a sprite on top of it, I'm getting black boxes where I should
be seeing the background color.
It also seems to affect drawing primitives.
see attachment.

Everything works fine, if I use a video bitmap for background image.
But I wanted to use a memory bitmap because I'm going to do lots of drawing to it.

What am I doing wrong?

Thanks,
all.

#SelectExpand
1#include <iostream> 2#include <allegro5/allegro.h> 3#include <allegro5/allegro_primitives.h> 4#include <allegro5/allegro_image.h> 5 6using namespace std; 7 8int main() 9{ 10 al_init(); 11 al_init_primitives_addon(); 12 al_init_image_addon(); 13 14 auto display= al_create_display(800, 600); 15 assert(display); 16 17 // load 32-bit sprite with alpha 18 ALLEGRO_BITMAP* sprite= al_load_bitmap("test.png"); 19 assert(sprite); 20 21 // create memory bitmap background image 22 auto old_flags= al_get_new_bitmap_flags(); 23 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); 24 ALLEGRO_BITMAP* bg= al_create_bitmap(320, 240); 25 al_set_target_bitmap(bg); 26 al_clear_to_color(al_map_rgba(0,0,255,255)); 27 al_set_new_bitmap_flags(old_flags); 28 29 // draw to temp buffer 30 // it seems to be faster than scaling everything to display width 31 ALLEGRO_BITMAP* tmp= al_create_bitmap(320, 240); 32 al_set_target_bitmap(tmp); 33 al_clear_to_color(al_map_rgb(0,0,0)); 34 al_draw_bitmap(bg, 0, 0, 0); 35 al_draw_line(0,0,100,100, al_map_rgb(255,0,0), 0); 36 al_draw_bitmap(sprite, 0, 0, 0); 37 38 // scale tmp buffer to display width 39 al_set_target_backbuffer(display); 40 al_draw_scaled_bitmap(tmp, 0, 0, al_get_bitmap_width(tmp), al_get_bitmap_height(tmp), 0, 0, al_get_display_width(display), al_get_display_height(display), 0); 41 al_flip_display(); 42 43 getchar(); 44 45 return 0; 46}

DanielH
Member #934
January 2001
avatar

It's doing what you told it to do.

1st bitmap is blue
2nd bitmap is black with line through it

It's drawing the black bitmap to the blue background.

You need to set the alpha channel to transparency for the black portion of the bitmap.

al_clear_color(temp, al_map_rg(0, 0, 0));
al_convert_mask_to_alpha(tmp, al_map_rgb(0, 0, 0));

Pho75_
Member #12,377
November 2010

DanielH,
Apologies, I should have attached the test.png file.
I updated my original post,

1.
you can see that test.png does have transparency for the background.

2.
And even if the test.png was broken (it's not), that does not explain the black boxes when drawing the line.

to clarify:
if I use a video bitmap for the background image there are no black regions.
It only happens when I use a memory bitmap.

Thanks.

Dizzy Egg
Member #10,824
March 2009
avatar

Is it necessary to do that with a memory bitmap? Wouldn't:

be more suitable?

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

DanielH
Member #934
January 2001
avatar

Yes and also this clear command also.

To your problem, I'm not sure. I'm not at home to test it.

What happens when you remove or comment out the draw line?
Do you still get the black under sprite?

Pho75_
Member #12,377
November 2010

DizzyEgg:
using al_map_rgb vs al_map_rgba does not remove the black.

DanielH:
removing the al_draw_line() call still leaves the black under the sprite.

Thanks.

Dizzy Egg
Member #10,824
March 2009
avatar

I cannot open your "test.png", I get an error.

Could you try the one I have attached, just for testing? (No pun intended).

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Pho75_
Member #12,377
November 2010

DizzyEgg
tested:
as expected, test2.png made no difference.

We can safely rule out the png file.
the sprite gets loaded to a video bitmap.
it draws fine when the background image is a video bitmap.
png file is not the problem.

Thanks.

Dizzy Egg
Member #10,824
March 2009
avatar

I have just tested using your original code and test.png (on Windows) and it works fine, must be a Ubuntu bug....

[EDIT]
Can you try to clear the display before drawing?

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Pho75_
Member #12,377
November 2010

DizzyEgg:
tried it, that made no difference.

But you bring up an interesting point. It might be an opengl bug.
Sorry I don't have windows10, but could you try and force allegro to
use opengl instead of directx and see if you can reproduce the bug on windows.
otherwise, it's looking like an allegro opengl-linux bug.

Thanks.

Dizzy Egg
Member #10,824
March 2009
avatar

I have tried using both DirectX and OpenGL.

Both work fine on Windows.

This looks like an Ubuntu specific bug; sorry I cannot be more help, but I don't have Ubuntu.

[EDIT]
One last try!! Maybe this?

#SelectExpand
1int main() 2{ 3 al_init(); 4 al_init_primitives_addon(); 5 al_init_image_addon(); 6 7 auto display= al_create_display(800, 600); 8 assert(display); 9 10 11 // create memory bitmap background image 12 auto old_flags= al_get_new_bitmap_flags(); 13 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); 14 ALLEGRO_BITMAP* bg= al_create_bitmap(320, 240); 15 al_set_target_bitmap(bg); 16 al_clear_to_color(al_map_rgba(0,0,255,255)); 17 al_set_new_bitmap_flags(old_flags); 18 19 // load 32-bit sprite with alpha 20 ALLEGRO_BITMAP* sprite= al_load_bitmap("test.png"); 21 assert(sprite); 22 23 // draw to temp buffer 24 // it seems to be faster than scaling everything to display width 25 ALLEGRO_BITMAP* tmp= al_create_bitmap(320, 240); 26 al_set_target_bitmap(tmp); 27 al_clear_to_color(al_map_rgb(0,0,0)); 28 al_draw_bitmap(bg, 0, 0, 0); 29 al_draw_line(0,0,100,100, al_map_rgb(255,0,0), 0); 30 al_draw_bitmap(sprite, 0, 0, 0); 31 32 // scale tmp buffer to display width 33 al_set_target_backbuffer(display); 34 al_draw_scaled_bitmap(tmp, 0, 0, al_get_bitmap_width(tmp), al_get_bitmap_height(tmp), 0, 0, al_get_display_width(display), al_get_display_height(display), 0); 35 al_flip_display(); 36 37 getchar(); 38 39 return 0; 40}

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Pho75_
Member #12,377
November 2010

nope, changing the order made no difference.
Thanks.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

The memory bitmap you are creating may not have an alpha channel.

Try setting the new bitmap format before creating it.

al_set_new_bitmap_format

Make sure you select a format with an alpha channel.

Pho75_
Member #12,377
November 2010

Edgar:
It's not drawing the sprite to the memory bitmap(bg), it's drawing to the temporary-buffer(tmp) which is a video bitmap.

Peter Hull
Member #1,136
March 2001

I checked on Debian (which has 5.2.4 packaged) and also with current git HEAD, both were OK.
Could be Ubuntu specific I suppose.

IIUC you are saying that merely drawing a memory bitmap (bg) to a display causes it to produce artifacts when you later draw primitives onto it.

What happens if you skip the 'tmp' part and draw directly to the window's display?
Also what if you al_save_bitmap the 'tmp' bitmap, is that also corrupted?

Pho75_
Member #12,377
November 2010

Peter,

IIUC you are saying that merely drawing a memory bitmap (bg) to a display causes it to produce artifacts when you later draw primitives onto it.

merely drawing a memory bitmap to a staging video bitmap, produces the artifacts for subsequent drawing of images/lines.

>What happens if you skip the 'tmp' part and draw directly to the window's display?
it works fine if I skip tmp, and draw straight to the display backbuffer.
it works fine if bg is a video bitmap.

Quote:

Also what if you al_save_bitmap the 'tmp' bitmap, is that also corrupted?

tested: yes, the output image via al_save_bitmap also has the artifacts.

Thanks.

SiegeLord
Member #7,827
October 2006
avatar

Looks like a driver bug, but I don't really get what the mechanism would be. When bg is drawn to tmp, tmp is locked READWRITE, and all the pixels are drawn in software. I don't have an explanation why the blocks only appear after the sprite and line are drawn. I'd be curious what the pixels in tmp look like after bg is drawn.

I'd avoid using memory bitmaps, and instead do al_lock_bitmap on bg before calling your `al_put_pixel`'s.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Pho75_
Member #12,377
November 2010

Siegelord:

SiegeLord said:

I'd avoid using memory bitmaps, and instead do al_lock_bitmap on bg before calling your `al_put_pixel`'s.

I originally started with a video bitmap for bg and performance with al_lock_bitmap and al_get_pixel/al_put_pixel was horrible.

As a work-around:
I ended up creating another buffer just to copy bg to video-bitmap.
That way I can use all video bitmaps in the final draw.
I hate to waste memory, but my game is low-res, so no matter.

I'm good now.
I'll close the issue on github.

Thanks to everyone for the help.

Go to: