Compare commits

...

71 Commits
v1.00 ... v1.07

Author SHA1 Message Date
efc473df98 Todo list 2014-08-18 19:13:18 +01:00
bbda899801 Removed unused parameter in demo window code 2014-08-18 19:10:00 +01:00
a17885f470 Fixed tooltip size (broken earlier today) + added todo items 2014-08-18 18:43:39 +01:00
7de89e0da3 Removing line from Todo list 2014-08-18 14:31:47 +01:00
7c61822d26 Skip most logic is alpha is 0.0, Begin() also return false to allow user to early out 2014-08-18 14:30:33 +01:00
ca027e1754 Skip rendering if alpha is 0.0 2014-08-18 13:20:57 +01:00
c5dacee3a7 Undo Begin() return false with Alpha==0.0, misleading at the moment 2014-08-18 13:18:32 +01:00
d6f6afabb3 Initialised window->Accessed in constructor. Begin() return false with Alpha==0.0 2014-08-18 13:09:48 +01:00
76a39ad224 Added global Alpha in ImGuiStyle + commented ImGuiStyle fields in .h 2014-08-18 13:03:02 +01:00
926f7bfcc5 Added InputFloat4(), SliderFloat4() helpers. 2014-08-17 14:16:10 +01:00
f6414f2011 Invisible child windows gets clipped earlier in the pipeline. 2014-08-17 14:02:32 +01:00
931a4c5b49 Renamed ImVector<> members. 2014-08-17 13:55:27 +01:00
c32221fa20 Child window with inverted clip rectangles are marked as collapsed. 2014-08-17 11:28:19 +01:00
a165954a69 Reduce inner window clipping to take account for the extend of CollapsingHeader
from arikwestbrook
2014-08-17 10:41:36 +01:00
ddf8b280e9 Allowing the user to call NewFrame() multiple times without calling Render()
Note that this is never a good idea. But, allowing it reduce confusion
in the initial stage of setup.
2014-08-16 18:47:59 +01:00
969b1e0563 Fix clipping of title bar text. 2014-08-16 18:22:52 +01:00
6e15b71663 Minor todo/readme changes 2014-08-16 14:19:19 +01:00
f5dbb0a973 Fixed floating-point precision issue making the right-side value of a plot sometimes wrap to the left-side value. 2014-08-15 17:54:42 +01:00
ade21a1ad5 PlotLines(), PlotHistogram(): added a stride parameter. 2014-08-15 17:36:54 +01:00
868ba05a13 Slowed down mouse wheel scrolling speed in combo boxes 2014-08-15 16:40:31 +01:00
152878571e TreeNode/CollapsingHeader ignore clicks when CTRL or SHFIT are held + make default button hover brighter 2014-08-15 16:38:29 +01:00
fa0aa5ace6 Added storage for up to 5 mouse buttons for convenience (even though ImGui itself only uses 1) 2014-08-15 16:22:03 +01:00
6267905a17 Added BeginTooltip()/EndTooltip() helpers to create tooltips with custom widgets 2014-08-15 16:18:00 +01:00
1509b8f634 Added TODO list items from users feedback 2014-08-15 12:35:39 +01:00
2bc6346b48 Added TextColored() helper. Changed some parameters to const references (still allows implicit casting) 2014-08-15 12:32:53 +01:00
9169b2911c Fixed trailing \n reporting extra text height 2014-08-14 17:01:42 +01:00
a4b96445e8 Fix typo and speculative warning 2014-08-14 16:02:42 +01:00
6c11d7623e Fix invalid .ini file data persistently saving back on next save 2014-08-14 15:51:55 +01:00
f33eb89018 Fix tooltip data needlessly leaking into .ini file 2014-08-14 15:43:58 +01:00
a8d3b045b7 Fix for doing multiple Begin()/End() during the same frame 2014-08-14 15:18:34 +01:00
a830037eab Default "local only" clipboard handler on non-Windows platforms 2014-08-14 15:03:10 +01:00
309ff44579 Undo IsHovered > IsItemHovered, shorter name wins 2014-08-14 14:32:01 +01:00
f30d23a502 Tweaks, more consistent #define names 2014-08-14 14:31:13 +01:00
a905505cca Added GetItemBoxMin(),GetItemBoxMax(), renamed IsHovered()-->IsItemHovered() 2014-08-14 12:43:30 +01:00
46eee0cee4 Tidying up example applications so it looks easier to just grab code 2014-08-14 00:01:41 +01:00
29863b55ef Fixed logarithmic sliders and HSV conversions on Mac/Linux
Tricky bug, I was calling abs() which resolve to abs(float) under
Windows with the include we have, but abs(int) under Mac/Linux
2014-08-13 23:25:42 +01:00
530f103dfe Tweak MacOS X Makefile for likely scenario 2014-08-13 23:02:30 +01:00
7a3e6aa38d Default Clipboard functions on Windows+ renamed ARRAYSIZE to IM_ARRAYSIZE 2014-08-13 19:53:26 +01:00
cda3aecc6a Fixed combo box (bug introduced earlier today) + adding bit of vertical padding in combo. 2014-08-13 19:26:25 +01:00
b6d1d85d86 Fixed scissoring in OpenGL example 2014-08-13 19:12:50 +01:00
9a426faf4f Added InputFloat2(), SliderFloat2() 2014-08-13 18:46:18 +01:00
b0d5600ffb Merge pull request #14 from Roflraging/constiteratorfix
Fix for gcc type qualifier warnings.
2014-08-13 18:40:18 +01:00
c52a54ef43 Fix for gcc type qualifier warnings.
With -Wall -Wextra -Werror, it is not possible to compile against
imgui.h due to const correctness violation in ImVector.
2014-08-13 11:57:37 -05:00
cc9d63b46a Fixed columns lines not being pixel aligned 2014-08-13 17:08:44 +01:00
d3ad5ce475 Update README.md 2014-08-13 13:23:37 +01:00
cb3d503941 OpenGL example now use the fixed function-pipeline. Code down by 120 lines. 2014-08-13 11:43:51 +01:00
ddc7f8b0b0 Simplified ImDrawList system (samples are 20 lines shorter) + merged title bar draw bar. 2014-08-13 11:34:08 +01:00
57ac561ecb Minor warning fix + removed unused function parameter. 2014-08-12 20:05:10 +01:00
2573ffb6fc Fixed warnings for more stringent compilation settings. Added various small helpers. 2014-08-12 19:57:46 +01:00
c938affcac Update README.md
Added References
2014-08-12 15:09:01 +01:00
a1e176fb07 Added Makefile for MacOS X (courtesy of djoshea) 2014-08-12 13:59:36 +01:00
901e9890d4 Removed stray debug code 2014-08-12 13:55:43 +01:00
f4ee74b312 Renamed Makefile 2014-08-12 13:55:30 +01:00
64e5c2f127 Merge pull request #11 from corpsmoderne/master
Add a quick and dirty makefile to build on linux
2014-08-12 13:53:06 +01:00
e2655d104e add a quick and dirty makefile to build on linux 2014-08-12 14:24:23 +02:00
8825545653 Portability fixes to OpenGL example application (courtesy of djoshea) 2014-08-12 11:21:47 +01:00
150ad95bd6 Missing assert + comments 2014-08-12 00:36:13 +01:00
ab8561e6fc Tweaked checkbox/radio default hover color to be less distracting. Added GetItemWidth(). Added text filter to style editor. 2014-08-12 00:04:13 +01:00
2a1ba33263 Merge pull request #9 from mhristov/master
Checkbox & radio button improvements
2014-08-11 23:37:53 +01:00
4fa623c43b Update README.md 2014-08-11 23:07:29 +01:00
080eb69e68 Removed dependency on limits.h 2014-08-11 22:31:45 +01:00
1b330f420e Checkboxes and radio buttons can be clicked on their labels as well as their icon 2014-08-11 21:43:48 +02:00
28df6f39d9 Added ImGuiCol_CheckHovered to show hovered checkboxes and radio buttons 2014-08-11 21:35:27 +02:00
98a000055e Tidying up example applications 2014-08-11 17:46:54 +01:00
4020ef7b58 Tidying up example applications 2014-08-11 16:17:59 +01:00
86d2c9d232 Commented samples and shuffled bits of the initialisation based on user's feedback. 2014-08-11 15:02:33 +01:00
8ab2942716 Added PixelCenterOffset for OpenGL/DirectX compatibility. 2014-08-11 14:51:22 +01:00
680a5a9b54 Git ignore imgui.ini files 2014-08-11 14:46:04 +01:00
900dd3bd0f Update README.md
Clarifying C++
Added item in todo list
2014-08-11 12:45:47 +01:00
678f6d3a3d Missing includes for some platforms 2014-08-11 12:13:05 +01:00
42419b59c0 Ignore list for Visual Studio output and temporaries 2014-08-11 11:10:50 +01:00
10 changed files with 1132 additions and 915 deletions

14
.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
## Visual Studio files
examples/directx9_example/Debug/*
examples/directx9_example/Release/*
examples/directx9_example/ipch/*
examples/opengl_example/Debug/*
examples/opengl_example/Release/*
examples/opengl_example/ipch/*
*.opensdf
*.sdf
*.suo
*.vcxproj.user
## Ini files
imgui.ini

View File

@ -1,17 +1,18 @@
ImGui
=====
ImGui is a bloat-free graphical user interface library for C/C++. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build simple user interfaces with ease.
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build simple user interfaces with ease.
ImGui is designed to allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
Usage example:
ImGui is particularly suited to integration in 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
After ImGui is setup in your engine, you can use it like in this example:
![screenshot of sample code alongside its output with ImGui](/web/code_sample_01.png?raw=true)
ImGui outputs vertex buffers and simple command-lists that you can render in your application. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate ImGui with your existing codebase.
Gallery
-------
@ -20,6 +21,16 @@ Gallery
![screenshot 3](/web/test_window_03.png?raw=true)
![screenshot 4](/web/test_window_04.png?raw=true)
References
----------
The Immediate Mode GUI paradigm may at first appear unusual to some users. This is mainly because "Retained Mode" GUIs have been so widespread and predominant. The following links can give you a better understanding about how Immediate Mode GUIs works.
- [Johannes 'johno' Norneby's article](http://www.johno.se/book/imgui.html).
- [A presentation by Rickard Gustafsson and Johannes Algelind](http://www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%20Computer%20Graphics/IMGUI.pdf).
- [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/).
- [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861).
Credits
-------
@ -27,7 +38,7 @@ Developed by [Omar Cornut](http://www.miracleworld.net). The library was develop
Embeds [proggy_clean](http://www.proggyfonts.net/) font by Tristan Grimmer (also MIT license).
Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Matt Willis. Thanks!
Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Thanks!
License
-------

View File

@ -12,16 +12,15 @@ static LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
static LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Our texture
struct CUSTOMVERTEX
{
D3DXVECTOR3 position;
D3DCOLOR color;
float tu, tv;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structuer)
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
size_t total_vtx_count = 0;
@ -30,31 +29,13 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
if (total_vtx_count == 0)
return;
ImVector<ImVec4> clip_rect_stack;
clip_rect_stack.push_back(ImVec4(-9999,-9999,+9999,+9999));
// Setup orthographic projection
// Set up world matrix
D3DXMATRIXA16 mat;
D3DXMatrixIdentity(&mat);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat);
g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);
D3DXMatrixOrthoOffCenterLH(&mat, 0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat);
D3DSURFACE_DESC texture_desc;
g_pTexture->GetLevelDesc(0, &texture_desc);
// Fill the vertex buffer
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
if (g_pVB->Lock(0, total_vtx_count, (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
return;
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
if (cmd_list->commands.empty() || cmd_list->vtx_buffer.empty())
continue;
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
{
@ -73,11 +54,10 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
// Setup render state: alpha-blending enabled, no face culling, no depth testing
// Setup render state: alpha-blending, no face culling, no depth testing
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, false );
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
g_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, false );
@ -94,97 +74,31 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
int vtx_consumed = 0; // offset in vertex buffer. each command consume ImDrawCmd::vtx_count of those
bool clip_rect_dirty = true;
// Setup orthographic projection matrix
D3DXMATRIXA16 mat;
D3DXMatrixIdentity(&mat);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat);
g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);
D3DXMatrixOrthoOffCenterLH(&mat, 0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat);
// Render command lists
int vtx_offset = 0;
for (int n = 0; n < cmd_lists_count; n++)
{
// Render command list
const ImDrawList* cmd_list = cmd_lists[n];
if (cmd_list->commands.empty() || cmd_list->vtx_buffer.empty())
continue;
const ImDrawCmd* pcmd = &cmd_list->commands.front();
const ImDrawCmd* pcmd_end = &cmd_list->commands.back();
int clip_rect_buf_consumed = 0; // offset in cmd_list->clip_rect_buffer. each PushClipRect command consume 1 of those.
while (pcmd <= pcmd_end)
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
{
const ImDrawCmd& cmd = *pcmd++;
switch (cmd.cmd_type)
{
case ImDrawCmdType_DrawTriangleList:
if (clip_rect_dirty)
{
const ImVec4& clip_rect = clip_rect_stack.back();
const RECT r = { (LONG)clip_rect.x, (LONG)clip_rect.y, (LONG)clip_rect.z, (LONG)clip_rect.w };
g_pd3dDevice->SetScissorRect(&r);
clip_rect_dirty = false;
}
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_consumed, cmd.vtx_count/3);
vtx_consumed += cmd.vtx_count;
break;
case ImDrawCmdType_PushClipRect:
clip_rect_stack.push_back(cmd_list->clip_rect_buffer[clip_rect_buf_consumed++]);
clip_rect_dirty = true;
break;
case ImDrawCmdType_PopClipRect:
clip_rect_stack.pop_back();
clip_rect_dirty = true;
break;
}
const RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w };
g_pd3dDevice->SetScissorRect(&r);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_offset, pcmd->vtx_count/3);
vtx_offset += pcmd->vtx_count;
}
}
}
// Get text data in Win32 clipboard
static const char* ImImpl_GetClipboardTextFn()
{
static char* buf_local = NULL;
if (buf_local)
{
free(buf_local);
buf_local = NULL;
}
if (!OpenClipboard(NULL))
return NULL;
HANDLE buf_handle = GetClipboardData(CF_TEXT);
if (buf_handle == NULL)
return NULL;
if (char* buf_global = (char*)GlobalLock(buf_handle))
buf_local = strdup(buf_global);
GlobalUnlock(buf_handle);
CloseClipboard();
return buf_local;
}
// Set text data in Win32 clipboard
static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
{
if (!OpenClipboard(NULL))
return;
if (!text_end)
text_end = text + strlen(text);
const int buf_length = (text_end - text) + 1;
HGLOBAL buf_handle = GlobalAlloc(GMEM_MOVEABLE, buf_length * sizeof(char));
if (buf_handle == NULL)
return;
char* buf_global = (char *)GlobalLock(buf_handle);
memcpy(buf_global, text, text_end - text);
buf_global[text_end - text] = 0;
GlobalUnlock(buf_handle);
EmptyClipboard();
SetClipboardData(CF_TEXT, buf_handle);
CloseClipboard();
}
HRESULT InitD3D(HWND hWnd)
{
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
@ -203,17 +117,6 @@ HRESULT InitD3D(HWND hWnd)
if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice) < 0)
return E_FAIL;
// Create the vertex buffer.
if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
return E_FAIL;
// Load font texture
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
if (D3DXCreateTextureFromFileInMemory(g_pd3dDevice, png_data, png_size, &g_pTexture) < 0)
return E_FAIL;
return S_OK;
}
@ -247,9 +150,11 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
io.MouseDown[1] = false;
return true;
case WM_MOUSEWHEEL:
// Mouse wheel: -1,0,+1
io.MouseWheel = GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1 : -1;
return true;
case WM_MOUSEMOVE:
// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MousePos.x = (signed short)(lParam);
io.MousePos.y = (signed short)(lParam >> 16);
return true;
@ -274,9 +179,10 @@ void InitImGui()
GetClientRect(hWnd, &rect);
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
io.DeltaTime = 1.0f/60.0f;
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
@ -295,8 +201,52 @@ void InitImGui()
io.KeyMap[ImGuiKey_Z] = 'Z';
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
// Create the vertex buffer
if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
{
IM_ASSERT(0);
return;
}
// Load font texture
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
if (D3DXCreateTextureFromFileInMemory(g_pd3dDevice, png_data, png_size, &g_pTexture) < 0)
{
IM_ASSERT(0);
return;
}
}
INT64 ticks_per_second = 0;
INT64 time = 0;
void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup timestep
INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
time = current_time;
// Setup inputs
// (we already got mouse position, buttons, wheel from the window message callback)
BYTE keystate[256];
GetKeyboardState(keystate);
for (int i = 0; i < 256; i++)
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
// io.MousePos : filled by WM_MOUSEMOVE event
// io.MouseDown : filled by WM_*BUTTON* events
// io.MouseWheel : filled by WM_MOUSEWHEEL events
// Start the frame
ImGui::NewFrame();
}
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
@ -308,99 +258,91 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
// Create the application's window
hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX9 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
INT64 ticks_per_second, time;
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
return 1;
// Initialize Direct3D
if (InitD3D(hWnd) >= 0)
if (InitD3D(hWnd) < 0)
{
if (g_pVB)
g_pVB->Release();
UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
InitImGui();
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
InitImGui();
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
// 1) ImGui start frame, setup time delta & inputs
ImGuiIO& io = ImGui::GetIO();
INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
time = current_time;
BYTE keystate[256];
GetKeyboardState(keystate);
for (int i = 0; i < 256; i++)
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
// io.MousePos : filled by WM_MOUSEMOVE event
// io.MouseDown : filled by WM_*BUTTON* events
// io.MouseWheel : filled by WM_MOUSEWHEEL events
ImGui::NewFrame();
UpdateImGui();
// 2) ImGui usage
static bool show_test_window = true;
static bool show_another_window = false;
static float f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Create a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
static bool show_test_window = true;
static bool show_another_window = false;
static float f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Calculate and show framerate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = io.DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
// Calculate and show framerate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
if (show_test_window)
{
// More example code in ShowTestWindow()
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
ImGui::Text("Hello");
ImGui::End();
}
// 3) Render
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(204, 153, 153), 1.0f, 0); // Clear the backbuffer and the zbuffer
if (g_pd3dDevice->BeginScene() >= 0)
{
ImGui::Render();
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
// Show the ImGui test window
// Most of user example code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
ImGui::Shutdown();
}
// Show another simple window
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
ImGui::Text("Hello");
ImGui::End();
}
// Rendering
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(204, 153, 153), 1.0f, 0);
if (g_pd3dDevice->BeginScene() >= 0)
{
ImGui::Render();
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
ImGui::Shutdown();
if (g_pVB)
g_pVB->Release();

View File

@ -0,0 +1,18 @@
#
# Quick and dirty makefile to build on Linux
# tested on Ubuntu 14.04.1 32bit
#
SRC = main.cpp ../../imgui.cpp
OBJ = $(SRC:.cpp=.o)
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
LIBS = `pkg-config --static --libs glfw3` -lGLEW
all: $(OBJ)
$(CXX) $(OBJ) $(LIBS)
clean:
$(RM) -f $(OBJ)

View File

@ -0,0 +1,18 @@
# This makefile currently only works for mac os
# You should install via homebrew:
# brew install glew
# brew install glfw3
#
CXXFLAGS=-framework OpenGL -framework Cocoa -framework IOKit
CXXFLAGS+=-I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/Cellar/glfw3/3.0.4/include
CXXFLAGS+=-L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/Cellar/glfw3/3.0.4/lib
CXXFLAGS+=-lglew -lglfw3
CXXFLAGS+=-I../../
CXXFLAGS+= -D__APPLE__
main: main.cpp ../../imgui.cpp
$(CXX) $(CXXFLAGS) -o $@ $^
clean:
rm main

View File

@ -2,116 +2,65 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" // for .png loading
#include "stb_image.h" // for .png loading
#include "../../imgui.h"
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#endif
static GLFWwindow* window;
static GLuint vbo;
static GLuint vao;
static GLuint vertexShader;
static GLuint fragmentShader;
static GLuint shaderProgram;
static GLuint fontTex;
static GLint uniMVP;
static GLint uniClipRect;
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structuer)
// We are using the fixed pipeline.
// A faster way would be to collate all vertices from all cmd_lists into a single vertex buffer
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
size_t total_vtx_count = 0;
for (int n = 0; n < cmd_lists_count; n++)
total_vtx_count += cmd_lists[n]->vtx_buffer.size();
if (total_vtx_count == 0)
if (cmd_lists_count == 0)
return;
int read_pos_clip_rect_buf = 0; // offset in 'clip_rect_buffer'. each PushClipRect command consume 1 of those.
ImVector<ImVec4> clip_rect_stack;
clip_rect_stack.push_back(ImVec4(-9999,-9999,+9999,+9999));
// Setup orthographic projection
const float L = 0.0f;
const float R = ImGui::GetIO().DisplaySize.x;
const float B = ImGui::GetIO().DisplaySize.y;
const float T = 0.0f;
const float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ -(R+L)/(R-L), -(T+B)/(T-B), 0.0f, 1.0f },
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindVertexArray(vao);
glBufferData(GL_ARRAY_BUFFER, total_vtx_count * sizeof(ImDrawVert), NULL, GL_STREAM_DRAW);
unsigned char* buffer_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!buffer_data)
return;
int vtx_consumed = 0;
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
if (!cmd_list->vtx_buffer.empty())
{
memcpy(buffer_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert));
buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert);
vtx_consumed += cmd_list->vtx_buffer.size();
}
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glUseProgram(shaderProgram);
glUniformMatrix4fv(uniMVP, 1, GL_FALSE, &mvp[0][0]);
// Setup render state: alpha-blending enabled, no face culling, no depth testing
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
// Setup texture
glBindTexture(GL_TEXTURE_2D, fontTex);
glEnable(GL_TEXTURE_2D);
vtx_consumed = 0; // offset in vertex buffer. each command consume ImDrawCmd::vtx_count of those
bool clip_rect_dirty = true;
// Setup orthographic projection matrix
const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Render command lists
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
if (cmd_list->commands.empty() || cmd_list->vtx_buffer.empty())
continue;
const ImDrawCmd* pcmd = &cmd_list->commands.front();
const ImDrawCmd* pcmd_end = &cmd_list->commands.back();
int clip_rect_buf_consumed = 0; // offset in cmd_list->clip_rect_buffer. each PushClipRect command consume 1 of those.
while (pcmd <= pcmd_end)
const unsigned char* vtx_buffer = (const unsigned char*)cmd_list->vtx_buffer.begin();
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer+8));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer+16));
int vtx_offset = 0;
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
{
const ImDrawCmd& cmd = *pcmd++;
switch (cmd.cmd_type)
{
case ImDrawCmdType_DrawTriangleList:
if (clip_rect_dirty)
{
glUniform4fv(uniClipRect, 1, (float*)&clip_rect_stack.back());
clip_rect_dirty = false;
}
glDrawArrays(GL_TRIANGLES, vtx_consumed, cmd.vtx_count);
vtx_consumed += cmd.vtx_count;
break;
case ImDrawCmdType_PushClipRect:
clip_rect_stack.push_back(cmd_list->clip_rect_buffer[clip_rect_buf_consumed++]);
clip_rect_dirty = true;
break;
case ImDrawCmdType_PopClipRect:
clip_rect_stack.pop_back();
clip_rect_dirty = true;
break;
}
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
vtx_offset += pcmd->vtx_count;
}
}
glDisable(GL_SCISSOR_TEST);
}
static const char* ImImpl_GetClipboardTextFn()
@ -124,55 +73,33 @@ static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
if (!text_end)
text_end = text + strlen(text);
char* buf = (char*)malloc(text_end - text + 1);
memcpy(buf, text, text_end-text);
buf[text_end-text] = '\0';
glfwSetClipboardString(window, buf);
free(buf);
if (*text_end == 0)
{
// Already got a zero-terminator at 'text_end', we don't need to add one
glfwSetClipboardString(window, text);
}
else
{
// Add a zero-terminator because glfw function doesn't take a size
char* buf = (char*)malloc(text_end - text + 1);
memcpy(buf, text, text_end-text);
buf[text_end-text] = '\0';
glfwSetClipboardString(window, buf);
free(buf);
}
}
// Shader sources
// FIXME-OPT: clip at vertex level
const GLchar* vertexSource =
"#version 150 core\n"
"uniform mat4 MVP;"
"in vec2 i_pos;"
"in vec2 i_uv;"
"in vec4 i_col;"
"out vec4 col;"
"out vec2 pixel_pos;"
"out vec2 uv;"
"void main() {"
" col = i_col;"
" pixel_pos = i_pos;"
" uv = i_uv;"
" gl_Position = MVP * vec4(i_pos.x, i_pos.y, 0.0f, 1.0f);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"uniform sampler2D Tex;"
"uniform vec4 ClipRect;"
"in vec4 col;"
"in vec2 pixel_pos;"
"in vec2 uv;"
"out vec4 o_col;"
"void main() {"
" o_col = texture(Tex, uv) * col;"
//" if (pixel_pos.x < ClipRect.x || pixel_pos.y < ClipRect.y || pixel_pos.x > ClipRect.z || pixel_pos.y > ClipRect.w) discard;" // Clipping: using discard
//" if (step(ClipRect.x,pixel_pos.x) * step(ClipRect.y,pixel_pos.y) * step(pixel_pos.x,ClipRect.z) * step(pixel_pos.y,ClipRect.w) < 1.0f) discard;" // Clipping: using discard and step
" o_col.w *= (step(ClipRect.x,pixel_pos.x) * step(ClipRect.y,pixel_pos.y) * step(pixel_pos.x,ClipRect.z) * step(pixel_pos.y,ClipRect.w));" // Clipping: branch-less, set alpha 0.0f
"}";
// GLFW callbacks to get events
static void glfw_error_callback(int error, const char* description)
{
fputs(description, stderr);
fputs(description, stderr);
}
static float mouse_wheel = 0.0f;
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
mouse_wheel = (float)yoffset;
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = (yoffset != 0.0f) ? yoffset > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
}
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
@ -197,79 +124,17 @@ void InitGL()
{
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
exit(1);
if (!glfwInit())
exit(1);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
//glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_REFRESH_RATE, 60);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", nullptr, nullptr);
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, glfw_key_callback);
glfwSetScrollCallback(window, glfw_scroll_callback);
glfwSetCharCallback(window, glfw_char_callback);
glewExperimental = GL_TRUE;
glewInit();
GLenum err = GL_NO_ERROR;
GLint status = GL_TRUE;
err = glGetError(); IM_ASSERT(err == GL_NO_ERROR);
// Create and compile the vertex shader
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE)
{
char buffer[512];
glGetShaderInfoLog(vertexShader, 1024, NULL, buffer);
printf("%s", buffer);
IM_ASSERT(status == GL_TRUE);
}
// Create and compile the fragment shader
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
IM_ASSERT(status == GL_TRUE);
// Link the vertex and fragment shader into a shader program
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "o_col");
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
IM_ASSERT(status == GL_TRUE);
uniMVP = glGetUniformLocation(shaderProgram, "MVP");
uniClipRect = glGetUniformLocation(shaderProgram, "ClipRect");
// Create Vertex Buffer Objects & Vertex Array Objects
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLint posAttrib = glGetAttribLocation(shaderProgram, "i_pos");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), 0);
glEnableVertexAttribArray(posAttrib);
GLint uvAttrib = glGetAttribLocation(shaderProgram, "i_uv");
glEnableVertexAttribArray(uvAttrib);
glVertexAttribPointer(uvAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (void*)(2*sizeof(float)));
GLint colAttrib = glGetAttribLocation(shaderProgram, "i_col");
glVertexAttribPointer(colAttrib, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (void*)(4*sizeof(float)));
glEnableVertexAttribArray(colAttrib);
err = glGetError(); IM_ASSERT(err == GL_NO_ERROR);
}
void InitImGui()
@ -278,9 +143,10 @@ void InitImGui()
glfwGetWindowSize(window, &w, &h);
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)w, (float)h);
io.DeltaTime = 1.0f/60.0f;
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB;
io.DisplaySize = ImVec2((float)w, (float)h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
io.PixelCenterOffset = 0.5f; // Align OpenGL texels
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
@ -307,7 +173,6 @@ void InitImGui()
glBindTexture(GL_TEXTURE_2D, fontTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
@ -317,44 +182,43 @@ void InitImGui()
stbi_image_free(tex_data);
}
void Shutdown()
void UpdateImGui()
{
ImGui::Shutdown();
ImGuiIO& io = ImGui::GetIO();
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
// Setup timestep
static double time = 0.0f;
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
time = current_time;
glfwTerminate();
// Setup inputs
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
// Start the frame
ImGui::NewFrame();
}
// Application code
int main(int argc, char** argv)
{
InitGL();
InitImGui();
double time = glfwGetTime();
while (!glfwWindowShouldClose(window))
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = 0;
glfwPollEvents();
UpdateImGui();
// 1) ImGui start frame, setup time delta & inputs
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
time = current_time;
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
io.MouseWheel = (mouse_wheel != 0) ? mouse_wheel > 0.0f ? 1 : - 1 : 0;
mouse_wheel = 0.0f;
ImGui::NewFrame();
// 2) ImGui usage
// Create a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
static bool show_test_window = true;
static bool show_another_window = false;
static float f;
@ -368,19 +232,21 @@ int main(int argc, char** argv)
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = io.DeltaTime * 1000.0f;
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
// Show the ImGui test window
// Most of user example code is in ImGui::ShowTestWindow()
if (show_test_window)
{
// More example code in ShowTestWindow()
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
// Show another simple window
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
@ -388,15 +254,15 @@ int main(int argc, char** argv)
ImGui::End();
}
// 3) Render
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Rendering
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui::Render();
glfwSwapBuffers(window);
}
Shutdown();
ImGui::Shutdown();
glfwTerminate();
return 0;
}

View File

@ -4,15 +4,22 @@
#pragma once
//----- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h
//---- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h
//#include <vector>
//#define ImVector std::vector
//#define ImVector MyVector
//----- Define assertion handler. Default to calling assert().
// #define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//---- Define assertion handler. Defaults to calling assert().
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//----- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard(), etc.)
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
//---- If you are loading a custom font, ImGui expect to find a pure white pixel at (0,0)
// Change it's UV coordinate here if you can't have a white pixel at (0,0)
//#define IMGUI_FONT_TEX_UV_FOR_WHITE ImVec2(0.f/256.f,0.f/256.f)
//---- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
/*
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
@ -23,12 +30,12 @@
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//----- Freely implement extra functions within the ImGui:: namespace.
//----- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
//---- Freely implement extra functions within the ImGui:: namespace.
//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
/*
namespace ImGui
{
void Value(const char* prefix, cosnt MyVec2& v, const char* float_format = NULL);
void Value(const char* prefix, cosnt MyVec4& v, const char* float_format = NULL);
void Value(const char* prefix, const MyVec2& v, const char* float_format = NULL);
void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL);
};
*/

1105
imgui.cpp

File diff suppressed because it is too large Load Diff

188
imgui.h
View File

@ -29,8 +29,8 @@ typedef ImU32 ImGuiID;
typedef int ImGuiCol; // enum ImGuiCol_
typedef int ImGuiKey; // enum ImGuiKey_
typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_
typedef ImU32 ImGuiWindowFlags; // enum ImGuiWindowFlags_
typedef ImU32 ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
typedef ImBitmapFont* ImFont;
struct ImVec2
@ -62,46 +62,46 @@ template<typename T>
class ImVector
{
private:
size_t _size;
size_t _capacity;
T* _data;
size_t Size;
size_t Capacity;
T* Data;
public:
typedef T value_type;
typedef value_type* iterator;
typedef const value_type* const_iterator;
ImVector() { _size = _capacity = 0; _data = NULL; }
~ImVector() { if (_data) free(_data); }
ImVector() { Size = Capacity = 0; Data = NULL; }
~ImVector() { if (Data) free(Data); }
inline bool empty() const { return _size == 0; }
inline size_t size() const { return _size; }
inline size_t capacity() const { return _capacity; }
inline bool empty() const { return Size == 0; }
inline size_t size() const { return Size; }
inline size_t capacity() const { return Capacity; }
inline value_type& at(size_t i) { IM_ASSERT(i < _size); return _data[i]; }
inline const value_type& at(size_t i) const { IM_ASSERT(i < _size); return _data[i]; }
inline value_type& operator[](size_t i) { IM_ASSERT(i < _size); return _data[i]; }
inline const value_type& operator[](size_t i) const { IM_ASSERT(i < _size); return _data[i]; }
inline value_type& at(size_t i) { IM_ASSERT(i < Size); return Data[i]; }
inline const value_type& at(size_t i) const { IM_ASSERT(i < Size); return Data[i]; }
inline value_type& operator[](size_t i) { IM_ASSERT(i < Size); return Data[i]; }
inline const value_type& operator[](size_t i) const { IM_ASSERT(i < Size); return Data[i]; }
inline void clear() { if (_data) { _size = _capacity = 0; free(_data); _data = NULL; } }
inline iterator begin() { return _data; }
inline const iterator begin() const { return _data; }
inline iterator end() { return _data + _size; }
inline const iterator end() const { return _data + _size; }
inline void clear() { if (Data) { Size = Capacity = 0; free(Data); Data = NULL; } }
inline iterator begin() { return Data; }
inline const_iterator begin() const { return Data; }
inline iterator end() { return Data + Size; }
inline const_iterator end() const { return Data + Size; }
inline value_type& front() { return at(0); }
inline const value_type& front() const { return at(0); }
inline value_type& back() { IM_ASSERT(_size > 0); return at(_size-1); }
inline const value_type& back() const { IM_ASSERT(_size > 0); return at(_size-1); }
inline void swap(ImVector<T>& rhs) { const size_t rhs_size = rhs._size; rhs._size = _size; _size = rhs_size; const size_t rhs_cap = rhs._capacity; rhs._capacity = _capacity; _capacity = rhs_cap; value_type* rhs_data = rhs._data; rhs._data = _data; _data = rhs_data; }
inline value_type& back() { IM_ASSERT(Size > 0); return at(Size-1); }
inline const value_type& back() const { IM_ASSERT(Size > 0); return at(Size-1); }
inline void swap(ImVector<T>& rhs) { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
inline void reserve(size_t new_capacity) { _data = (value_type*)realloc(_data, new_capacity * sizeof(value_type)); _capacity = new_capacity; }
inline void resize(size_t new_size) { if (new_size > _capacity) reserve(new_size); _size = new_size; }
inline void reserve(size_t new_capacity) { Data = (value_type*)realloc(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
inline void resize(size_t new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; }
inline void push_back(const value_type& v) { if (_size == _capacity) reserve(_capacity ? _capacity * 2 : 4); _data[_size++] = v; }
inline void pop_back() { IM_ASSERT(_size > 0); _size--; }
inline void push_back(const value_type& v) { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; }
inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const int off = it - begin(); memmove(_data + off, _data + off + 1, (_size - off - 1) * sizeof(value_type)); _size--; return _data + off; }
inline void insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const int off = it - begin(); if (_size == _capacity) reserve(_capacity ? _capacity * 2 : 4); if (off < (int)_size) memmove(_data + off + 1, _data + off, (_size - off) * sizeof(value_type)); _data[off] = v; _size++; }
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const int off = it - begin(); memmove(Data + off, Data + off + 1, (Size - off - 1) * sizeof(value_type)); Size--; return Data + off; }
inline void insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const int off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - off) * sizeof(value_type)); Data[off] = v; Size++; }
};
#endif // #ifndef ImVector
@ -135,7 +135,7 @@ namespace ImGui
bool GetWindowIsFocused();
float GetWindowWidth();
ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing
void SetWindowPos(ImVec2 pos); // unchecked
void SetWindowPos(const ImVec2& pos); // set current window pos
ImVec2 GetWindowSize();
ImVec2 GetWindowContentRegionMin();
ImVec2 GetWindowContentRegionMax();
@ -143,13 +143,20 @@ namespace ImGui
void SetFontScale(float scale);
void SetScrollPosHere();
void SetTreeStateStorage(ImGuiStorage* tree);
ImGuiStorage* GetTreeStateStorage();
void PushItemWidth(float item_width);
void PopItemWidth();
float GetItemWidth();
void PushAllowKeyboardFocus(bool v);
void PopAllowKeyboardFocus();
void PushStyleColor(ImGuiCol idx, ImVec4 col);
void PushStyleColor(ImGuiCol idx, const ImVec4& col);
void PopStyleColor();
// Tooltip
void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins.
void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text.
void EndTooltip();
// Layout
void Separator(); // horizontal line
void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets to layout them horizontally
@ -159,8 +166,8 @@ namespace ImGui
float GetColumnOffset(int column_index = -1);
void SetColumnOffset(int column_index, float offset);
float GetColumnWidth(int column_index = -1);
ImVec2 GetCursorPos(); // cursor position relative to window position
void SetCursorPos(ImVec2 p);
ImVec2 GetCursorPos(); // cursor position is relative to window position
void SetCursorPos(const ImVec2& pos); // "
void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match higher widgets.
float GetTextLineSpacing();
float GetTextLineHeight();
@ -174,6 +181,7 @@ namespace ImGui
// Widgets
void Text(const char* fmt, ...);
void TextV(const char* fmt, va_list args);
void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut to doing PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, better for long chunks of text.
void LabelText(const char* label, const char* fmt, ...);
void BulletText(const char* fmt, ...);
@ -181,17 +189,21 @@ namespace ImGui
bool SmallButton(const char* label);
bool CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderFloat4(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); // *v in radians
bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0));
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0));
void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
void Checkbox(const char* label, bool* v);
void CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
bool RadioButton(const char* label, bool active);
bool RadioButton(const char* label, int* v, int v_button);
bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1);
bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
bool InputFloat4(const char* label, float v[4], int decimal_precision = -1);
bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100);
bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0);
bool Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items = 7);
@ -220,17 +232,20 @@ namespace ImGui
// Logging
void LogButtons();
void LogToTTY(int max_depth);
void LogToFile(int max_depth, const char* filename);
void LogToClipboard(int max_depth);
void LogToTTY(int max_depth = -1);
void LogToFile(int max_depth = -1, const char* filename = NULL);
void LogToClipboard(int max_depth = -1);
// Utilities
void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). (currently no contention handling, last call win)
void SetNewWindowDefaultPos(ImVec2 pos); // set position of window that do
void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
bool IsHovered(); // was the last item active area hovered by mouse?
bool IsClipped(ImVec2 item_size); // to perform coarse clipping on user's side (as an optimisation)
ImVec2 GetItemBoxMin(); // get bounding box of last item
ImVec2 GetItemBoxMax(); // get bounding box of last item
bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimisation)
bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
bool IsMouseClicked(int button, bool repeat = false);
bool IsMouseDoubleClicked(int button);
bool IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max);
ImVec2 GetMousePos();
float GetTime();
int GetFrameCount();
@ -302,6 +317,7 @@ enum ImGuiCol_
ImGuiCol_ScrollbarGrabHovered,
ImGuiCol_ScrollbarGrabActive,
ImGuiCol_ComboBg,
ImGuiCol_CheckHovered,
ImGuiCol_CheckActive,
ImGuiCol_SliderGrab,
ImGuiCol_SliderGrabActive,
@ -337,21 +353,21 @@ enum ImGuiColorEditMode_
ImGuiColorEditMode_HEX = 2,
};
// See constructor for comments of individual fields.
struct ImGuiStyle
{
ImVec2 WindowPadding;
ImVec2 WindowMinSize;
ImVec2 FramePadding;
ImVec2 ItemSpacing;
ImVec2 ItemInnerSpacing;
ImVec2 TouchExtraPadding;
ImVec2 AutoFitPadding;
float WindowFillAlphaDefault;
float WindowRounding;
float TreeNodeSpacing;
float ColumnsMinSpacing;
float ScrollBarWidth;
float Alpha; // Global alpha applies to everything in ImGui
ImVec2 WindowPadding; // Padding within a window
ImVec2 WindowMinSize; // Minimum window size
ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets)
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
ImVec2 TouchExtraPadding; // Expand bounding box for touch-based system where touch position is not accurate enough (unnecessary for mouse inputs). Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget running. So dont grow this too much!
ImVec2 AutoFitPadding; // Extra space after auto-fit (double-clicking on resize grip)
float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin()
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows
float TreeNodeSpacing; // Horizontal spacing when entering a tree node
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns
float ScrollBarWidth; // Width of the vertical scroll bar
ImVec4 Colors[ImGuiCol_COUNT];
ImGuiStyle();
@ -373,37 +389,46 @@ struct ImGuiIO
ImFont Font; // <auto> // Gets passed to text functions. Typedef ImFont to the type you want (ImBitmapFont* or your own font).
float FontHeight; // <auto> // Default font height, must be the vertical distance between two lines of text, aka == CalcTextSize(" ").y
bool FontAllowScaling; // = false // Set to allow scaling text with CTRL+Wheel.
float PixelCenterOffset; // = 0.5f // Set to 0.0f for DirectX <= 9, 0.5f for Direct3D >= 10 and OpenGL.
// Settings - Functions (fill once)
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count); // Required
const char* (*GetClipboardTextFn)(); // Required for clipboard support
void (*SetClipboardTextFn)(const char* text, const char* text_end); // Required for clipboard support (nb- the string is *NOT* zero-terminated at 'text_end')
// Settings - Rendering function (REQUIRED)
// See example code if you are unsure of how to implement this.
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
// Settings - Clipboard Support
// Override to provide your clipboard handlers.
// On Windows architecture, defaults to use the native Win32 clipboard, otherwise default to use a ImGui private clipboard.
// NB- for SetClipboardTextFn, the string is *NOT* zero-terminated at 'text_end'
const char* (*GetClipboardTextFn)();
void (*SetClipboardTextFn)(const char* text, const char* text_end);
// Input - Fill before calling NewFrame()
ImVec2 MousePos; // Mouse position (set to -1,-1 if no mouse / on another screen, etc.)
bool MouseDown[2]; // Mouse buttons
ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
bool MouseDown[5]; // Mouse buttons. ImGui itself only uses button 0 (left button) but you can use others as storage for convenience.
int MouseWheel; // Mouse wheel: -1,0,+1
bool KeyCtrl; // Keyboard modifier pressed: Control
bool KeyShift; // Keyboard modifier pressed: Shift
bool KeysDown[512]; // Keyboard keys that are pressed (in whatever order user naturally has access to keyboard data)
char InputCharacters[16]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs for the rest of your application
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application
bool WantCaptureMouse; // ImGui is using your mouse input (= window is being hovered or widget is active).
bool WantCaptureKeyboard; // imGui is using your keyboard input (= widget is active).
// Function
void AddInputCharacter(char c); // Helper to add a new character into InputCharacters[]
// [Internal] ImGui will maintain those fields for you
ImVec2 MousePosPrev;
ImVec2 MouseDelta;
bool MouseClicked[2];
ImVec2 MouseClickedPos[2];
float MouseClickedTime[2];
bool MouseDoubleClicked[2];
float MouseDownTime[2];
bool MouseClicked[5];
ImVec2 MouseClickedPos[5];
float MouseClickedTime[5];
bool MouseDoubleClicked[5];
float MouseDownTime[5];
float KeysDownTime[512];
ImGuiIO();
void AddInputCharacter(char c); // Helper to add a new character into InputCharacters[]
};
//-----------------------------------------------------------------------------
@ -464,7 +489,7 @@ struct ImGuiTextBuffer
size_t size() const { return Buf.size()-1; }
bool empty() { return Buf.empty(); }
void clear() { Buf.clear(); Buf.push_back(0); }
void Append(const char* fmt, ...);
void append(const char* fmt, ...);
};
// Helper: Key->value storage
@ -491,23 +516,14 @@ struct ImGuiStorage
// Hold a series of drawing commands. The user provide a renderer for ImDrawList
//-----------------------------------------------------------------------------
enum ImDrawCmdType
{
ImDrawCmdType_DrawTriangleList,
ImDrawCmdType_PushClipRect,
ImDrawCmdType_PopClipRect,
};
// sizeof() == 4
struct ImDrawCmd
{
ImDrawCmdType cmd_type : 16;
unsigned int vtx_count : 16;
ImDrawCmd(ImDrawCmdType _cmd_type = ImDrawCmdType_DrawTriangleList, unsigned int _vtx_count = 0) { cmd_type = _cmd_type; vtx_count = _vtx_count; }
unsigned int vtx_count;
ImVec4 clip_rect;
};
#ifndef IMDRAW_TEX_UV_FOR_WHITE
#define IMDRAW_TEX_UV_FOR_WHITE ImVec2(0,0)
#ifndef IMGUI_FONT_TEX_UV_FOR_WHITE
#define IMGUI_FONT_TEX_UV_FOR_WHITE ImVec2(0.f,0.f)
#endif
// sizeof() == 20
@ -522,18 +538,20 @@ struct ImDrawVert
// User is responsible for providing a renderer for this in ImGuiIO::RenderDrawListFn
struct ImDrawList
{
ImVector<ImDrawCmd> commands;
// This is what you have to render
ImVector<ImDrawCmd> commands; // commands
ImVector<ImDrawVert> vtx_buffer; // each command consume ImDrawCmd::vtx_count of those
ImVector<ImVec4> clip_rect_buffer; // each PushClipRect command consume 1 of those
ImVector<ImVec4> clip_rect_stack_; // [internal] clip rect stack while building the command-list (so text command can perform clipping early on)
ImDrawVert* vtx_write_; // [internal] point within vtx_buffer after each add command. allow us to use less [] and .resize on the vector (often slow on windows/debug)
// [Internal to ImGui]
ImVector<ImVec4> clip_rect_stack; // [internal] clip rect stack while building the command-list (so text command can perform clipping early on)
ImDrawVert* vtx_write; // [internal] point within vtx_buffer after each add command (to avoid using the ImVector<> operators too much)
ImDrawList() { Clear(); }
void Clear();
void PushClipRect(const ImVec4& clip_rect);
void PopClipRect();
void AddCommand(ImDrawCmdType cmd_type, int vtx_count);
void ReserveVertices(unsigned int vtx_count);
void AddVtx(const ImVec2& pos, ImU32 col);
void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB