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 | |
| 3 | void 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 | |
| 27 | int 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!
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.
Didn't work. Still produces the same output.
Not sure if the created bitmap has an alpha channel.
Does:
if( test.HasAlphaChannel() ) { allegro_message( "Yes it does!" ); }
Show the message?
Yes it does!
edit: Did you try the code yourself? What do you get?
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..
You are right! It doesn't change anything...:(
But, nevertheless, I really appreciate your help, Richard! Thanks a lot!
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
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.
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.
Finally, what version of OpenLayer are you using? I use 2.0
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?


I'm not using a newish SVN version and I have a Geforce 4 MX 440SE.
Any more ideas Flad?
Here is an even shorter version, which uses OL's save-function to create the screenshot:
| 1 | #include "tilechunkrendertest.h" |
| 2 | |
| 3 | int 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...
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?
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?
No, that doesn't change anything...
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.
Flad?
Maybe it's the OpenGL drivers then... But I'll check if there's an issue with the alpha channels...
Did you find something?