Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » DirectX backbuffer copy in 5.0.6

This thread is locked; no one can reply to it. rss feed Print
DirectX backbuffer copy in 5.0.6
APrince
Member #12,698
March 2011

Hi, I tried the 5.0.6 changes that were made based on this thread. But there's yet another problem...

It seems that DX version set's a an alpha channel to some strange, when copying backbuffer to a bitmap.

I have a problem with openGL as well so I attach three images.

{"name":"605733","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/e\/be6938800620ae639c83667e508258b6.png","w":442,"h":162,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/e\/be6938800620ae639c83667e508258b6"}605733
{"name":"605734","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/c\/9c3f6c1ef5871872f60d2274681b1f8f.png","w":442,"h":162,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/c\/9c3f6c1ef5871872f60d2274681b1f8f"}605734
{"name":"605735","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/f\/5f496b018d569ddf0015d9dbcb4f5ffc.png","w":442,"h":162,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/f\/5f496b018d569ddf0015d9dbcb4f5ffc"}605735

First one is rendered using DirectX and is rendered to backbuffer and then copied out of to a bitmap and than from the bitmap back to backbuffer (which is than flipped and thus shown on the screen).

Second one is rendered the same way as the first one, but using openGL.

Third one is rendered directly to backbuffer, wich is then flipped and shown on screen (normal rendering).

The image consist of black background with the reflection effect and vertical and horizontal guidelines. On top of it there's some function rendered using multiple calls to al_draw_line.

What I would actually like to accomplish is, of course, to make the first two images look exactly the same as the third one...

Elias
Member #358
May 2000

Is the third one rendered with OpenGL or DirectX?

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

Trent Gamblin
Member #261
April 2000
avatar

Please paste a small test case.

APrince
Member #12,698
March 2011

Sorry for the late answer, for a few days I didn't have a luxury of internet connection...

Anyway I did some testing and dug up this:

1) Simple example could be ANYTHING that draws any multisampled lines. For example:

#SelectExpand
1#include <iostream> 2#include <vector> 3#include "Allegro5/allegro.h" 4#include <allegro5/allegro_image.h> 5#include <allegro5/allegro_primitives.h> 6#include <allegro5/allegro_font.h> 7#include <allegro5/allegro_ttf.h> 8 9bool as_al_init(int display_width, int display_height, ALLEGRO_DISPLAY** display, ALLEGRO_EVENT_QUEUE** event_queue){ 10 if (!al_init()){ 11 std::cerr << "Failed to initialize allegro!" << std::endl; 12 return false; 13 } 14 if (!al_install_mouse()){ 15 std::cerr << "Failed to install mouse!" << std::endl; 16 return false; 17 } 18 if (!al_install_keyboard()){ 19 std::cerr << "Failed to install keyboard!" << std::endl; 20 return false; 21 } 22 if (!display) return false; 23 al_set_new_display_flags(ALLEGRO_OPENGL); 24 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); 25 al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST); 26 if (!(*display = al_create_display(display_width,display_height))){ 27 return false; 28 } 29 30 if (!event_queue) {al_destroy_display(*display); return false;} 31 if (!(*event_queue = al_create_event_queue())){ 32 al_destroy_display(*display); 33 std::cerr << "Failed to create event queue!" << std::endl; 34 return false; 35 } 36 if (!(al_init_image_addon())){ 37 std::cerr << "Failed to initialize image addon." << std::endl; 38 al_destroy_display(*display); 39 return false; 40 } 41 if (!(al_init_primitives_addon())){ 42 std::cerr << "Failed to initialize primitives addon." << std::endl; 43 al_destroy_display(*display); 44 return false; 45 } 46 47 return true; 48} 49 50void as_al_cleanUp(ALLEGRO_DISPLAY* display, ALLEGRO_EVENT_QUEUE* event_queue){ 51 if (event_queue) al_destroy_event_queue(event_queue); 52 if (display) al_destroy_display(display); 53 54 al_shutdown_primitives_addon(); 55 al_shutdown_image_addon(); 56 al_uninstall_keyboard(); 57 al_uninstall_mouse(); 58 al_uninstall_system(); //all allegro shutdowns have to go before this one... 59} 60 61 62int main(int argc, char* argv[]) 63{ 64 ALLEGRO_DISPLAY* display = NULL; 65 ALLEGRO_EVENT_QUEUE* event_queue = NULL; 66 67 if (!as_al_init(640, 480, &display, &event_queue)) return 1; 68 69 al_clear_to_color(al_map_rgb(0,0,0)); 70 al_draw_line(210, 210, 250, 250, al_map_rgb(25,136,200), 1); 71 al_draw_line(250, 250, 280, 210, al_map_rgb(25,136,200), 1); 72 al_draw_line(280, 210, 310, 250, al_map_rgb(25,136,200), 1); 73 74 ALLEGRO_BITMAP* backbufferImage = al_get_backbuffer(display); 75 76 ALLEGRO_BITMAP* image = al_create_bitmap(400,60); 77 ALLEGRO_DISPLAY* currentDisplay = al_get_current_display(); 78 al_set_target_bitmap(image); 79 al_clear_to_color(al_map_rgb(255,255,255)); 80 al_draw_bitmap_region(backbufferImage, 200, 200, 400, 60, 0, 0, 0); 81 82 al_set_target_backbuffer(currentDisplay); 83 84 al_draw_bitmap(image, 200,140,0); 85 86 al_flip_display(); 87 88 Sleep(15000); 89 90 as_al_cleanUp(display, event_queue); 91 return 0; 92}

2) The DirectX problem was caused by this fact:

#SelectExpand
1class AAllegroBackbufferRegionGetter : public ABackbufferRegionGetter{ 2 ALLEGRO_DISPLAY* display; 3public: 4 AAllegroBackbufferRegionGetter(ALLEGRO_DISPLAY* display) : display(display){} 5 virtual void getRegion(AImage& storeTo, const ARectangle<size_t>& region){ 6 ALLEGRO_BITMAP* backbufferImage = al_get_backbuffer(display); 7 if (storeTo.getSize() != region.size){ 8 storeTo.setSize(region.size); 9 } 10 ALLEGRO_BITMAP* image = static_cast<ALLEGRO_BITMAP*> (storeTo.getRepresentedObject()); 11 ALLEGRO_DISPLAY* currentDisplay = al_get_current_display(); 12 al_set_target_bitmap(image); 13 //al_clear_to_color(al_map_rgba(0,0,0,255)); 14 //int op, src, dst; al_get_blender(&op, &src, &dst); 15 //al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE); 16 al_draw_bitmap_region(backbufferImage, region.origin.x, region.origin.y, region.size.x, region.size.y, 0, 0, 0); 17 //al_set_blender(op, src, dst); 18 al_set_target_backbuffer(currentDisplay); 19 } 20};

When I comment out those blender lines it works fine for DirectX. That means the result is identical to the image drawn to backbuffer and it even does not have the degradation as OpenGL version. The reason I included those lines was to ensure that I do not copy the alpha channel as well (for I need to have the image 100% opaque). I don't how the transparency behaves when copying, so this was my idea how to solve this (not very smart - obviously).

Anyway it is strange, that setting the blender as above, does not have any impact on OpenGL rendering... I think it should behave the same way...

Go to: