Compare commits
97 Commits
Author | SHA1 | Date | |
---|---|---|---|
618a42acf8 | |||
3cd1b8a37b | |||
746951691a | |||
8eafb373f7 | |||
fec4232c79 | |||
85672fec2e | |||
d5ed586d70 | |||
d58a029285 | |||
6e039c8b7d | |||
05a42ba3a6 | |||
da2ccf0a78 | |||
3e647d86aa | |||
0e0cd5e705 | |||
8d32fcb7d4 | |||
4ea2af7ea5 | |||
3773fb4117 | |||
24028911e3 | |||
3fd68c3a31 | |||
1cf4b313e2 | |||
2e85dce1ee | |||
62d233aaab | |||
3cdb4fa456 | |||
7439df0ba1 | |||
ad42787543 | |||
91059da1a5 | |||
b420a51541 | |||
c07ab1b56a | |||
22a9555a99 | |||
25080d53e5 | |||
43448d9c89 | |||
e20077fbd0 | |||
2c677c45c7 | |||
3b339efeb2 | |||
8fc50f5ed3 | |||
dd5d251273 | |||
2fb63b6068 | |||
cd3d027df0 | |||
7adad71042 | |||
88c33ecc29 | |||
1f63e01cc6 | |||
bd26de0628 | |||
5a9639b423 | |||
b90d0c558d | |||
51f8e33eb4 | |||
80dd1e1065 | |||
5f6b261c9b | |||
681ac5f777 | |||
0d344e1f03 | |||
d2b43f31e3 | |||
d17a586738 | |||
710b9b68b1 | |||
29ba288ea0 | |||
addfa75eb0 | |||
882072cf30 | |||
7bd507d266 | |||
1ff104641a | |||
3b8d1ec207 | |||
e9e1fd2b3c | |||
6062d18cf9 | |||
05f0993616 | |||
6dd2b13220 | |||
5864c45fe3 | |||
4bc3642bdb | |||
a3f32381c4 | |||
67f17a644c | |||
e807d97089 | |||
23d156908d | |||
42d4b4be6a | |||
efc473df98 | |||
bbda899801 | |||
a17885f470 | |||
7de89e0da3 | |||
7c61822d26 | |||
ca027e1754 | |||
c5dacee3a7 | |||
d6f6afabb3 | |||
76a39ad224 | |||
aa7fc37b37 | |||
c13c2449bb | |||
c2cb727ac9 | |||
47fd8431c1 | |||
926f7bfcc5 | |||
f6414f2011 | |||
931a4c5b49 | |||
c32221fa20 | |||
a165954a69 | |||
ddf8b280e9 | |||
969b1e0563 | |||
6e15b71663 | |||
ef628a0a9d | |||
df5a06f119 | |||
e9b697698a | |||
5240013c90 | |||
1956703c42 | |||
6d6ee4e1f1 | |||
e9b0a61f48 | |||
e3001fb986 |
31
README.md
@ -13,6 +13,8 @@ After ImGui is setup in your engine, you can use it like in this example:
|
||||
|
||||
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.
|
||||
|
||||
ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, etc.
|
||||
|
||||
Gallery
|
||||
-------
|
||||
|
||||
@ -30,15 +32,40 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This
|
||||
- [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).
|
||||
|
||||
Frequently Asked Question
|
||||
-------------------------
|
||||
<b>How do you use ImGui on a platform that may not have a mouse and keyboard?</b>
|
||||
|
||||
I recommend using [Synergy](http://synergy-project.org). With the uSynergy.c micro client running you can seamlessly use your PC input devices from a video game console or a tablet. ImGui was also designed to function with touch inputs if you increase the padding of widgets to compensate for the lack of precision of touch devices, but it is recommended you use a mouse to allow optimising for screen real-estate.
|
||||
|
||||
<b>I integrated ImGui in my engine and the text or lines are blurry..</b>
|
||||
|
||||
- Try adjusting ImGui::GetIO().PixelCenterOffset to 0.0f or 0.5f.
|
||||
- In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f).
|
||||
|
||||
<b>Can you create elaborate/serious tools with ImGui?</b>
|
||||
|
||||
Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. There's no reason you cannot, and in my experience the simplicity of the API is very empowering. However note that ImGui is programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential.
|
||||
|
||||
<b>Can you reskin the look of ImGui?</b>
|
||||
|
||||
Yes, you can alter the look of the interface to some degree: changing colors, sizes and padding, font. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. The example below uses modified settings to create a more compact UI with different colors:
|
||||
|
||||

|
||||
|
||||
<b>Can you develop features xxxx for ImGui?</b>
|
||||
|
||||
Please use GitHub 'Issues' facilities to suggest and discuss improvements. If you are company and would like specific non-trivial features to be implemented, I am available for hire to work on or with ImGui. Donations are also welcome to support further work on the library.
|
||||
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
Developed by [Omar Cornut](http://www.miracleworld.net). The library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com).
|
||||
|
||||
Embeds [proggy_clean](http://www.proggyfonts.net/) font by Tristan Grimmer (also MIT license).
|
||||
Embeds [proggy_clean](http://upperbounds.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
|
||||
-------
|
||||
|
@ -5,98 +5,101 @@
|
||||
#include <dinput.h>
|
||||
#include "../../imgui.h"
|
||||
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
|
||||
|
||||
static HWND hWnd;
|
||||
static LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
|
||||
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
|
||||
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;
|
||||
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)
|
||||
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
|
||||
// If text or lines are blurry when integrating ImGui in your engine:
|
||||
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
|
||||
// - try adjusting ImGui::GetIO().PixelCenterOffset to 0.5f or 0.375f
|
||||
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)
|
||||
return;
|
||||
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)
|
||||
return;
|
||||
|
||||
// Copy and convert all vertices into a single contiguous 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];
|
||||
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
|
||||
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
|
||||
{
|
||||
vtx_dst->position.x = vtx_src->pos.x;
|
||||
vtx_dst->position.y = vtx_src->pos.y;
|
||||
vtx_dst->position.z = 0.0f;
|
||||
vtx_dst->color = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
|
||||
vtx_dst->tu = vtx_src->uv.x;
|
||||
vtx_dst->tv = vtx_src->uv.y;
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
}
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
|
||||
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
|
||||
{
|
||||
vtx_dst->position.x = vtx_src->pos.x;
|
||||
vtx_dst->position.y = vtx_src->pos.y;
|
||||
vtx_dst->position.z = 0.0f;
|
||||
vtx_dst->color = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
|
||||
vtx_dst->tu = vtx_src->uv.x;
|
||||
vtx_dst->tv = vtx_src->uv.y;
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
}
|
||||
g_pVB->Unlock();
|
||||
|
||||
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
|
||||
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
|
||||
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
|
||||
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
|
||||
|
||||
// Setup render state: alpha-blending, 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 );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, false );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
|
||||
|
||||
// Setup texture
|
||||
g_pd3dDevice->SetTexture( 0, g_pTexture );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
|
||||
// Setup texture
|
||||
g_pd3dDevice->SetTexture( 0, g_pTexture );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
|
||||
|
||||
// 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);
|
||||
// Setup orthographic projection matrix
|
||||
D3DXMATRIXA16 mat;
|
||||
D3DXMatrixIdentity(&mat);
|
||||
g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat);
|
||||
g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);
|
||||
D3DXMatrixOrthoOffCenterLH(&mat, 0.5f, ImGui::GetIO().DisplaySize.x+0.5f, ImGui::GetIO().DisplaySize.y+0.5f, 0.5f, -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];
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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];
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT InitD3D(HWND hWnd)
|
||||
@ -111,7 +114,7 @@ HRESULT InitD3D(HWND hWnd)
|
||||
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.EnableAutoDepthStencil = TRUE;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
// Create the D3DDevice
|
||||
if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice) < 0)
|
||||
@ -134,90 +137,90 @@ void Cleanup()
|
||||
|
||||
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
io.MouseDown[0] = true;
|
||||
return true;
|
||||
case WM_LBUTTONUP:
|
||||
io.MouseDown[0] = false;
|
||||
return true;
|
||||
case WM_RBUTTONDOWN:
|
||||
io.MouseDown[1] = true;
|
||||
return true;
|
||||
case WM_RBUTTONUP:
|
||||
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;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 1 && wParam < 256)
|
||||
io.AddInputCharacter((char)wParam);
|
||||
return true;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
Cleanup();
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
io.MouseDown[0] = true;
|
||||
return true;
|
||||
case WM_LBUTTONUP:
|
||||
io.MouseDown[0] = false;
|
||||
return true;
|
||||
case WM_RBUTTONDOWN:
|
||||
io.MouseDown[1] = true;
|
||||
return true;
|
||||
case WM_RBUTTONUP:
|
||||
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;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 1 && wParam < 256)
|
||||
io.AddInputCharacter((char)wParam);
|
||||
return true;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
Cleanup();
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
void InitImGui()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
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;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
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;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
|
||||
// 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;
|
||||
}
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
|
||||
// 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;
|
||||
}
|
||||
// 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;
|
||||
@ -225,28 +228,28 @@ INT64 time = 0;
|
||||
|
||||
void UpdateImGui()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup timestep
|
||||
INT64 current_time;
|
||||
QueryPerformanceCounter((LARGE_INTEGER *)¤t_time);
|
||||
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
|
||||
time = current_time;
|
||||
// Setup timestep
|
||||
INT64 current_time;
|
||||
QueryPerformanceCounter((LARGE_INTEGER *)¤t_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
|
||||
// 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();
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
@ -258,25 +261,25 @@ 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);
|
||||
|
||||
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
|
||||
return 1;
|
||||
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
|
||||
return 1;
|
||||
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
|
||||
return 1;
|
||||
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
|
||||
return 1;
|
||||
|
||||
// Initialize Direct3D
|
||||
// Initialize Direct3D
|
||||
if (InitD3D(hWnd) < 0)
|
||||
{
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
UnregisterClass(L"ImGui Example", wc.hInstance);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
UnregisterClass(L"ImGui Example", wc.hInstance);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Show the window
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hWnd);
|
||||
// Show the window
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
InitImGui();
|
||||
InitImGui();
|
||||
|
||||
// Enter the message loop
|
||||
MSG msg;
|
||||
@ -287,65 +290,65 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
UpdateImGui();
|
||||
|
||||
UpdateImGui();
|
||||
|
||||
// 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");
|
||||
// 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] = 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);
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Show another simple window
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
// 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();
|
||||
ImGui::Shutdown();
|
||||
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
|
||||
UnregisterClass(L"ImGui Example", wc.hInstance);
|
||||
return 0;
|
||||
|
@ -4,7 +4,7 @@
|
||||
# brew install glfw3
|
||||
#
|
||||
|
||||
CXXFLAGS=-framework OpenGL -framework Cocoa -framework IOKit
|
||||
CXXFLAGS=-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
|
||||
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
|
||||
|
@ -2,267 +2,278 @@
|
||||
#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 fontTex;
|
||||
static ImVec2 mousePosScale(1.0f, 1.0f);
|
||||
|
||||
// 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
|
||||
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
|
||||
// If text or lines are blurry when integrating ImGui in your engine:
|
||||
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
|
||||
// - try adjusting ImGui::GetIO().PixelCenterOffset to 0.5f or 0.375f
|
||||
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
|
||||
{
|
||||
if (cmd_lists_count == 0)
|
||||
return;
|
||||
if (cmd_lists_count == 0)
|
||||
return;
|
||||
|
||||
// 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);
|
||||
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
|
||||
// A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer.
|
||||
// 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);
|
||||
// Setup texture
|
||||
glBindTexture(GL_TEXTURE_2D, fontTex);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// 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();
|
||||
// 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];
|
||||
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));
|
||||
// Render command lists
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
int vtx_offset = 0;
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
{
|
||||
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);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
static const char* ImImpl_GetClipboardTextFn()
|
||||
{
|
||||
return glfwGetClipboardString(window);
|
||||
return glfwGetClipboardString(window);
|
||||
}
|
||||
|
||||
static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text + strlen(text);
|
||||
if (!text_end)
|
||||
text_end = text + strlen(text);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// GLFW callbacks to get events
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
fputs(description, stderr);
|
||||
fputs(description, stderr);
|
||||
}
|
||||
|
||||
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseWheel = (yoffset != 0.0f) ? yoffset > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
|
||||
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)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (action == GLFW_PRESS)
|
||||
io.KeysDown[key] = true;
|
||||
if (action == GLFW_RELEASE)
|
||||
io.KeysDown[key] = false;
|
||||
io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
|
||||
io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (action == GLFW_PRESS)
|
||||
io.KeysDown[key] = true;
|
||||
if (action == GLFW_RELEASE)
|
||||
io.KeysDown[key] = false;
|
||||
io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
|
||||
io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
|
||||
}
|
||||
|
||||
static void glfw_char_callback(GLFWwindow* window, unsigned int c)
|
||||
{
|
||||
if (c > 0 && c <= 255)
|
||||
ImGui::GetIO().AddInputCharacter((char)c);
|
||||
if (c > 0 && c <= 255)
|
||||
ImGui::GetIO().AddInputCharacter((char)c);
|
||||
}
|
||||
|
||||
// OpenGL code based on http://open.gl tutorials
|
||||
void InitGL()
|
||||
{
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(1);
|
||||
if (!glfwInit())
|
||||
exit(1);
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||
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);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||
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);
|
||||
|
||||
glewInit();
|
||||
glewInit();
|
||||
}
|
||||
|
||||
void InitImGui()
|
||||
{
|
||||
int w, h;
|
||||
glfwGetWindowSize(window, &w, &h);
|
||||
int w, h;
|
||||
int fb_w, fb_h;
|
||||
glfwGetWindowSize(window, &w, &h);
|
||||
glfwGetFramebufferSize(window, &fb_w, &fb_h);
|
||||
mousePosScale.x = (float)fb_w / w; // Some screens e.g. Retina display have framebuffer size != from window size, and mouse inputs are given in window/screen coordinates.
|
||||
mousePosScale.y = (float)fb_h / h;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
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;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
|
||||
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
|
||||
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
|
||||
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
|
||||
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
|
||||
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)fb_w, (float)fb_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.0f; // 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;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
|
||||
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
|
||||
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
|
||||
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
|
||||
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
|
||||
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
|
||||
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
|
||||
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
|
||||
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
|
||||
|
||||
// Load font texture
|
||||
glGenTextures(1, &fontTex);
|
||||
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);
|
||||
int tex_x, tex_y, tex_comp;
|
||||
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
|
||||
stbi_image_free(tex_data);
|
||||
// Load font texture
|
||||
glGenTextures(1, &fontTex);
|
||||
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);
|
||||
int tex_x, tex_y, tex_comp;
|
||||
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
|
||||
stbi_image_free(tex_data);
|
||||
}
|
||||
|
||||
void UpdateImGui()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup timestep
|
||||
static double time = 0.0f;
|
||||
const double current_time = glfwGetTime();
|
||||
io.DeltaTime = (float)(current_time - time);
|
||||
time = current_time;
|
||||
// Setup timestep
|
||||
static double time = 0.0f;
|
||||
const double current_time = glfwGetTime();
|
||||
io.DeltaTime = (float)(current_time - time);
|
||||
time = current_time;
|
||||
|
||||
// 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;
|
||||
// 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 * mousePosScale.x, (float)mouse_y * mousePosScale.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();
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
// Application code
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
InitGL();
|
||||
InitImGui();
|
||||
InitGL();
|
||||
InitImGui();
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseWheel = 0;
|
||||
glfwPollEvents();
|
||||
UpdateImGui();
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseWheel = 0;
|
||||
glfwPollEvents();
|
||||
UpdateImGui();
|
||||
|
||||
// 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");
|
||||
// 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] = 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);
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Show another simple window
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
// Show another simple window
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
ImGui::Shutdown();
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
ImGui::Shutdown();
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
BIN
extra_fonts/ProggyClean.zip
Normal file
BIN
extra_fonts/ProggySmall.zip
Normal file
71
extra_fonts/README.txt
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
Extra fonts for ImGui.
|
||||
THOSE FONTS ARE OPTIONAL.
|
||||
|
||||
ImGui embeds a copy of 'proggy_clean' that you can use without any external files.
|
||||
Export your own font with bmfont (www.angelcode.com/products/bmfont).
|
||||
|
||||
bmfont reads fonts (.ttf, .fon, etc.) and output a .fnt file and a texture file, e.g:
|
||||
|
||||
proggy_clean.fon --> [bmfont] ---> proggy_clean_13.fnt
|
||||
proggy_clean_13.png
|
||||
|
||||
Configure bmfont:
|
||||
|
||||
- Export .fnt as Binary
|
||||
- Tip: uncheck "Render from TrueType outline" and "Font Smoothing" for best result with non-anti-aliased type fonts.
|
||||
But you can experiment with other settings if you want anti-aliased fonts.
|
||||
|
||||
|
||||
(A) Use font data embedded in ImGui
|
||||
|
||||
// Access embedded font data
|
||||
const void* fnt_data; // pointer to FNT data
|
||||
unsigned fnt_size; // size of FNT data
|
||||
const void* png_data; // pointer to PNG data
|
||||
unsigned int png_size; // size of PNG data
|
||||
ImGui::GetDefaultFontData(&fnt_data, &fnt_size, &png_data, &png_size);
|
||||
|
||||
1. Load the .FNT data from 'fnt_data' (NB: this is done for you by default if you don't do anything)
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Font = new ImBitmapFont();
|
||||
io.Font->LoadFromMemory(fnt_data, fnt_size);
|
||||
|
||||
2. Load the .PNG data from 'png_data' into a texture
|
||||
|
||||
|
||||
|
||||
(B) Use fonts from external files
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
1. Load the .FNT data, e.g.
|
||||
|
||||
// proggy_clean_13 [default]
|
||||
io.Font->LoadFromFile("proggy_clean_13.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(0.0f/256.0f,0.0f/128);
|
||||
io.FontYOffset = +1;
|
||||
|
||||
// proggy_small_12
|
||||
io.Font = new ImBitmapFont();
|
||||
io.Font->LoadFromFile("proggy_small_12.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
|
||||
io.FontYOffset = +2;
|
||||
|
||||
// proggy_small_14
|
||||
io.Font = new ImBitmapFont();
|
||||
io.Font->LoadFromFile("proggy_small_14.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
|
||||
io.FontYOffset = +3;
|
||||
|
||||
// courier_new_16
|
||||
io.Font->LoadFromFile("courier_new_16.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(1.0f/256.0f,4.0f/128);
|
||||
|
||||
// courier_new_18
|
||||
io.Font->LoadFromFile("courier_new_18.fnt");
|
||||
io.FontTexUvForWhite = ImVec2(4.0f/256.0f,5.0f/256);
|
||||
|
||||
2. Load the matching .PNG data into a texture
|
||||
|
BIN
extra_fonts/courier_new_16.fnt
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
extra_fonts/courier_new_16.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
extra_fonts/courier_new_18.fnt
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
extra_fonts/courier_new_18.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
extra_fonts/proggy_clean_13.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_clean_13.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
extra_fonts/proggy_small_12.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_small_12.png
Normal file
After Width: | Height: | Size: 949 B |
BIN
extra_fonts/proggy_small_14.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_small_14.png
Normal file
After Width: | Height: | Size: 949 B |
33
imconfig.h
@ -1,41 +1,44 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// USER IMPLEMENTATION
|
||||
// This file contains compile-time options for ImGui.
|
||||
// Other options (memory allocation overrides, callbacks, etc.) can be set at runtime via the ImGuiIO structure - ImGui::GetIO().
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- 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 ImVector std::vector
|
||||
//#define ImVector MyVector
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
|
||||
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard(), etc.)
|
||||
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
|
||||
//#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)
|
||||
//---- Include imgui_user.cpp at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_CPP
|
||||
|
||||
//---- 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; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Freely implement extra functions within the ImGui:: namespace.
|
||||
//---- Declare helpers or widgets implemented in imgui_user.cpp or elsewhere, so end-user doesn't need to include multiple files.
|
||||
//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
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);
|
||||
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);
|
||||
};
|
||||
*/
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// stb_textedit.h - v1.3 - public domain - Sean Barrett
|
||||
// stb_textedit.h - v1.4 - public domain - Sean Barrett
|
||||
// Development of this library was sponsored by RAD Game Tools
|
||||
//
|
||||
// This C header file implements the guts of a multi-line text-editing
|
||||
@ -30,8 +30,9 @@
|
||||
//
|
||||
// VERSION HISTORY
|
||||
//
|
||||
// 1.3 (2013-06-19) fix mouse clicking to round to nearest char boundary
|
||||
// 1.2 (2013-05-27) fix some RAD types that had crept into the new code
|
||||
// 1.4 (2014-08-17) fix signed/unsigned warnings
|
||||
// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary
|
||||
// 1.2 (2014-05-27) fix some RAD types that had crept into the new code
|
||||
// 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE )
|
||||
// 1.0 (2012-07-26) improve documentation, initial public release
|
||||
// 0.3 (2012-02-24) bugfixes, single-line mode; insert mode
|
||||
@ -41,7 +42,7 @@
|
||||
// ADDITIONAL CONTRIBUTORS
|
||||
//
|
||||
// Ulf Winklemann: move-by-word in 1.1
|
||||
// Scott Graham: mouse selectiom bugfix in 1.3
|
||||
// Scott Graham: mouse selection bugfix in 1.3
|
||||
//
|
||||
// USAGE
|
||||
//
|
||||
@ -445,7 +446,7 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_insert(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||
|
||||
typedef struct
|
||||
@ -649,7 +650,7 @@ static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||
stb_textedit_delete_selection(str,state);
|
||||
// try to insert the characters
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
|
||||
stb_text_makeundo_insert(str, state, state->cursor, len);
|
||||
stb_text_makeundo_insert(state, state->cursor, len);
|
||||
state->cursor += len;
|
||||
state->has_preferred_x = 0;
|
||||
return 1;
|
||||
@ -684,7 +685,7 @@ retry:
|
||||
} else {
|
||||
stb_textedit_delete_selection(str,state); // implicity clamps
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
||||
stb_text_makeundo_insert(str, state, state->cursor, 1);
|
||||
stb_text_makeundo_insert(state, state->cursor, 1);
|
||||
++state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
@ -1007,13 +1008,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
int n = state->undo_rec[0].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
|
||||
memmove(state->undo_char, state->undo_char + n, state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE));
|
||||
memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=0; i < state->undo_point; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
|
||||
}
|
||||
--state->undo_point;
|
||||
memmove(state->undo_rec, state->undo_rec+1, state->undo_point*sizeof(state->undo_rec[0]));
|
||||
memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1031,13 +1032,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
int n = state->undo_rec[k].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
|
||||
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE));
|
||||
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=state->redo_point; i < k; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
|
||||
}
|
||||
++state->redo_point;
|
||||
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]));
|
||||
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1203,7 +1204,7 @@ static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
s->redo_point++;
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_insert(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length)
|
||||
{
|
||||
stb_text_createundo(&state->undostate, where, 0, length);
|
||||
}
|
||||
|
BIN
web/skinning_sample_01.png
Normal file
After Width: | Height: | Size: 18 KiB |