@ -52,7 +52,8 @@
- Minimize setup and maintenance
- Minimize state storage on user side
- Portable , minimize dependencies , run on target ( consoles , phones , etc . )
- Efficient runtime and memory consumption ( NB - we do allocate when " growing " content - creating a window / opening a tree node for the first time , etc . - but a typical frame won ' t allocate anything )
- Efficient runtime and memory consumption ( NB - we do allocate when " growing " content e . g . creating a window , opening a tree node
for the first time , etc . but a typical frame won ' t allocate anything )
Designed for developers and content - creators , not the typical end - user ! Some of the weaknesses includes :
- Doesn ' t look fancy , doesn ' t animate
@ -90,7 +91,8 @@
READ FIRST
- Read the FAQ below this section !
- Your code creates the UI , if your code doesn ' t run the UI is gone ! = = very dynamic UI , no construction / destructions steps , less data retention on your side , no state duplication , less sync , less bugs .
- Your code creates the UI , if your code doesn ' t run the UI is gone ! = = very dynamic UI , no construction / destructions steps , less data retention
on your side , no state duplication , less sync , less bugs .
- Call and read ImGui : : ShowTestWindow ( ) for demo code demonstrating most features .
- You can learn about immediate - mode gui principles at http : //www.johno.se/book/imgui.html or watch http://mollyrocket.com/861
@ -105,25 +107,28 @@
GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE / ENGINE
- Add the Dear ImGui source files to your projects , using your preferred build system . It is recommended you build the . cpp files as part of your project and not as a library .
- Add the Dear ImGui source files to your projects , using your preferred build system .
It is recommended you build the . cpp files as part of your project and not as a library .
- You can later customize the imconfig . h file to tweak some compilation time behavior , such as integrating imgui types with your own maths types .
- See examples / folder for standalone sample applications . To understand the integration process , you can read examples / opengl2_example / because it is short ,
then switch to the one more appropriate to your use case .
- See examples / folder for standalone sample applications . To understand the integration process , you can read examples / opengl2_example / because
it is short , then switch to the one more appropriate to your use case .
- You may be able to grab and copy a ready made imgui_impl_ * * * file from the examples / .
- When using Dear ImGui , your programming IDE is your friend : follow the declaration of variables , functions and types to find comments about them .
- Init : retrieve the ImGuiIO structure with ImGui : : GetIO ( ) and fill the fields marked ' Settings ' : at minimum you need to set io . DisplaySize ( application resolution ) .
Later on you will fill your keyboard mapping , clipboard handlers , and other advanced features but for a basic integration you don ' t need to worry about it all .
- Init : retrieve the ImGuiIO structure with ImGui : : GetIO ( ) and fill the fields marked ' Settings ' : at minimum you need to set io . DisplaySize
( application resolution ) . Later on you will fill your keyboard mapping , clipboard handlers , and other advanced features but for a basic
integration you don ' t need to worry about it all .
- Init : call io . Fonts - > GetTexDataAsRGBA32 ( . . . ) , it will build the font atlas texture , then load the texture pixels into graphics memory .
- Every frame :
- In your main loop as early a possible , fill the IO fields marked ' Input ' ( e . g . mouse position , buttons , keyboard info , etc . )
- Call ImGui : : NewFrame ( ) to begin the frame
- You can use any ImGui function you want between NewFrame ( ) and Render ( )
- Call ImGui : : Render ( ) as late as you can to end the frame and finalize render data . it will call your io . RenderDrawListFn handler .
( if you don ' t need to render, you still need to call Render ( ) and ignore the callback , or call EndFrame ( ) instead . if you call neither some aspects of windows focusing / moving will appear broken . )
( Even if you don ' t render, call Render ( ) and ignore the callback , or call EndFrame ( ) instead . Otherwhise some features will break )
- All rendering information are stored into command - lists until ImGui : : Render ( ) is called .
- Dear ImGui never touches or knows about your GPU state . the only function that knows about GPU is the RenderDrawListFn handler that you provide .
- Effectively it means you can create widgets at any time in your code , regardless of considerations of being in " update " vs " render " phases of your own application .
- Effectively it means you can create widgets at any time in your code , regardless of considerations of being in " update " vs " render " phases
of your own application .
- Refer to the examples applications in the examples / folder for instruction on how to setup your code .
- A minimal application skeleton may be :
@ -131,7 +136,7 @@
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . DisplaySize . x = 1920.0f ;
io . DisplaySize . y = 1280.0f ;
io . RenderDrawListsFn = MyRenderFunction ; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data.
io . RenderDrawListsFn = MyRenderFunction ; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access render data.
// TODO: Fill others settings of the io structure later.
// Load texture atlas (there is a default font so you don't need to care about choosing a font yet)
@ -185,9 +190,16 @@
}
else
{
// Render 'pcmd->ElemCount/3' texture triangles
// The texture for the draw call is specified by pcmd->TextureId.
// The vast majority of draw calls with use the imgui texture atlas, which value you have set yourself during initialization.
MyEngineBindTexture ( pcmd - > TextureId ) ;
// We are using scissoring to clip some objects. All low-level graphics API supports it.
// If your engine doesn't support scissoring yet, you will get some small glitches (some elements outside their bounds) which you can fix later.
MyEngineScissor ( ( int ) pcmd - > ClipRect . x , ( int ) pcmd - > ClipRect . y , ( int ) ( pcmd - > ClipRect . z - pcmd - > ClipRect . x ) , ( int ) ( pcmd - > ClipRect . w - pcmd - > ClipRect . y ) ) ;
// Render 'pcmd->ElemCount/3' indexed triangles.
// By default the indices ImDrawIdx are 16-bits, you can change them to 32-bits if your engine doesn't support 16-bits indices.
MyEngineDrawIndexedTriangles ( pcmd - > ElemCount , sizeof ( ImDrawIdx ) = = 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT , idx_buffer , vtx_buffer ) ;
}
idx_buffer + = pcmd - > ElemCount ;
@ -396,21 +408,22 @@
Also make sure your orthographic projection matrix and io . DisplaySize matches your actual framebuffer dimension .
Q : I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around . .
A : Most likely you are mishandling the clipping rectangles in your render function . Rectangles provided by ImGui are defined as ( x1 = left , y1 = top , x2 = right , y2 = bottom ) and NOT as ( x1 , y1 , width , height ) .
A : You are probably mishandling the clipping rectangles in your render function .
Rectangles provided by ImGui are defined as ( x1 = left , y1 = top , x2 = right , y2 = bottom ) and NOT as ( x1 , y1 , width , height ) .
Q : Can I have multiple widgets with the same label ? Can I have widget without a label ?
A : Yes . A primer on the use of labels / IDs in Dear ImGui . .
- Elements that are not clickable , such as Text ( ) items don ' t need an ID .
- Interactive widgets require state to be carried over multiple frames ( most typically Dear ImGui often needs to remember what is the " active " widget ) .
t o do so they need a unique ID . unique ID are typically derived from a string label , an integer index or a pointer .
- Interactive widgets require state to be carried over multiple frames ( most typically Dear ImGui often needs to remember what is
t he " active " widget ) . t o do so they need a unique ID . unique ID are typically derived from a string label , an integer index or a pointer .
Button ( " OK " ) ; // Label = "OK", ID = hash of "OK"
Button ( " Cancel " ) ; // Label = "Cancel", ID = hash of "Cancel"
- ID are uniquely scoped within windows , tree nodes , etc . so no conflict can happen if you have two buttons called " OK " in two different windows
or in two different locations of a tree .
- ID are uniquely scoped within windows , tree nodes , etc . so no conflict can happen if you have two buttons called " OK "
in two different windows or in two different locations of a tree .
- If you have a same ID twice in the same location , you ' ll have a conflict :
@ -419,8 +432,8 @@
Fear not ! this is easy to solve and there are many ways to solve it !
- When passing a label you can optionally specify extra unique ID information within string itself . This helps solving the simpler collision cases .
u se " ## " to pass a complement to the ID that won ' t be visible to the end - user :
- When passing a label you can optionally specify extra unique ID information within string itself .
This helps solving the simpler collision cases . U se " ## " to pass a complement to the ID that won ' t be visible to the end - user :
Button ( " Play " ) ; // Label = "Play", ID = hash of "Play"
Button ( " Play##foo1 " ) ; // Label = "Play", ID = hash of "Play##foo1" (different from above)
@ -488,18 +501,22 @@
- When working with trees , ID are used to preserve the open / close state of each tree node .
Depending on your use cases you may want to use strings , indices or pointers as ID .
e . g . when displaying a single object that may change over time ( 1 - 1 relationship ) , using a static string as ID will preserve your node open / closed state when the targeted object change .
e . g . when displaying a list of objects , using indices or pointers as ID will preserve the node open / closed state differently . experiment and see what makes more sense !
e . g . when displaying a single object that may change over time ( dynamic 1 - 1 relationship ) , using a static string as ID will preserve your
node open / closed state when the targeted object change .
e . g . when displaying a list of objects , using indices or pointers as ID will preserve the node open / closed state differently .
experiment and see what makes more sense !
Q : How can I tell when Dear ImGui wants my mouse / keyboard inputs VS when I can pass them to my application ?
A : You can read the ' io . WantCaptureMouse ' / ' io . WantCaptureKeyboard ' / ' ioWantTextInput ' flags from the ImGuiIO structure .
- When ' io . WantCaptureMouse ' or ' io . WantCaptureKeyboard ' flags are set you may want to discard / hide the inputs from the rest of your application .
- When ' io . WantTextInput ' is set to may want to notify your OS to popup an on - screen keyboard , if available ( e . g . on a mobile phone , or console without a keyboard ) .
Preferably read the flags after calling ImGui : : NewFrame ( ) to avoid them lagging by one frame . But reading those flags before calling NewFrame ( ) is also generally ok ,
as the bool toggles fairly rarely and you don ' t generally expect to interact with either Dear ImGui or your application during the same frame when that transition occurs .
Dear ImGui is tracking dragging and widget activity that may occur outside the boundary of a window , so ' io . WantCaptureMouse ' is more accurate and correct than checking if a window is hovered .
( Advanced note : text input releases focus on Return ' KeyDown ' , so the following Return ' KeyUp ' event that your application receive will typically have ' io . WantCaptureKeyboard = false ' .
Depending on your application logic it may or not be inconvenient . You might want to track which key - downs were for Dear ImGui ( e . g . with an array of bool ) and filter out the corresponding key - ups . )
- When ' io . WantTextInput ' is set to may want to notify your OS to popup an on - screen keyboard , if available ( e . g . on a mobile phone , or console OS ) .
Preferably read the flags after calling ImGui : : NewFrame ( ) to avoid them lagging by one frame . But reading those flags before calling NewFrame ( ) is
also generally ok , as the bool toggles fairly rarely and you don ' t generally expect to interact with either Dear ImGui or your application during
the same frame when that transition occurs . Dear ImGui is tracking dragging and widget activity that may occur outside the boundary of a window ,
so ' io . WantCaptureMouse ' is more accurate and correct than checking if a window is hovered .
( Advanced note : text input releases focus on Return ' KeyDown ' , so the following Return ' KeyUp ' event that your application receive will typically
have ' io . WantCaptureKeyboard = false ' . Depending on your application logic it may or not be inconvenient . You might want to track which key - downs
were for Dear ImGui , e . g . with an array of bool , and filter out the corresponding key - ups . )
Q : How can I load a different font than the default ? ( default is an embedded version of ProggyClean . ttf , rendered at size 13 )
A : Use the font atlas to load the TTF / OTF file you want :
@ -509,8 +526,8 @@
io . Fonts - > GetTexDataAsRGBA32 ( ) or GetTexDataAsAlpha8 ( )
Q : How can I easily use icons in my application ?
A : The most convenient and practical way is to merge an icon font such as FontAwesome inside you main font . Then you can refer to icons within your strings .
Read ' How can I load multiple fonts ? ' and the file ' extra_fonts / README . txt ' for instruction s.
A : The most convenient and practical way is to merge an icon font such as FontAwesome inside you main font . Then you can refer to icons within your
strings. Read ' How can I load multiple fonts ? ' and the file ' extra_fonts / README . txt ' for instruction s and useful header file s.
Q : How can I load multiple fonts ?
A : Use the font atlas to pack them into a single texture :
@ -560,19 +577,24 @@
Otherwise you can convert yourself to UTF - 8 or load text data from file already saved as UTF - 8.
Text input : it is up to your application to pass the right character code to io . AddInputCharacter ( ) . The applications in examples / are doing that .
For languages using IME , on Windows you can copy the Hwnd of your application to io . ImeWindowHandle . The default implementation of io . ImeSetInputScreenPosFn ( ) on Windows will set your IME position correctly .
For languages using IME , on Windows you can copy the Hwnd of your application to io . ImeWindowHandle .
The default implementation of io . ImeSetInputScreenPosFn ( ) on Windows will set your IME position correctly .
Q : How can I preserve my Dear ImGui context across reloading a DLL ? ( loss of the global / static variables )
A : Create your own context ' ctx = CreateContext ( ) ' + ' SetCurrentContext ( ctx ) ' and your own font atlas ' ctx - > GetIO ( ) . Fonts = new ImFontAtlas ( ) ' so you don ' t rely on the default globals .
A : Create your own context ' ctx = CreateContext ( ) ' + ' SetCurrentContext ( ctx ) ' and your own font atlas ' ctx - > GetIO ( ) . Fonts = new ImFontAtlas ( ) '
so you don ' t rely on the default globals .
Q : How can I use the drawing facilities without an ImGui window ? ( using ImDrawList API )
A : The easiest way is to create a dummy window . Call Begin ( ) with NoTitleBar | NoResize | NoMove | NoScrollbar | NoSavedSettings | NoInputs flag , zero background alpha ,
then retrieve the ImDrawList * via GetWindowDrawList ( ) and draw to it in any way you like .
You can also perfectly create a standalone ImDrawList instance _but_ you need ImGui to be initialized because ImDrawList pulls from ImGui data to retrieve the coordinates of the white pixel .
- tip : the construct ' IMGUI_ONCE_UPON_A_FRAME { . . . } ' will run the block of code only once a frame . You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code .
- tip : you can create widgets without a Begin ( ) / End ( ) block , they will go in an implicit window called " Debug "
- tip : you can call Begin ( ) multiple times with the same name during the same frame , it will keep appending to the same window . this is also useful to set yourself in the context of another window ( to get / set other settings )
A : The easiest way is to create a dummy window . Call Begin ( ) with NoTitleBar | NoResize | NoMove | NoScrollbar | NoSavedSettings | NoInputs flag ,
zero background alpha , then retrieve the ImDrawList * via GetWindowDrawList ( ) and draw to it in any way you like .
You can also perfectly create a standalone ImDrawList instance _but_ you need ImGui to be initialized because ImDrawList pulls from ImGui
data to retrieve the coordinates of the white pixel .
- tip : you can call Begin ( ) multiple times with the same name during the same frame , it will keep appending to the same window .
this is also useful to set yourself in the context of another window ( to get / set other settings )
- tip : you can create widgets without a Begin ( ) / End ( ) block , they will go in an implicit window called " Debug " .
- tip : the ImGuiOnceUponAFrame helper will allow run the block of code only once a frame . You can use it to quickly add custom UI in the middle
of a deep nested inner loop in your code .
- tip : you can call Render ( ) multiple times ( e . g for VR renders ) .
- tip : call and read the ShowTestWindow ( ) code in imgui_demo . cpp for more example of how to use ImGui !
@ -10840,21 +10862,6 @@ static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2
RenderArrow ( draw_list , ImVec2 ( pos . x + bar_w - half_sz . x , pos . y ) , half_sz , ImGuiDir_Left , IM_COL32_WHITE ) ;
}
static void PaintVertsLinearGradientKeepAlpha ( ImDrawVert * vert_start , ImDrawVert * vert_end , ImVec2 gradient_p0 , ImVec2 gradient_p1 , ImU32 col0 , ImU32 col1 )
{
ImVec2 gradient_extent = gradient_p1 - gradient_p0 ;
float gradient_inv_length2 = 1.0f / ImLengthSqr ( gradient_extent ) ;
for ( ImDrawVert * vert = vert_start ; vert < vert_end ; vert + + )
{
float d = ImDot ( vert - > pos - gradient_p0 , gradient_extent ) ;
float t = ImClamp ( d * gradient_inv_length2 , 0.0f , 1.0f ) ;
int r = ImLerp ( ( int ) ( col0 > > IM_COL32_R_SHIFT ) & 0xFF , ( int ) ( col1 > > IM_COL32_R_SHIFT ) & 0xFF , t ) ;
int g = ImLerp ( ( int ) ( col0 > > IM_COL32_G_SHIFT ) & 0xFF , ( int ) ( col1 > > IM_COL32_G_SHIFT ) & 0xFF , t ) ;
int b = ImLerp ( ( int ) ( col0 > > IM_COL32_B_SHIFT ) & 0xFF , ( int ) ( col1 > > IM_COL32_B_SHIFT ) & 0xFF , t ) ;
vert - > col = ( r < < IM_COL32_R_SHIFT ) | ( g < < IM_COL32_G_SHIFT ) | ( b < < IM_COL32_B_SHIFT ) | ( vert - > col & IM_COL32_A_MASK ) ;
}
}
// ColorPicker
// Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set.
// FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..)
@ -11075,7 +11082,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
// Paint colors over existing vertices
ImVec2 gradient_p0 ( wheel_center . x + cosf ( a0 ) * wheel_r_inner , wheel_center . y + sinf ( a0 ) * wheel_r_inner ) ;
ImVec2 gradient_p1 ( wheel_center . x + cosf ( a1 ) * wheel_r_inner , wheel_center . y + sinf ( a1 ) * wheel_r_inner ) ;
PaintVertsLinea rGradientKeepAlpha( draw_list - > _VtxWritePtr - ( draw_list - > _VtxCurrentIdx - vert_start_idx ) , draw_list - > _VtxWritePtr , gradient_p0 , gradient_p1 , hue_colors [ n ] , hue_colors [ n + 1 ] ) ;
ShadeVertsLinearColo rGradientKeepAlpha( draw_list - > _VtxWritePtr - ( draw_list - > _VtxCurrentIdx - vert_start_idx ) , draw_list - > _VtxWritePtr , gradient_p0 , gradient_p1 , hue_colors [ n ] , hue_colors [ n + 1 ] ) ;
}
// Render Cursor + preview on Hue Wheel