[OL] invisible bitmap handling
imaxcs

Hi!

OpenLayer is a great library, but to me, it still has some quirks which make it unusable for some tasks. On of them has to do with the handling of invisible bitmaps. Please have a look at the following code:

1#include "tilechunkrendertest.h"
2 
3void save_screenshot(const char *path)
4{
5 BITMAP *bmp = create_bitmap(SCREEN_W,SCREEN_H);
6 if(!bmp) return;
7 unsigned char *buff = new unsigned char[4*SCREEN_W*SCREEN_H];
8 if(!buff)
9 {
10 destroy_bitmap(bmp);
11 return;
12 }
13 
14 glReadPixels(0,0,SCREEN_W,SCREEN_H,GL_RGBA,GL_UNSIGNED_BYTE,buff);
15 
16 int y;
17 for(y=0;y<SCREEN_H;y++)
18 memcpy(bmp->line[y],buff+4*SCREEN_W*(SCREEN_H-1-y),4*SCREEN_W);
19 
20 save_bitmap(path,bmp,NULL);
21 
22 destroy_bitmap(bmp);
23 delete buff;
24}
25 
26 
27int main(void)
28{
29 Setup::SetupProgram();
30 
31 Settings::StoreMemoryBitmaps(true);
32 
33 Setup::SetupScreen(800, 600, WINDOWED);
34 
35 set_color_depth(32);
36 
37 Settings::SetAntialiasing(true);
38 
39 Bitmap test(200, 200, Rgba::INVISIBLE);
40 
41 Canvas::SetTo(test);
42 Rect(90, 90, 20, 20).Draw(Rgba::RED);
43 
44 Canvas::SetTo(SCREEN_BACKBUF);
45 Canvas::Fill(Rgba::BLUE);
46 
47 test.Blit(100, 100);
48 
49 Canvas::Refresh();
50 
51 save_screenshot("out.bmp");
52 
53 return 0;
54}

(I omit the .h-file because it just includes the necessary headers)
Now, IMO, the bitmap it produces should look like the first attached picture (out_right.gif). But it looks like the second (out_wrong.gif).
It seems like when you draw to a bitmap, all invisible areas get filled with black, which is not a wanted behavior. :(

Why is that? Is there even a way to create these kind of bitmaps in Openlayer?

I need it for my game-project (the current IOTD, btw :)), because right now, I render all tiles separately. But I want to create larger tile-chunks when the map loads to reduce the number of renders. (rendering a few big bitmaps is faster than more small bitmaps). For, example, I want to always group 5x5 tiles into one bitmap.

Thanks for your help! :)

Richard Phipps

Try adding this:

 // Deal with cases where people have a screen with an alpha channel.
 Canvas::SetPixelWriteMode( COLOR_AND_ALPHA );

After your settings::SetAntiAliasing(true) line.

imaxcs

Didn't work. Still produces the same output. :(

Richard Phipps

Not sure if the created bitmap has an alpha channel.
Does:

if( test.HasAlphaChannel() ) {
  allegro_message( "Yes it does!" );
}

Show the message?

imaxcs

Yes it does!

edit: Did you try the code yourself? What do you get?

Richard Phipps

No, I haven't compiled the code.

Does adding this make any difference before blitting?
Blenders::Set( ALPHA_BLENDER );
It shouldn't do, but just checking..

imaxcs

You are right! It doesn't change anything...:(

But, nevertheless, I really appreciate your help, Richard! Thanks a lot! :)

Richard Phipps

Imaxcs, I made a new project, cut out your code and made it draw to the screen until I pressed the mouse. It works fine for me. If I change the INVISIBLE to BLACK I get the black square too.

Are you sure your screenshot save function is not causing the problem? Do you see the output on the screen?

Finally, what version of OpenLayer are you using? I use 2.0

Fladimir da Gorf
Quote:

It seems like when you draw to a bitmap, all invisible areas get filled with black, which is not a wanted behavior.

You should use the latest SVN version.

imaxcs
Quote:

Are you sure your screenshot save function is not causing the problem? Do you see the output on the screen?

No, my screenshot-function surely does work right. I can see the black square on the screen too.

Quote:

Finally, what version of OpenLayer are you using? I use 2.0

Quote:

You should use the latest SVN version.

I am using an SVN-version which is about 1 month old. Has anything changed since then?

Anyway, I use Gentoo Linux. Could it be the case that this doesn't work because of that? And I have a Nvidia Geforce MX 440 Go. Maybe that's it?

:(:(:(

Richard Phipps

I'm not using a newish SVN version and I have a Geforce 4 MX 440SE.

Any more ideas Flad?

imaxcs

Here is an even shorter version, which uses OL's save-function to create the screenshot:

1#include "tilechunkrendertest.h"
2 
3int main(void)
4{
5 Setup::SetupProgram();
6 
7 Settings::StoreMemoryBitmaps(true);
8 
9 Setup::SetupScreen(800, 600, WINDOWED);
10 
11 set_color_depth(32);
12 
13 Settings::SetAntialiasing(true);
14 
15 Bitmap test(200, 200, Rgba::INVISIBLE);
16 
17 Canvas::SetTo(test);
18 Rect(90, 90, 20, 20).Draw(Rgba::RED);
19 
20 Canvas::SetTo(SCREEN_BACKBUF);
21 Canvas::Fill(Rgba::BLUE);
22 
23 test.Blit(100, 100);
24 
25 Canvas::Refresh();
26 
27 Canvas::Save( "out.png" );
28 
29 return 0;
30}

Still, it doesn't work! :(
I will try it under Windows...

Richard Phipps

Well the old code works for me, so it sounds like it's either something in OpenLayer, AllegroGL or your gfx drivers. Does it work in full screen?

BTW: I don't think you need the set-color-depth(32) line. Does it make a difference if you remove it?

imaxcs
Quote:

Does it work in full screen?

Quote:

BTW: I don't think you need the set-color-depth(32) line. Does it make a difference if you remove it?

No, that doesn't change anything...

Quote:

Well the old code works for me, so it sounds like it's either something in OpenLayer, AllegroGL or your gfx drivers.

I just tried it under Windows and it worked. So the problem is Linux. It seems to handle these bitmaps a bit different. :o Flad?

Fladimir da Gorf

Maybe it's the OpenGL drivers then... But I'll check if there's an issue with the alpha channels...

imaxcs

Did you find something? :)

Thread #586636. Printed from Allegro.cc