Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Redrawing smoothly while display is being resized

This thread is locked; no one can reply to it. rss feed Print
Redrawing smoothly while display is being resized
xsquid
Member #16,498
July 2016

This is a continuation of the problem that was being explored in this thread: https://www.allegro.cc/forums/thread/616674

I would like for the contents of the display to be smoothly redrawn as it's being resized. Prior to using a callback and capturing the WM_SIZING event to resize the display immediately, there was a delay before the content inside of the display matched the window size. Now that delay is gone (even though this feels like a really messy way of accomplishing that), and the next task was to fix this problem (reality vs desired): https://my.mixtape.moe/rdxqwg.webm

Setting the background brush of the window gets rid of the stuff that appears on the edges during the resize. The only downside at this point is that the display is filled with the color of the background brush every time the window changes size*, causing it to flicker. I don't know enough about how Allegro is implemented to know how to fix this.

  • I might be wrong about this. No matter what color I set the background brush to, it fills the new parts of the window with black... Along with everything else. So the display cuts to black every time the size is changed.

As per the suggestions in the previous thread I've implemented everything using an event queue, and used a user event to trigger the immediate resize:

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_image.h> 3#include <allegro5/allegro_primitives.h> 4#include <allegro5/allegro_windows.h> 5#include <algorithm> 6#include <Windows.h> 7#define USER_EVENT_TYPE 999 8 9static int neww, newh; 10ALLEGRO_EVENT_SOURCE user_event_source; 11 12bool WinProcCallback(ALLEGRO_DISPLAY* d, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT* result, void* userdata) { 13 14 if (msg == WM_SIZING) { 15 16 int oldh = neww; 17 int oldw = newh; 18 19 RECT r = *(RECT*)lparam; 20 int rw = (r.right - r.left) - 21; 21 int rh = (r.bottom - r.top) - 42; 22 23 if (oldh != rh || oldw != rw) { 24 ALLEGRO_EVENT ev; 25 ev.user.data1 = rw; 26 ev.user.data2 = rh; 27 ev.type = USER_EVENT_TYPE; 28 neww = rw; 29 newh = rh; 30 al_emit_user_event(&user_event_source, &ev, 0); 31 } 32 33 // Return true, so Allegro knows it doesn't need to do anything for this event. 34 return true; 35 36 } 37 38 // Return false, so Allegro will handle the event on its own. 39 return false; 40 41} 42 43int main() { 44 45 // Initialize Allegro and required add-ons. 46 al_init(); 47 al_init_primitives_addon(); 48 49 // Set display flags and create the display. 50 al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_RESIZABLE); 51 ALLEGRO_DISPLAY* display = al_create_display(640, 480); 52 53 // Create event queue and register event sources. 54 ALLEGRO_EVENT_QUEUE* event_queue = al_create_event_queue(); 55 al_register_event_source(event_queue, al_get_display_event_source(display)); 56 57 ALLEGRO_TIMER* timer = al_create_timer(1.0f / 60.0f); 58 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 59 al_start_timer(timer); 60 61 al_init_user_event_source(&user_event_source); 62 al_register_event_source(event_queue, &user_event_source); 63 64 // Set the background brush of the window. 65 HWND hwnd = al_get_win_window_handle(display); 66 HBRUSH brush = CreateSolidBrush(RGB(0, 0, 0)); 67 SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG)brush); 68 DeleteObject(brush); 69 70 // Add callback function. 71 al_win_add_window_callback(display, WinProcCallback, 0); 72 73 bool redraw = false; 74 while (true) { 75 76 ALLEGRO_EVENT ev; 77 al_wait_for_event(event_queue, &ev); 78 79 switch (ev.type) { 80 81 case USER_EVENT_TYPE: 82 al_resize_display(display, ev.user.data1, ev.user.data2); 83 84 case ALLEGRO_EVENT_DISPLAY_RESIZE: 85 al_acknowledge_resize(display); 86 redraw = true; 87 break; 88 89 case ALLEGRO_EVENT_TIMER: 90 redraw = true; 91 break; 92 93 } 94 95 // Redraw the display contents. 96 if (redraw && al_is_event_queue_empty(event_queue)) { 97 98 al_clear_to_color(al_map_rgb(0, 0, 0)); 99 float w = (std::min)(al_get_display_width(display), al_get_display_height(display)); 100 float x = al_get_display_width(display) / 2.0f - w / 2.0f; 101 float y = al_get_display_height(display) / 2.0f - w / 2.0f; 102 al_draw_filled_rectangle(x, y, x + w, y + w, al_map_rgb(192, 192, 192)); 103 al_flip_display(); 104 105 } 106 107 } 108 109 return 0; 110 111}

Does anyone know what I can do about the flickering?

Go to: