Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » al_clone_bitmap() of backbuffer gives bad results with OGL

This thread is locked; no one can reply to it. rss feed Print
al_clone_bitmap() of backbuffer gives bad results with OGL
Bruce Pascoe
Member #15,931
April 2015
avatar

I have a screenshot feature in my minisphere game engine, so that when you press F12, it takes a screenshot and saves it in the user's home directory. When I was using DX for rendering, this worked fine. Now that I'm using OpenGL, however, it doesn't work so well. Here's the code for screenshots in minisphere:

#SelectExpand
406snapshot = al_clone_bitmap(al_get_backbuffer(g_display)); 407path = al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH); 408al_append_path_component(path, "Sphere Files"); 409al_append_path_component(path, "Screenshots"); 410al_make_directory(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); 411do { 412 sprintf(filename, "SS_%s.png", rng_name(10)); 413 al_set_path_filename(path, filename); 414 pathstr = al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP); 415} while (al_filename_exists(pathstr)); 416al_save_bitmap(pathstr, snapshot); 417al_destroy_bitmap(snapshot); 418al_destroy_path(path);

Here are the screenshots side-by-side, one taken using the above code, and the other using PrintScreen and then pasted into MS Paint:
{"name":"actual.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/e\/1ebd62af7149d8dc5919d444f146eaca.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/e\/1ebd62af7149d8dc5919d444f146eaca"}actual.png{"name":"expected.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/8\/f89f7a92448bb4c87a217ba7ad169172.png","w":656,"h":519,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/8\/f89f7a92448bb4c87a217ba7ad169172"}expected.png

Make sure to enlarge them because the thumbnails are identical for some reason. ???

What it looks like is that al_clone_bitmap() is preserving the backbuffer alpha channel even though it's ignored for actual rendering. That's just a guess though.

Elias
Member #358
May 2000

If the back buffer has an alpha channel, I think it should be preserved. What you should do is create a new bitmap with the display size then al_draw_bitmap the back buffer into that bitmap.

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

Bruce Pascoe
Member #15,931
April 2015
avatar

The alpha channel has no effect on rendering, though, so for all intents and purposes it doesn't exist. And since the backbuffer serves no other purpose than to stage for rendering, it's not intuitive that if I grab its contents I get a different image than what is visible to the user.

Even so, creating a new bitmap won't help me, will it? I'll still end up copying the alpha channel over to the new image. Unless there's a way to create bitmap with no alpha channel. I never remember seeing such an option.

Elias
Member #358
May 2000

If you draw the bitmap the alpha channel is blended, so you just have to use a blend mode where the output is not affected. You also can create a bitmap without alpha, and also a back buffer without alpha.

I don't know why opengl uses a back buffer with alpha by default - that probably should be changed.

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

Bruce Pascoe
Member #15,931
April 2015
avatar

Okay, interesting thing I found, I think I discovered a bug.

Grabbing the backbuffer like this didn't fix it:

al_store_state(&old_state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS);
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA);
snapshot = al_clone_bitmap(al_get_backbuffer(g_display));
al_restore_state(&old_state);

However, this worked:

al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_888);

So it looks like ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA is not being honored?

SiegeLord
Member #7,827
October 2006
avatar

Can you check what the format of the bitmap created by ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA is?

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

Bruce Pascoe
Member #15,931
April 2015
avatar

#SelectExpand
1al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA); 2ALLEGRO_BITMAP* snapshot = al_clone_bitmap(al_get_backbuffer(g_display)); 3int pf = al_get_bitmap_format(snapshot);

pf == 9 (ALLEGRO_PIXEL_FORMAT_ARGB_8888)

For RGB_888, I got back 12, i.e. exactly what I requested.

SiegeLord
Member #7,827
October 2006
avatar

Looks like in multiple locations in Allegro's code NO_ALPHA actually means, "don't care if it has alpha or not". Sounds like changing this will require a bit of testing.

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

Bruce Pascoe
Member #15,931
April 2015
avatar

So basically it's just an alias for PIXEL_FORMAT_ANY. Seems... redundant.

SiegeLord
Member #7,827
October 2006
avatar

It's subtly different. Either way, even if it did select the right format (XRGB_8888), it still wouldn't quite work, as XRGB means don't care whether X is alpha or not :P. The real format you want in this situation is ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, which should resolve to ALLEGRO_PIXEL_FORMAT_RGB_888. I'll probably fix the NO_ALPHA not picking XRGB, but this caveat will continue to remain.

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

Bruce Pascoe
Member #15,931
April 2015
avatar

Just for the record, the documentation says this:

ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA - Let the driver choose a format without alpha.

I'm fine with it if Allegro itself treats the flag differently, but the documentation should probably be updated in that case. ;)

Go to: