[A5] Drawing primitives to sub-bitmaps causes erroneous behavior
X-G

The scenario, pseudo-like:

set_target_bitmap(create_sub_bitmap(somebitmap))
draw_some_stuff()
draw_filled_rectangle()
draw_some_more_stuff()

When I do this, everything in the same frame after the primitive is drawn as if the sub-bitmap originated at (0, 0) rather than wherever it originates. In other words, half the stuff or so on screen ends up massively offset. xofs and yofs in the ALLEGRO_BITMAP structure are still correct, however. It does appear to draw to the correct parent bitmap (i.e. somebitmap).

If I remove the call to draw_filled_rectangle(), everything works correctly, so this surely cannot be an issue in my code.

Suggestions?

APPEND: Surrounding the primitive draw call with al_store_state(&st, ALLEGRO_STATE_TRANSFORM); causes the error to disappear, so the primitive rendering is apparently doing something inappropriate to the transforms.

Matthew Leverton

Sounds like a bad bug... Is there any primitive specifically that triggers the behavior?

Edit: I'm unable to reproduce it using a small test program on Windows with D3D or OpenGL. What types of bitmaps are you working with? Backbuffer, memory, etc.

SiegeLord

I'm having trouble reproducing it as well. Here's the test code I used:

#SelectExpand
1#include <allegro5/allegro5.h> 2#include <allegro5/allegro_direct3d.h> 3#include <allegro5/allegro_opengl.h> 4#include <allegro5/allegro_primitives.h> 5 6int main() 7{ 8 al_init(); 9 al_init_primitives_addon(); 10 al_install_keyboard(); 11 12 al_set_new_display_flags(ALLEGRO_DIRECT3D); 13 14 ALLEGRO_DISPLAY *disp = al_create_display(800, 600); 15 ALLEGRO_BITMAP* bmp = al_create_bitmap(800, 600); 16 ALLEGRO_BITMAP* sub_bmp = al_create_sub_bitmap(bmp, 100, 100, 100, 100); 17 ALLEGRO_BITMAP* square = al_create_bitmap(50, 50); 18 19 al_set_target_bitmap(square); 20 al_clear_to_color(al_map_rgb_f(0, 0, 1)); 21 al_set_target_bitmap(al_get_backbuffer(disp)); 22 23 ALLEGRO_KEYBOARD_STATE state; 24 while(!al_key_down(&state, ALLEGRO_KEY_ESCAPE)) 25 { 26 al_get_keyboard_state( &state ); 27 28 /* Clear large bitmap */ 29 al_set_target_bitmap(bmp); 30 al_clear_to_color(al_map_rgb_f(0, 0, 0)); 31 32 /* Draw to sub-bitmap */ 33 al_set_target_bitmap(sub_bmp); 34 /* Primitives call */ 35 al_draw_filled_rectangle(0, 0, 50, 50, al_map_rgb_f(1, 0, 0)); 36 /* This call should be drawn in different spot than the above one */ 37 al_draw_bitmap(square, 0, 0, 0); 38 39 al_set_target_bitmap(al_get_backbuffer(disp)); 40 al_draw_bitmap(bmp, 0, 0, 0); 41 42 al_flip_display(); 43 } 44 45 return 0; 46}

X-G

Aside from the backbuffer provided by Allegro, I have a separate bitmap that is 1/4 the size of the backbuffer (256x240 vs. 512x480). I then have a sub-bitmap inside this second bitmap, which is 256x244 and offset by 8 on the y-axis. I don't know if it matters, but there is then a clipping rectangle in place on top of this, but in this case it equals the size of the 256x244 sub-bitmap.

Then I draw some bitmaps, then the filled rectangle, then some more bitmaps. Finally the larger bitmap is draw_scaled to the real backbuffer. Then I flip. The second batch of bitmaps is drawn 8 pixels above the first. The exact distance changes if I change where the sub-bitmap starts, along both the X and Y axes.

I only tried with filled and stroked rectangles, but it happens for both of those.

Matthew Leverton
X-G said:

I then have a sub-bitmap inside this second bitmap, which is 256x244

I assume you mean 256x224. But still I cannot duplicate your behavior.

However, it looks like OpenGL totally ignores the clipping on a sub bitmap. Using the D3D driver, I get results I expect when clipping a sub bitmap. On OpenGL, it's as if the clipping rectangle was never set.

Update: The patch here might help, if this was somehow related to the clipping not being set.

X-G

Yes, I meant 256x224. I forgot to check last night, but I don't think this is a clipping issue. The bitmaps are literally offset, not inappropriately clipped. I don't know if I'm using the OpenGL driver; whatever is the default on Windows 7.

I'll try and cook up a smaller reproduction sample...

Matthew Leverton

If it's particular to D3D or OpenGL you can easily find out:

#include <allegro5/allegro_direct3d.h>
#include <allegro5/allegro_opengl.h>

al_set_new_display_flags(ALLEGRO_OPENGL);
// al_set_new_display_flags(ALLEGRO_DIRECT3D);

Thread #605793. Printed from Allegro.cc