[A5] Show & Hide window/display Cross-Platform ?
SilverTES

I wonder to know if we can show and hide the display with allegro 5 functions ?

Something like this:

#SelectExpand
1ALLEGRO_DISPLAY * display[2]; // if I have 3 monitors for example ! 2 3function_to_show(display[0]); // show display[0] ! 4function_to_hide(display[1]); // hide display[1] ! 5function_to_hide(display[2]); // hide display[2] !

Have you some solution ? I can use winapi with , ShowWindow & HideWindow, but it's not very cross-platform.

EDIT : Finally, I found a solution ! ;)

create-> destroy -> create -> destroy...(bitmap & display at the same time)

Edgar Reynaldo

ShowWindow and HideWindow are better than destroying and recreating the display. :/

There are bound to be functions on the other platforms that allow you to do the same thing.

SilverTES

Refactor Code, MultiMonitor support, Allegro 5:

Window.h :

#SelectExpand
1#ifndef WINDOW_H_INCLUDED 2#define WINDOW_H_INCLUDED 3 4template <class E, class M> 5E log (E error, M msg) 6{ 7 std::cout << msg; 8 return error; 9} 10 11class Window 12{ 13 public: 14 15 Window(){} 16 virtual ~Window(){} 17 18 int init(int screenW, int screenH, int scale, const char* title) 19 { 20 if (!al_init()) 21 return log(1,"- Unable to init Allegro 5 !\n"); 22 23 if (!al_init_image_addon()) 24 return log(1,"- Unable to init Addon image !\n"); 25 26 if (!al_init_primitives_addon()) 27 return log(1,"- Unable to init Addon primitives !\n"); 28 29 if (!al_init_font_addon()) 30 return log(1,"- Unable to init Addon font !\n"); 31 32 if (!al_init_ttf_addon()) 33 return log(1,"- Unable to init Addon ttf !\n"); 34 35 if (!al_install_keyboard()) 36 return log(2,"- Unable to install Keyboard !\n"); 37 38 if (!al_install_mouse()) 39 return log(2,"- Unable to install Keyboard !\n"); 40 41 _title = title; 42 _scaleWindowed = scale; 43 _screenW = screenW; 44 _screenH = screenH; 45 _isFullScreen = false; 46 _displayAdapter = 0; 47 48 _windowDisplay = al_create_display(screenW*scale,screenH*scale); 49 _windowBuffer = al_create_bitmap(screenW,screenH); 50 51 al_set_window_title(_windowDisplay, _title); 52 setupScreen(_isFullScreen); 53 54 55 return log(0,"- Init Window ! \n"); 56 } 57 int done() 58 { 59 if (_windowBuffer != NULL) 60 al_destroy_display(_windowDisplay); 61 62 if (_windowDisplay != NULL) 63 al_destroy_bitmap(_windowBuffer); 64 65 return log(0,"- Done Window ! \n"); 66 } 67 68 int setWindow(int screenW, int screenH, int scale, const char* title, int adapter) 69 { 70 al_set_new_display_adapter(adapter); 71 _scaleWindowed = scale; 72 _windowDisplay = al_create_display(screenW*scale,screenH*scale); 73 al_set_window_title(_windowDisplay, title); 74 75 return log(0,"+++ Window Modified !\n"); 76 } 77 78 void delWindow() 79 { 80 if (_windowDisplay!=NULL) 81 al_destroy_display(_windowDisplay); 82 83 _windowDisplay = NULL; 84 } 85 86 void beginRender() const 87 { 88 al_set_target_bitmap(_windowBuffer); 89 } 90 91 void endRender() const 92 { 93 al_set_target_backbuffer(_windowDisplay); 94 al_clear_to_color(al_map_rgb(0,0,0)); 95 96 if (_isFullScreen) 97 al_draw_scaled_bitmap(_windowBuffer, 98 0,0,_screenW,_screenH, 99 _viewX,_viewY,_viewW,_viewH, 100 0); 101 else 102 al_draw_scaled_bitmap(_windowBuffer, 103 0,0,_screenW,_screenH, 104 0,0,_screenW*_scaleWindowed,_screenH*_scaleWindowed, 105 0); 106 al_flip_display(); 107 } 108 109 void switchMonitor() 110 { 111 _displayAdapter++; 112 if (_displayAdapter>al_get_num_video_adapters()-1) _displayAdapter =0; 113 delWindow(); 114 setWindow(_screenW,_screenH,_scaleWindowed,_title,_displayAdapter); 115 setupScreen(_isFullScreen); 116 } 117 118 void toggleFullScreen() 119 { 120 int activeMonitor( (currentMonitor(getDisplay())) ); 121 if (_displayAdapter != activeMonitor) 122 { 123 _displayAdapter = activeMonitor; // Set index at current Monitor ! 124 delWindow(); 125 setWindow(_screenW,_screenH,_scaleWindowed,_title,_displayAdapter); 126 } 127 setupScreen(_isFullScreen = !_isFullScreen); 128 } 129 130 void setupScreen(bool isFullScreen) 131 { 132 _isFullScreen = isFullScreen; 133 al_set_display_flag(_windowDisplay, ALLEGRO_FULLSCREEN_WINDOW, isFullScreen); 134 135 ALLEGRO_MONITOR_INFO info; 136 al_get_monitor_info(_displayAdapter, &info); 137 138 _currentMonitorW = info.x2 - info.x1; 139 _currentMonitorH = info.y2 - info.y1; 140 141 // calculate scaling factor 142 _sx = _currentMonitorW / _screenW; 143 _sy = _currentMonitorH / _screenH; 144 _scaleMax = std::min(_sx, _sy); 145 146 // calculate how much the windowBuffer should be scaled 147 _viewW = _screenW * _scaleMax; 148 _viewH = _screenH * _scaleMax; 149 _viewX = (_currentMonitorW - _viewW) / 2; 150 _viewY = (_currentMonitorH - _viewH) / 2; 151 } 152 153 int currentMonitor(ALLEGRO_DISPLAY * display) // Find the current monitor where the window is 154 { 155 for (int i(0); i<al_get_num_video_adapters(); i++) 156 { 157 ALLEGRO_MONITOR_INFO info; 158 al_get_monitor_info(i, &info); 159 160 int xWin(0); 161 int yWin(0); 162 163 al_get_window_position(display, &xWin, &yWin); 164 165 if (xWin>=info.x1 && 166 yWin>=info.y1 && 167 xWin<info.x2 && 168 yWin<info.y2) 169 return i; 170 } 171 return 0; // Main/Default monitor 172 } 173 174 void pollMouse(ALLEGRO_MOUSE_STATE &mouseState) 175 { 176 177 if (_isFullScreen) 178 { 179 _xMouse = (mouseState.x-_viewX)/ float(_currentMonitorW/_screenW); 180 _yMouse = (mouseState.y-_viewY)/ float(_currentMonitorH/_screenH); 181 } 182 else 183 { 184 _xMouse = mouseState.x/_scaleWindowed; 185 _yMouse = mouseState.y/_scaleWindowed; 186 } 187 188 if (_xMouse < 0) _xMouse = 0; 189 if (_xMouse > _screenW) _xMouse = _screenW; 190 if (_yMouse < 0) _yMouse = 0; 191 if (_yMouse > _screenH) _yMouse = _screenH; 192 } 193 194 // Getter / Setter ! 195 196 ALLEGRO_DISPLAY * getDisplay() 197 { 198 return _windowDisplay; 199 } 200 201 ALLEGRO_BITMAP * getBuffer() 202 { 203 return _windowBuffer; 204 } 205 206 207 bool isFullScreen() const 208 { 209 return _isFullScreen; 210 } 211 212 int getDisplayAdapter() const 213 { 214 return _displayAdapter; 215 } 216 void setDisplayAdapter(int displayAdapter) 217 { 218 _displayAdapter = displayAdapter; 219 } 220 int getScaleWindowed() const 221 { 222 return _scaleWindowed; 223 } 224 225 int getScaleMax() const 226 { 227 return _scaleMax; 228 } 229 int getViewX() const 230 { 231 return _viewX; 232 } 233 int getViewY() const 234 { 235 return _viewY; 236 } 237 int getViewW() const 238 { 239 return _viewW; 240 } 241 int getViewH() const 242 { 243 return _viewH; 244 } 245 246 int getScreenW() const 247 { 248 return _screenW; 249 } 250 int getScreenH() const 251 { 252 return _screenH; 253 } 254 255 int getCurrentMonitorW() const 256 { 257 return _currentMonitorW; 258 } 259 int getCurrentMonitorH() const 260 { 261 return _currentMonitorH; 262 } 263 264 float getMouseX() const 265 { 266 return _xMouse; 267 } 268 float getMouseY() const 269 { 270 return _yMouse; 271 } 272 273 protected: 274 275 // Window 276 const char* _title; 277 int _displayAdapter; 278 bool _isFullScreen; 279 int _screenW; 280 int _screenH; 281 int _scaleWindowed; 282 283 // Screen 284 int _sx; 285 int _sy; 286 int _scaleMax; 287 int _viewW; 288 int _viewH; 289 int _viewX; 290 int _viewY; 291 292 // Monitor 293 int _currentMonitorW; 294 int _currentMonitorH; 295 296 // Mouse 297 float _xMouse; 298 float _yMouse; 299 300 private: 301 302 ALLEGRO_DISPLAY * _windowDisplay; 303 ALLEGRO_BITMAP * _windowBuffer; 304}; 305#endif // WINDOW_H_INCLUDED

MultiMonitor.cpp

#SelectExpand
1#include <iostream> 2#include <vector> 3#include <memory> 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_image.h> 6#include <allegro5/allegro_primitives.h> 7#include <allegro5/allegro_windows.h> 8#include <allegro5/allegro_ttf.h> 9#include <allegro5/allegro_font.h> 10#include <allegro5/allegro_windows.h> 11 12#include "Window.h" 13 14int main() 15{ 16// --- Local Variables --- 17 const char * title("--- Multi Monitor Allegro 5 ---"); 18 int screenW(320); 19 int screenH(180); 20 int scale(4); 21 const char * fontFile("Kyrou.ttf"); 22 int fontSize(8); 23 24 ALLEGRO_FONT * mainFont(NULL); 25 ALLEGRO_MOUSE_STATE _mouseState; 26 ALLEGRO_KEYBOARD_STATE _keyState; 27 28 bool _quit(false); 29 bool _keyFullScreen(false); 30 bool _keyTabScreen(false); 31 32 Window _window; 33 34// --- Init --- 35 _window.init(screenW,screenH,scale,title); 36 37// --- Load content --- 38 mainFont = al_load_font(fontFile,fontSize,0); 39 if (!mainFont) _quit = true; 40 41// --- Begin Main loop --- 42 while (!_quit) 43 { 44 // --- Input --- 45 46 // Keyboard 47 al_get_keyboard_state(&_keyState); 48 49 if (al_key_down(&_keyState, ALLEGRO_KEY_ESCAPE)) // Keyboard <Escape> for quit ! 50 _quit=true; 51 52 if (!al_key_down(&_keyState, ALLEGRO_KEY_TAB)) _keyTabScreen = false; 53 if (!al_key_down(&_keyState, ALLEGRO_KEY_F)) _keyFullScreen = false; 54 55 56 if (al_key_down(&_keyState, ALLEGRO_KEY_TAB) && !_keyTabScreen) // Keyboard <TAB> for switch monitor ! 57 { 58 _keyTabScreen = true; 59 _window.switchMonitor(); 60 } 61 if (al_key_down(&_keyState, ALLEGRO_KEY_F) && !_keyFullScreen) // Keyboard <F> to enter fullscreen ! 62 { 63 _keyFullScreen = true; 64 _window.toggleFullScreen(); 65 } 66 67 // Mouse 68 al_get_mouse_state(&_mouseState); 69 _window.pollMouse(_mouseState); 70 71 // --- Render --- 72 73 _window.beginRender(); 74 { 75 al_clear_to_color(al_map_rgb(25,30,50)); 76 77 int _windowX(0); 78 int _windowY(0); 79 80 al_get_window_position(_window.getDisplay(), &_windowX, &_windowY); 81 82 int _windowW(al_get_display_width(_window.getDisplay())); 83 int _windowH(al_get_display_height(_window.getDisplay())); 84 85 al_draw_textf(mainFont, al_map_rgb(25,250,200), 200, 2, 0, 86 "_isFullScreen : %i", _window.isFullScreen()); 87 88 al_draw_textf(mainFont, al_map_rgb(25,250,200), 200, 22, 0, 89 "_viewX : %i", _window.getViewX() ); 90 91 al_draw_textf(mainFont, al_map_rgb(25,250,200), 200, 32, 0, 92 "_viewY : %i", _window.getViewY() ); 93 94 al_draw_textf(mainFont, al_map_rgb(25,250,200), 200, 42, 0, 95 "_scaleMax : %i", _window.getScaleMax() ); 96 97 al_draw_textf(mainFont, al_map_rgb(25,250,200), 200, 52, 0, 98 "_viewW : %i", _window.getViewW() ); 99 al_draw_textf(mainFont, al_map_rgb(25,250,200), 200, 62, 0, 100 "_viewH : %i", _window.getViewH() ); 101 102 al_draw_textf(mainFont, al_map_rgb(205,250,200), 4, 2, 0, 103 "currentMonitor : %i", _window.currentMonitor(_window.getDisplay())); 104 105 al_draw_textf(mainFont, al_map_rgb(205,250,200), 4, 12, 0, 106 "_displayAdapter : %i", _window.getDisplayAdapter()); 107 108 al_draw_textf(mainFont, al_map_rgb(250,120,50), 4, 36, 0, 109 "Window Pos : %i , %i", _windowX, _windowY); 110 111 al_draw_textf(mainFont, al_map_rgb(0,250,250), 4, 46, 0, 112 "Window Size : %i , %i", _windowW, _windowH); 113 114 al_draw_textf(mainFont, al_map_rgb(50,150,250), 4, 106, 0, 115 "Mouse Pos : %i , %i", int(_window.getMouseX()), int(_window.getMouseY())); 116 117 al_draw_line(0,_window.getMouseY()+.5, 118 screenW,_window.getMouseY()+.5, 119 al_map_rgba(55,155,100,25),0); 120 121 al_draw_line(_window.getMouseX()+.5,0, 122 _window.getMouseX()+.5,screenH, 123 al_map_rgba(55,155,100,25),0); 124 } 125 _window.endRender(); 126 127 } 128// --- End Main loop --- 129 130// --- Done --- 131 132 _window.done(); 133 al_destroy_font(mainFont); 134 135// --- Quit program ! 136 return log(0,"- Program terminated normally !\n"); 137}

You can test here : https://www.allegro.cc/files/attachment/610653

TAB to switch monitor, F for fullscreen !

Edgar Reynaldo

FWIW, Allegro would use HideWindow and ShowWindow in it's windows code, so there's no reason you shouldn't either. That's what the Win32 API is there for.

SilverTES

But when I create more one ALLEGRO_DISPLAY, one of display is very slow like 5fps !!

example something like this:

#SelectExpand
1ALLEGRO_DISPLAY * _display[2] 2... 3... 4while (_quit) 5{ 6 // update : 7 if (_switchMonitor) 8 { 9 for (int i(0); i<2; i++) 10 { 11 HWND hwnd al_get_win_window_handle(_display[i]); 12 if (i != _selectedDisplay) 13 ShowWindow (hwnd, SW_HIDE); 14 else 15 ShowWindow (hwnd, SW_SHOW); 16 } 17 } 18 ... 19 ... 20 // render : 21 ... 22 ... 23 24 al_set_target_backbuffer( _display[_selectedDisplay] ); 25 al_flip_display(); 26}

Thread #616620. Printed from Allegro.cc