99// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
1010// [ ] Platform: Missing gamepad support.
1111
12- // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
12+ // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
1313// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
1414// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
1515// Read online: https://github.com/ocornut/imgui/tree/master/docs
1616
1717// CHANGELOG
1818// (minor and older changes stripped away, please see git history for details)
19+ // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
1920// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
2021// 2021-02-18: Change blending equation to preserve alpha in output buffer.
2122// 2020-08-10: Inputs: Fixed horizontal mouse wheel direction.
5354#pragma warning (disable: 4127) // condition expression is constant
5455#endif
5556
56- // Data
57- static ALLEGRO_DISPLAY* g_Display = NULL ;
58- static ALLEGRO_BITMAP* g_Texture = NULL ;
59- static double g_Time = 0.0 ;
60- static ALLEGRO_MOUSE_CURSOR* g_MouseCursorInvisible = NULL ;
61- static ALLEGRO_VERTEX_DECL* g_VertexDecl = NULL ;
62- static char * g_ClipboardTextData = NULL ;
57+ // Allegro Data
58+ struct ImGui_ImplAllegro5_Data
59+ {
60+ ALLEGRO_DISPLAY* Display;
61+ ALLEGRO_BITMAP* Texture;
62+ double Time;
63+ ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible;
64+ ALLEGRO_VERTEX_DECL* VertexDecl;
65+ char * ClipboardTextData;
66+
67+ ImGui_ImplAllegro5_Data () { memset (this , 0 , sizeof (*this )); }
68+ };
69+
70+ // Wrapping access to backend data (to facilitate multiple-contexts stored in io.BackendPlatformUserData)
71+ static ImGui_ImplAllegro5_Data* g_Data;
72+ static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_CreateBackendData () { IM_ASSERT (g_Data == NULL ); g_Data = IM_NEW (ImGui_ImplAllegro5_Data); return g_Data; }
73+ static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_GetBackendData () { return ImGui::GetCurrentContext () != NULL ? g_Data : NULL ; }
74+ static void ImGui_ImplAllegro5_DestroyBackendData () { IM_DELETE (g_Data); g_Data = NULL ; }
6375
6476struct ImDrawVertAllegro
6577{
@@ -96,6 +108,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
96108 return ;
97109
98110 // Backup Allegro state that will be modified
111+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
99112 ALLEGRO_TRANSFORM last_transform = *al_get_current_transform ();
100113 ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform ();
101114 int last_clip_x, last_clip_y, last_clip_w, last_clip_h;
@@ -161,7 +174,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
161174 // Draw
162175 ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID ();
163176 al_set_clipping_rectangle (pcmd->ClipRect .x - clip_off.x , pcmd->ClipRect .y - clip_off.y , pcmd->ClipRect .z - pcmd->ClipRect .x , pcmd->ClipRect .w - pcmd->ClipRect .y );
164- al_draw_prim (&vertices[0 ], g_VertexDecl , texture, idx_offset, idx_offset + pcmd->ElemCount , ALLEGRO_PRIM_TRIANGLE_LIST);
177+ al_draw_prim (&vertices[0 ], bd-> VertexDecl , texture, idx_offset, idx_offset + pcmd->ElemCount , ALLEGRO_PRIM_TRIANGLE_LIST);
165178 }
166179 idx_offset += pcmd->ElemCount ;
167180 }
@@ -177,6 +190,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
177190bool ImGui_ImplAllegro5_CreateDeviceObjects ()
178191{
179192 // Build texture atlas
193+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
180194 ImGuiIO& io = ImGui::GetIO ();
181195 unsigned char * pixels;
182196 int width, height;
@@ -210,54 +224,61 @@ bool ImGui_ImplAllegro5_CreateDeviceObjects()
210224
211225 // Store our identifier
212226 io.Fonts ->SetTexID ((void *)cloned_img);
213- g_Texture = cloned_img;
227+ bd-> Texture = cloned_img;
214228
215229 // Create an invisible mouse cursor
216230 // Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
217231 ALLEGRO_BITMAP* mouse_cursor = al_create_bitmap (8 , 8 );
218- g_MouseCursorInvisible = al_create_mouse_cursor (mouse_cursor, 0 , 0 );
232+ bd-> MouseCursorInvisible = al_create_mouse_cursor (mouse_cursor, 0 , 0 );
219233 al_destroy_bitmap (mouse_cursor);
220234
221235 return true ;
222236}
223237
224238void ImGui_ImplAllegro5_InvalidateDeviceObjects ()
225239{
226- if (g_Texture)
240+ ImGuiIO& io = ImGui::GetIO ();
241+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
242+ if (bd->Texture )
227243 {
228- ImGuiIO& io = ImGui::GetIO ();
229244 io.Fonts ->SetTexID (NULL );
230- al_destroy_bitmap (g_Texture );
231- g_Texture = NULL ;
245+ al_destroy_bitmap (bd-> Texture );
246+ bd-> Texture = NULL ;
232247 }
233- if (g_MouseCursorInvisible )
248+ if (bd-> MouseCursorInvisible )
234249 {
235- al_destroy_mouse_cursor (g_MouseCursorInvisible );
236- g_MouseCursorInvisible = NULL ;
250+ al_destroy_mouse_cursor (bd-> MouseCursorInvisible );
251+ bd-> MouseCursorInvisible = NULL ;
237252 }
238253}
239254
240255#if ALLEGRO_HAS_CLIPBOARD
241256static const char * ImGui_ImplAllegro5_GetClipboardText (void *)
242257{
243- if (g_ClipboardTextData)
244- al_free (g_ClipboardTextData);
245- g_ClipboardTextData = al_get_clipboard_text (g_Display);
246- return g_ClipboardTextData;
258+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
259+ if (bd->ClipboardTextData )
260+ al_free (bd->ClipboardTextData );
261+ bd->ClipboardTextData = al_get_clipboard_text (bd->Display );
262+ return bd->ClipboardTextData ;
247263}
248264
249265static void ImGui_ImplAllegro5_SetClipboardText (void *, const char * text)
250266{
251- al_set_clipboard_text (g_Display, text);
267+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
268+ al_set_clipboard_text (bd->Display , text);
252269}
253270#endif
254271
255272bool ImGui_ImplAllegro5_Init (ALLEGRO_DISPLAY* display)
256273{
257- g_Display = display;
274+ ImGuiIO& io = ImGui::GetIO ();
275+ IM_ASSERT (io.BackendPlatformUserData == NULL && " Already initialized a platform backend!" );
276+
277+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_CreateBackendData ();
278+ bd->Display = display;
258279
259280 // Setup backend capabilities flags
260- ImGuiIO& io = ImGui::GetIO () ;
281+ io. BackendRendererUserData = ( void *)bd ;
261282 io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
262283 io.BackendPlatformName = io.BackendRendererName = " imgui_impl_allegro5" ;
263284
@@ -271,7 +292,7 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
271292 { ALLEGRO_PRIM_COLOR_ATTR, 0 , IM_OFFSETOF (ImDrawVertAllegro, col) },
272293 { 0 , 0 , 0 }
273294 };
274- g_VertexDecl = al_create_vertex_decl (elems, sizeof (ImDrawVertAllegro));
295+ bd-> VertexDecl = al_create_vertex_decl (elems, sizeof (ImDrawVertAllegro));
275296
276297 io.KeyMap [ImGuiKey_Tab] = ALLEGRO_KEY_TAB;
277298 io.KeyMap [ImGuiKey_LeftArrow] = ALLEGRO_KEY_LEFT;
@@ -308,18 +329,20 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
308329
309330void ImGui_ImplAllegro5_Shutdown ()
310331{
332+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
311333 ImGui_ImplAllegro5_InvalidateDeviceObjects ();
312334
313- g_Display = NULL ;
314- g_Time = 0.0 ;
335+ bd-> Display = NULL ;
336+ bd-> Time = 0.0 ;
315337
316- if (g_VertexDecl )
317- al_destroy_vertex_decl (g_VertexDecl );
318- g_VertexDecl = NULL ;
338+ if (bd-> VertexDecl )
339+ al_destroy_vertex_decl (bd-> VertexDecl );
340+ bd-> VertexDecl = NULL ;
319341
320- if (g_ClipboardTextData)
321- al_free (g_ClipboardTextData);
322- g_ClipboardTextData = NULL ;
342+ if (bd->ClipboardTextData )
343+ al_free (bd->ClipboardTextData );
344+ bd->ClipboardTextData = NULL ;
345+ ImGui_ImplAllegro5_DestroyBackendData ();
323346}
324347
325348// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
@@ -329,11 +352,12 @@ void ImGui_ImplAllegro5_Shutdown()
329352bool ImGui_ImplAllegro5_ProcessEvent (ALLEGRO_EVENT* ev)
330353{
331354 ImGuiIO& io = ImGui::GetIO ();
355+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
332356
333357 switch (ev->type )
334358 {
335359 case ALLEGRO_EVENT_MOUSE_AXES:
336- if (ev->mouse .display == g_Display )
360+ if (ev->mouse .display == bd-> Display )
337361 {
338362 io.MouseWheel += ev->mouse .dz ;
339363 io.MouseWheelH -= ev->mouse .dw ;
@@ -342,31 +366,31 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
342366 return true ;
343367 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
344368 case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
345- if (ev->mouse .display == g_Display && ev->mouse .button <= 5 )
369+ if (ev->mouse .display == bd-> Display && ev->mouse .button <= 5 )
346370 io.MouseDown [ev->mouse .button - 1 ] = (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
347371 return true ;
348372 case ALLEGRO_EVENT_TOUCH_MOVE:
349- if (ev->touch .display == g_Display )
373+ if (ev->touch .display == bd-> Display )
350374 io.MousePos = ImVec2 (ev->touch .x , ev->touch .y );
351375 return true ;
352376 case ALLEGRO_EVENT_TOUCH_BEGIN:
353377 case ALLEGRO_EVENT_TOUCH_END:
354378 case ALLEGRO_EVENT_TOUCH_CANCEL:
355- if (ev->touch .display == g_Display && ev->touch .primary )
379+ if (ev->touch .display == bd-> Display && ev->touch .primary )
356380 io.MouseDown [0 ] = (ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
357381 return true ;
358382 case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
359- if (ev->mouse .display == g_Display )
383+ if (ev->mouse .display == bd-> Display )
360384 io.MousePos = ImVec2 (-FLT_MAX, -FLT_MAX);
361385 return true ;
362386 case ALLEGRO_EVENT_KEY_CHAR:
363- if (ev->keyboard .display == g_Display )
387+ if (ev->keyboard .display == bd-> Display )
364388 if (ev->keyboard .unichar != 0 )
365389 io.AddInputCharacter ((unsigned int )ev->keyboard .unichar );
366390 return true ;
367391 case ALLEGRO_EVENT_KEY_DOWN:
368392 case ALLEGRO_EVENT_KEY_UP:
369- if (ev->keyboard .display == g_Display )
393+ if (ev->keyboard .display == bd-> Display )
370394 io.KeysDown [ev->keyboard .keycode ] = (ev->type == ALLEGRO_EVENT_KEY_DOWN);
371395 return true ;
372396 }
@@ -379,11 +403,12 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
379403 if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
380404 return ;
381405
406+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
382407 ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor ();
383408 if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
384409 {
385410 // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
386- al_set_mouse_cursor (g_Display, g_MouseCursorInvisible );
411+ al_set_mouse_cursor (bd-> Display , bd-> MouseCursorInvisible );
387412 }
388413 else
389414 {
@@ -398,27 +423,28 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
398423 case ImGuiMouseCursor_ResizeNWSE: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW; break ;
399424 case ImGuiMouseCursor_NotAllowed: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE; break ;
400425 }
401- al_set_system_mouse_cursor (g_Display , cursor_id);
426+ al_set_system_mouse_cursor (bd-> Display , cursor_id);
402427 }
403428}
404429
405430void ImGui_ImplAllegro5_NewFrame ()
406431{
407- if (!g_Texture)
432+ ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData ();
433+ if (!bd->Texture )
408434 ImGui_ImplAllegro5_CreateDeviceObjects ();
409435
410436 ImGuiIO& io = ImGui::GetIO ();
411437
412438 // Setup display size (every frame to accommodate for window resizing)
413439 int w, h;
414- w = al_get_display_width (g_Display );
415- h = al_get_display_height (g_Display );
440+ w = al_get_display_width (bd-> Display );
441+ h = al_get_display_height (bd-> Display );
416442 io.DisplaySize = ImVec2 ((float )w, (float )h);
417443
418444 // Setup time step
419445 double current_time = al_get_time ();
420- io.DeltaTime = g_Time > 0.0 ? (float )(current_time - g_Time ) : (float )(1 .0f / 60 .0f );
421- g_Time = current_time;
446+ io.DeltaTime = bd-> Time > 0.0 ? (float )(current_time - bd-> Time ) : (float )(1 .0f / 60 .0f );
447+ bd-> Time = current_time;
422448
423449 // Setup inputs
424450 ALLEGRO_KEYBOARD_STATE keys;
0 commit comments