|
[A5+OpenGL] How to render OpenGL to a bitmap |
Roy Balela
Member #16,645
March 2017
|
How to render OpenGL to a bitmap instead of display backbuffer? That's what I was going to ask you after I spent almost two days on this problem. But I managed to figure it out! Rendering to bitmap was quite simple. Just set the bitmap as target and then call the OpenGL routines. That's it! {"name":"610814","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/d\/6d11b307d6fc138cb8e3229463480532.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/d\/6d11b307d6fc138cb8e3229463480532"} But, as you can see, the polygons are being displayed in the order of drawing. 1 al_set_new_display_flags(ALLEGRO_OPENGL);
2 al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST);
Then you have to enable it manually and clear it's buffer everytime you want to redraw your scene. 1 glEnable(GL_DEPTH_TEST);
2 glClear(GL_DEPTH_BUFFER_BIT);
{"name":"610815","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/5\/2515b37b8e21ce0475047a758badd0a9.png","w":1282,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/5\/2515b37b8e21ce0475047a758badd0a9"} This corrects the depth buffer for the display backbuffer, but rendering to bitmap still doesn't work. {"name":"610816","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/9\/d9cde8e8741ee0536ef25f51f1de34fc.png","w":1282,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/9\/d9cde8e8741ee0536ef25f51f1de34fc"} A simple workaround is simply to render on the display backbuffer and then transfer to your bitmap. 1 al_set_target_backbuffer(display);
2 glViewport(0, DISPLAY_HEIGHT-BUFFER_HEIGHT, BUFFER_WIDTH, BUFFER_HEIGHT);
3 // Draw your stuff
4
5 ...
6
7 // Back to the original viewport
8 glViewport(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
9 // Need to disable depth test for Allegro drawing routines
10 glDisable(GL_DEPTH_TEST);
11 al_set_target_bitmap(buffer);
12 al_draw_bitmap(al_get_backbuffer(display), 0, 0, 0);
{"name":"610817","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/d\/2da7cfbe74d640aae7fbbafbd09f44b9.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/d\/2da7cfbe74d640aae7fbbafbd09f44b9"} This works just fine! But I still was after the answer to why depth buffer was not enabled on the bitmap itself. Also, keep in mind you cannot draw images larger than your current display size. A little bit more of search, and I found a tutorial on how to render to texture using OpenGL. 1 // Creates your bitmap
2 buffer = al_create_bitmap(BUFFER_WIDTH, BUFFER_HEIGHT);
3 if (!buffer) abort_on_error("Failed to create bitmap");
4 al_set_target_bitmap(buffer);
5 { // Creates depth buffer for the bitmap
6 GLuint buffer_depth_render;
7 glGenRenderbuffers(1, &buffer_depth_render);
8 glBindRenderbuffer(GL_RENDERBUFFER, buffer_depth_render);
9 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, BUFFER_WIDTH, BUFFER_HEIGHT);
10 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer_depth_render);
11 }
This also makes the ALLEGRO_DEPTH_SIZE option obsolete, as you are explicitly creating the buffer for the bitmap, though you should still use it if you are rendering to the backbuffer, of course. I continued my tests and ended up mixing Allegro and OpenGL drawing routines. Here is my final result. {"name":"610818","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/1\/014ae07796b6ff198e6a82dd042a408d.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/1\/014ae07796b6ff198e6a82dd042a408d"} You can download the working code, if you want to try it out. I don't know if this is the right way to do it, just that it worked for me. I'm not sure on how freeing the bitmap works, nor if I have to free the depth buffer myself. As I will be using the bitmap throughout the application lifetime, it's not a problem. Any feedback is welcome. |
SiegeLord
Member #7,827
October 2006
|
To enable the depth buffer for bitmaps you call al_set_new_bitmap_depth. Note that we haven't implemented it for Direct3D, so you'll want to make sure you force the driver to be OpenGL via the display flags. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Roy Balela
Member #16,645
March 2017
|
Sweet! Thank you very much. I was using version 5.0, the last one available on my repository, and so was the manual I was consulting. Also, one needs to add #define ALLEGRO_UNSTABLE to use the function. Here's my corrected code. |
|