diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 99be4e8..babee5f 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -3,7 +3,7 @@
#include
#include "imgui_impl_dx9.h"
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 99be4e8..babee5f 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -3,7 +3,7 @@
#include
#include "imgui_impl_dx9.h"
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
index b1d2a40..0e3a754 100644
--- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
+++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
@@ -46,6 +46,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -111,6 +112,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 99be4e8..babee5f 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -3,7 +3,7 @@
#include
#include "imgui_impl_dx9.h"
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
index b1d2a40..0e3a754 100644
--- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
+++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
@@ -46,6 +46,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -111,6 +112,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp
index f6447e1..2d1f5c1 100644
--- a/examples/opengl_example/imgui_impl_glfw.cpp
+++ b/examples/opengl_example/imgui_impl_glfw.cpp
@@ -101,7 +101,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 99be4e8..babee5f 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -3,7 +3,7 @@
#include
#include "imgui_impl_dx9.h"
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
index b1d2a40..0e3a754 100644
--- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
+++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
@@ -46,6 +46,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -111,6 +112,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp
index f6447e1..2d1f5c1 100644
--- a/examples/opengl_example/imgui_impl_glfw.cpp
+++ b/examples/opengl_example/imgui_impl_glfw.cpp
@@ -101,7 +101,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
index 5406f42..d97b4cc 100644
--- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
+++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
@@ -40,6 +40,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -105,6 +106,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
@@ -328,6 +330,8 @@
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
+#else
+ (void)window;
#endif
return true;
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 99be4e8..babee5f 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -3,7 +3,7 @@
#include
#include "imgui_impl_dx9.h"
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
index b1d2a40..0e3a754 100644
--- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
+++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
@@ -46,6 +46,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -111,6 +112,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp
index f6447e1..2d1f5c1 100644
--- a/examples/opengl_example/imgui_impl_glfw.cpp
+++ b/examples/opengl_example/imgui_impl_glfw.cpp
@@ -101,7 +101,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
index 5406f42..d97b4cc 100644
--- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
+++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
@@ -40,6 +40,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -105,6 +106,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
@@ -328,6 +330,8 @@
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
+#else
+ (void)window;
#endif
return true;
diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp
index 0d885b0..ae42f14 100644
--- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp
+++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp
@@ -90,7 +90,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
@@ -218,6 +218,8 @@
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
+#else
+ (void)window;
#endif
return true;
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 99be4e8..babee5f 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -3,7 +3,7 @@
#include
#include "imgui_impl_dx9.h"
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
index b1d2a40..0e3a754 100644
--- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
+++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
@@ -46,6 +46,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -111,6 +112,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp
index f6447e1..2d1f5c1 100644
--- a/examples/opengl_example/imgui_impl_glfw.cpp
+++ b/examples/opengl_example/imgui_impl_glfw.cpp
@@ -101,7 +101,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
index 5406f42..d97b4cc 100644
--- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
+++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
@@ -40,6 +40,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -105,6 +106,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
@@ -328,6 +330,8 @@
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
+#else
+ (void)window;
#endif
return true;
diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp
index 0d885b0..ae42f14 100644
--- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp
+++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp
@@ -90,7 +90,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
@@ -218,6 +218,8 @@
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
+#else
+ (void)window;
#endif
return true;
diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt
index b577b87..1e9bc13 100644
--- a/extra_fonts/README.txt
+++ b/extra_fonts/README.txt
@@ -1,9 +1,13 @@
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files.
- Those are only provided as a convenience, you can load your own .TTF files.
+ The files in this folder are only provided as a convenience, you can use any of your own .TTF files.
Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
+ If you want to use icons in ImGui, a good idea is to merge an icon font within your main font, and refer to icons directly in your strings.
+ You can use headers files with definitions for popular icon fonts codepoints, by Juliette Foucaut, at https://github.com/juliettef/IconFontCppHeaders
+
+
---------------------------------
LOADING INSTRUCTIONS
---------------------------------
@@ -35,10 +39,10 @@
Combine two fonts into one:
- // Load main font
+ // Load a first font
io.Fonts->AddFontDefault();
- // Add character ranges and merge into main font
+ // Add character ranges and merge into the previous font
// The ranges array is not copied by the AddFont* functions and is used lazily
// so ensure it is available for duration of font usage
static const ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0 }; // will not be copied by AddFont* so keep in scope.
@@ -63,6 +67,16 @@
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
font->DisplayOffset.y += 1; // Render 1 pixel down
+
+---------------------------------
+ REMAP CODEPOINTS
+---------------------------------
+
+ All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will not work.
+ In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8.
+ You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code.
+
+
---------------------------------
EMBED A FONT IN SOURCE CODE
---------------------------------
@@ -75,8 +89,9 @@
ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...);
+
---------------------------------
- INCLUDED FONT FILES
+ FONT FILES INCLUDED IN THIS FOLDER
---------------------------------
Cousine-Regular.ttf
@@ -102,6 +117,7 @@
Copyright (c) 2012, Jonathan Pinhorn
SIL OPEN FONT LICENSE Version 1.1
+
---------------------------------
LINKS
---------------------------------
@@ -109,6 +125,7 @@
Icon fonts
https://fortawesome.github.io/Font-Awesome/
https://github.com/SamBrishes/kenney-icon-font
+ https://design.google.com/icons/
Typefaces for source code beautification
https://github.com/chrissimpkins/codeface
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -65,27 +64,6 @@
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D11_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
- RSDesc.FillMode = D3D11_FILL_SOLID;
- RSDesc.CullMode = D3D11_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D11RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDeviceContext->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx9_example/build_win32.bat b/examples/directx9_example/build_win32.bat
index 08a3475..c3647d4 100644
--- a/examples/directx9_example/build_win32.bat
+++ b/examples/directx9_example/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib
+cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj
index 83932c5..c10731d 100644
--- a/examples/directx9_example/directx9_example.vcxproj
+++ b/examples/directx9_example/directx9_example.vcxproj
@@ -86,7 +86,7 @@
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -99,7 +99,7 @@
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -116,7 +116,7 @@
true
true
$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
@@ -133,7 +133,7 @@
true
true
$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)
- d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)
+ d3d9.lib;%(AdditionalDependencies)
Console
diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp
index 813d58e..bb309a8 100644
--- a/examples/directx9_example/imgui_impl_dx9.cpp
+++ b/examples/directx9_example/imgui_impl_dx9.cpp
@@ -10,7 +10,7 @@
#include "imgui_impl_dx9.h"
// DirectX
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
@@ -26,9 +26,9 @@
struct CUSTOMVERTEX
{
- D3DXVECTOR3 pos;
- D3DCOLOR col;
- D3DXVECTOR2 uv;
+ float pos[3];
+ D3DCOLOR col;
+ float uv[2];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@@ -37,6 +37,11 @@
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
+ // Avoid rendering when minimized
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+ return;
+
// Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
@@ -53,14 +58,10 @@
return;
}
- // Backup some DX9 state (not all!)
- // FIXME: Backup/restore everything else
- D3DRENDERSTATETYPE last_render_state_to_backup[] = { D3DRS_CULLMODE, D3DRS_LIGHTING, D3DRS_ZENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_ALPHATESTENABLE, D3DRS_BLENDOP, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_SCISSORTESTENABLE };
- DWORD last_render_state_values[ARRAYSIZE(last_render_state_to_backup)] = { 0 };
- IDirect3DPixelShader9* last_ps; g_pd3dDevice->GetPixelShader( &last_ps );
- IDirect3DVertexShader9* last_vs; g_pd3dDevice->GetVertexShader( &last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->GetRenderState(last_render_state_to_backup[n], &last_render_state_values[n]);
+ // Backup the DX9 state
+ IDirect3DStateBlock9* d3d9_state_block = NULL;
+ if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
+ return;
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst;
@@ -75,12 +76,12 @@
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{
- vtx_dst->pos.x = vtx_src->pos.x;
- vtx_dst->pos.y = vtx_src->pos.y;
- vtx_dst->pos.z = 0.0f;
+ vtx_dst->pos[0] = vtx_src->pos.x;
+ vtx_dst->pos[1] = vtx_src->pos.y;
+ vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
- vtx_dst->uv.x = vtx_src->uv.x;
- vtx_dst->uv.y = vtx_src->uv.y;
+ vtx_dst->uv[0] = vtx_src->uv.x;
+ vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@@ -89,38 +90,47 @@
}
g_pVB->Unlock();
g_pIB->Unlock();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
- g_pd3dDevice->SetIndices( g_pIB );
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+ g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
+ g_pd3dDevice->SetIndices(g_pIB);
+ g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
- g_pd3dDevice->SetPixelShader( NULL );
- g_pd3dDevice->SetVertexShader( NULL );
- 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_ALPHATESTENABLE, false );
- g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
- 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 );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetPixelShader(NULL);
+ g_pd3dDevice->SetVertexShader(NULL);
+ 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_ALPHATESTENABLE, false);
+ g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ 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);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// 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 );
+ // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
+ {
+ const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+ D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
+ D3DMATRIX mat_projection =
+ {
+ 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
+ };
+ g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
+ g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
+ }
// Render command lists
int vtx_offset = 0;
@@ -138,20 +148,18 @@
else
{
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
- g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId );
- g_pd3dDevice->SetScissorRect( &r );
- g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
+ g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
+ g_pd3dDevice->SetScissorRect(&r);
+ g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
- // Restore some modified DX9 state (not all!)
- g_pd3dDevice->SetPixelShader( last_ps );
- g_pd3dDevice->SetVertexShader( last_vs );
- for (int n = 0; n < ARRAYSIZE(last_render_state_to_backup); n++)
- g_pd3dDevice->SetRenderState(last_render_state_to_backup[n], last_render_state_values[n]);
+ // Restore the DX9 state
+ d3d9_state_block->Apply();
+ d3d9_state_block->Release();
}
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -256,7 +264,7 @@
// Upload texture to graphics system
g_FontTexture = NULL;
- if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
+ if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false;
D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp
index 99be4e8..babee5f 100644
--- a/examples/directx9_example/main.cpp
+++ b/examples/directx9_example/main.cpp
@@ -3,7 +3,7 @@
#include
#include "imgui_impl_dx9.h"
-#include
+#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
index b1d2a40..0e3a754 100644
--- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
+++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp
@@ -46,6 +46,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -111,6 +112,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp
index f6447e1..2d1f5c1 100644
--- a/examples/opengl_example/imgui_impl_glfw.cpp
+++ b/examples/opengl_example/imgui_impl_glfw.cpp
@@ -101,7 +101,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
index 5406f42..d97b4cc 100644
--- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
+++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp
@@ -40,6 +40,7 @@
// Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@@ -105,6 +106,7 @@
// Restore modified GL state
glUseProgram(last_program);
+ glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
@@ -328,6 +330,8 @@
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
+#else
+ (void)window;
#endif
return true;
diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp
index 0d885b0..ae42f14 100644
--- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp
+++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp
@@ -90,7 +90,7 @@
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- glBindTexture(GL_TEXTURE_2D, last_texture);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
@@ -218,6 +218,8 @@
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
+#else
+ (void)window;
#endif
return true;
diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt
index b577b87..1e9bc13 100644
--- a/extra_fonts/README.txt
+++ b/extra_fonts/README.txt
@@ -1,9 +1,13 @@
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files.
- Those are only provided as a convenience, you can load your own .TTF files.
+ The files in this folder are only provided as a convenience, you can use any of your own .TTF files.
Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
+ If you want to use icons in ImGui, a good idea is to merge an icon font within your main font, and refer to icons directly in your strings.
+ You can use headers files with definitions for popular icon fonts codepoints, by Juliette Foucaut, at https://github.com/juliettef/IconFontCppHeaders
+
+
---------------------------------
LOADING INSTRUCTIONS
---------------------------------
@@ -35,10 +39,10 @@
Combine two fonts into one:
- // Load main font
+ // Load a first font
io.Fonts->AddFontDefault();
- // Add character ranges and merge into main font
+ // Add character ranges and merge into the previous font
// The ranges array is not copied by the AddFont* functions and is used lazily
// so ensure it is available for duration of font usage
static const ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0 }; // will not be copied by AddFont* so keep in scope.
@@ -63,6 +67,16 @@
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
font->DisplayOffset.y += 1; // Render 1 pixel down
+
+---------------------------------
+ REMAP CODEPOINTS
+---------------------------------
+
+ All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will not work.
+ In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8.
+ You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code.
+
+
---------------------------------
EMBED A FONT IN SOURCE CODE
---------------------------------
@@ -75,8 +89,9 @@
ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...);
+
---------------------------------
- INCLUDED FONT FILES
+ FONT FILES INCLUDED IN THIS FOLDER
---------------------------------
Cousine-Regular.ttf
@@ -102,6 +117,7 @@
Copyright (c) 2012, Jonathan Pinhorn
SIL OPEN FONT LICENSE Version 1.1
+
---------------------------------
LINKS
---------------------------------
@@ -109,6 +125,7 @@
Icon fonts
https://fortawesome.github.io/Font-Awesome/
https://github.com/SamBrishes/kenney-icon-font
+ https://design.google.com/icons/
Typefaces for source code beautification
https://github.com/chrissimpkins/codeface
diff --git a/imgui.cpp b/imgui.cpp
index 6216737..c70b464 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -20,12 +20,14 @@
- How can I help?
- How do I update to a newer version of ImGui?
- What is ImTextureID and how do I display an image?
- - Can I have multiple widgets with the same label? Can I have widget without a label? (Yes) / A primer on the use of labels/IDs in ImGui.
- I integrated ImGui in my engine and the text or lines are blurry..
- I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around..
+ - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+ - How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
- How can I load a different font than the default?
- How can I load multiple fonts?
- How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+ - How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
- ISSUES & TODO-LIST
- CODE
@@ -53,7 +55,7 @@
==============
- double-click title bar to collapse window
- - click upper right corner to close a window, available when 'bool* p_opened' is passed to ImGui::Begin()
+ - click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin()
- click and drag on lower right corner to resize window
- click and drag on any empty space to move window
- double-click/double-tap on lower right corner grip to auto-fit to content
@@ -78,7 +80,7 @@
- read the FAQ below this section!
- your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs.
- call and read ImGui::ShowTestWindow() for demo code demonstrating most features.
- - see examples/ folder for standalone sample applications. Prefer reading examples/opengl_example/ first at it is the simplest.
+ - see examples/ folder for standalone sample applications. Prefer reading examples/opengl_example/ first as it is the simplest.
you may be able to grab and copy a ready made imgui_impl_*** file from the examples/.
- customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme).
@@ -140,9 +142,8 @@
SwapBuffers();
}
- - after calling ImGui::NewFrame() you can read back flags from the IO structure to tell how ImGui intends to use your inputs.
- When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application.
- When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available.
+ - You can read back 'io.WantCaptureMouse', 'io.WantCaptureKeybord' etc. flags from the IO structure to tell how ImGui intends to use your
+ inputs and to know if you should share them or hide them from the rest of your application. Read the FAQ below for more information.
API BREAKING CHANGES
@@ -152,8 +153,21 @@
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
- - 2016/04/xx (1.49) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit*() functions
+ - 2016/06/xx (1.xx) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit*() functions
replaced ColorEdit4() third parameter 'bool show_alpha=true' to 'ImGuiColorEditFlags flags=0x01' where ImGuiColorEditFlags_Alpha=0x01 for dodgy compatibility
+ - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore.
+ If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you.
+ However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar.
+ This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color.
+ ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col)
+ {
+ float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)), k = title_bg_col.w / new_a;
+ return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a);
+ }
+ If this is confusing, pick the RGB value from title bar from an old screenshot and apply this as TitleBg/TitleBgActive. Or you may just create TitleBgActive from a tweaked TitleBg color.
+ - 2016/05/07 (1.49) - removed confusing set of GetInternalState(), GetInternalStateSize(), SetInternalState() functions. Now using CreateContext(), DestroyContext(), GetCurrentContext(), SetCurrentContext().
+ - 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection.
+ - 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen).
- 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer.
- 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337).
- 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337)
@@ -197,7 +211,7 @@
- 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete).
- 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete).
- 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons.
- - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "opened" state of a popup. BeginPopup() returns true if the popup is opened.
+ - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "open" state of a popup. BeginPopup() returns true if the popup is opened.
- 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same).
- 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete).
- 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API
@@ -278,6 +292,13 @@
ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use.
It is your responsibility to get textures uploaded to your GPU.
+ Q: I integrated ImGui in my engine and the text or lines are blurry..
+ A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f).
+ Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension.
+
+ Q: I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around..
+ A: Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1,y1,x2,y2) and NOT as (x1,y1,width,height).
+
Q: Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
A: Yes. A primer on the use of labels/IDs in ImGui..
@@ -366,17 +387,16 @@
TreePop();
}
- - When working with trees, ID are used to preserve the opened/closed state of each tree node.
+ - When working with trees, ID are used to preserve the open/close state of each tree node.
Depending on your use cases you may want to use strings, indices or pointers as ID.
e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change.
e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense!
- Q: I integrated ImGui in my engine and the text or lines are blurry..
- A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f).
- Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension.
-
- Q: I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around..
- A: Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1,y1,x2,y2) and NOT as (x1,y1,width,height).
+ Q: How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
+ A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame.
+ When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application.
+ When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available.
+ ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is a more accurate and complete than testing for ImGui::IsMouseHoveringAnyWindow().
Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13)
A: Use the font atlas to load the TTF file you want:
@@ -413,13 +433,21 @@
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese());
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
- A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board.
- Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
+ A: When loading a font, pass custom Unicode ranges to specify the glyphs to load.
+ All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese or CP-1251 for Cyrillic) will not work.
+ In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8.
+ You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code.
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
io.ImeWindowHandle = MY_HWND; // To input using Microsoft IME, give ImGui the hwnd of your application
+ As for text input, depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
+
+ Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
+ A: The easiest way is to create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, zero background alpha,
+ then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
+
- tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code.
- tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
- tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. this is also useful to set yourself in the context of another window (to get/set other settings)
@@ -433,7 +461,6 @@
The list below consist mostly of notes of things to do before they are requested/discussed by users (at that point it usually happens on the github)
- doc: add a proper documentation+regression testing system (#435)
- - window: maximum window size settings (per-axis). for large popups in particular user may not want the popup to fill all space.
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis).
- window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify.
@@ -441,7 +468,7 @@
- window: background options for child windows, border option (disable rounding)
- window: add a way to clear an existing window instead of appending (e.g. for tooltip override using a consistent api rather than the deferred tooltip)
- window: resizing from any sides? + mouse cursor directives for app.
-!- window: begin with *p_opened == false should return false.
+!- window: begin with *p_open == false should return false.
- window: get size/pos helpers given names (see discussion in #249)
- window: a collapsed window can be stuck behind the main menu bar?
- window: when window is small, prioritize resize button over close button.
@@ -522,12 +549,12 @@
- drag float: up/down axis
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
- tree node / optimization: avoid formatting when clipped.
- - tree node: clarify spacing, perhaps provide API to query exact spacing. provide API to draw the primitive. same with Bullet().
- tree node: tree-node/header right-most side doesn't take account of horizontal scrolling.
- - tree node: add treenode/treepush int variants? because (void*) cast from int warns on some platforms/settings
+ - tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings?
- tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits?
- tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer)
- - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (git issue #249)
+ - tree node: tweak color scheme to distinguish headers from selected tree node (#581)
+ - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249)
- settings: write more decent code to allow saving/loading new fields
- settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file
- style: add window shadows.
@@ -540,6 +567,9 @@
- style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle
- text: simple markup language for color change?
- font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
+ - font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance
+ - font: add support for kerning, probably optional. perhaps default to (32..128)^2 matrix ~ 36KB then hash fallback.
+ - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
- font: fix AddRemapChar() to work before font has been built.
- log: LogButtons() options for specifying depth and/or hiding depth slider
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
@@ -550,8 +580,9 @@
- shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus)
!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
- keyboard: full keyboard navigation and focus. (#323)
+ - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
- focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
- - input: rework IO system to be able to pass actual ordered/timestamped events.
+ - input: rework IO system to be able to pass actual ordered/timestamped events. (~#335, #71)
- input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style).
- input: support track pad style scrolling & slider edit.
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
@@ -560,9 +591,11 @@
- style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438)
- style editor: color child window height expressed in multiple of line height.
- remote: make a system like RemoteImGui first-class citizen/project (#75)
+ - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?)
- drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack.
- examples: directx9: save/restore device state more thoroughly.
- examples: window minimize, maximize (#583)
+ - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)
- optimization: use another hash function than crc32, e.g. FNV1a
- optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
- optimization: turn some the various stack vectors into statically-sized arrays
@@ -582,6 +615,7 @@
#include // sqrtf, fabsf, fmodf, powf, cosf, sinf, floorf, ceilf
#include // NULL, malloc, free, qsort, atoi
#include // vsnprintf, sscanf, printf
+#include // INT_MIN, INT_MAX
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include // intptr_t
#else
@@ -592,7 +626,6 @@
#pragma warning (disable: 4127) // condition expression is constant
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
-#define snprintf _snprintf
#endif
// Clang warnings with -Weverything
@@ -603,13 +636,13 @@
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
-#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning : function xx could be declared with attribute 'noreturn' warning // GetDefaultFontData() asserts which some implementation makes it never return.
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"// warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code)
-#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
-#endif
-#ifdef __GNUC__
+#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' //
+#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
+#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*'
+#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
+#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#endif
//-------------------------------------------------------------------------
@@ -678,15 +711,15 @@
// Context
//-----------------------------------------------------------------------------
-// We access everything through this pointer (always assumed to be != NULL)
-// You can swap the pointer to a different context by calling ImGui::SetInternalState()
-static ImGuiState GImDefaultState;
-ImGuiState* GImGui = &GImDefaultState;
-
-// Statically allocated default font atlas. This is merely a maneuver to keep ImFontAtlas definition at the bottom of the .h file (otherwise it'd be inside ImGuiIO)
-// Also we wouldn't be able to new() one at this point, before users may define IO.MemAllocFn.
+// Default context, default font atlas.
+// New contexts always point by default to this font atlas. It can be changed by reassigning the GetIO().Fonts variable.
+static ImGuiContext GImDefaultContext;
static ImFontAtlas GImDefaultFontAtlas;
+// Current context pointer. Implicitely used by all ImGui functions. Always assumed to be != NULL. Change to a different context by calling ImGui::SetCurrentContext()
+// ImGui is currently not thread-safe because of this variable. If you want thread-safety to allow N threads to access N different contexts, you might work around it by (A) having two instances of the ImGui code under different namespaces or (B) change this variable to be TLS. Further development aim to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586
+ImGuiContext* GImGui = &GImDefaultContext;
+
//-----------------------------------------------------------------------------
// User facing structures
//-----------------------------------------------------------------------------
@@ -704,7 +737,7 @@
ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines
ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
- IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node
+ IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns
ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar
ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
@@ -726,9 +759,9 @@
Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input
Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f);
Colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f);
- Colors[ImGuiCol_TitleBg] = ImVec4(0.50f, 0.50f, 1.00f, 0.45f);
+ Colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f);
Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f);
- Colors[ImGuiCol_TitleBgActive] = ImVec4(0.50f, 0.50f, 1.00f, 0.55f);
+ Colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f);
Colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f);
Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f);
Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f);
@@ -835,9 +868,6 @@
#define IM_F32_TO_INT8(_VAL) ((int)((_VAL) * 255.0f + 0.5f))
-#define IM_INT_MIN (-2147483647-1)
-#define IM_INT_MAX (2147483647)
-
// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n.
#ifdef _WIN32
#define IM_NEWLINE "\r\n"
@@ -1298,6 +1328,11 @@
return it->val_i;
}
+bool ImGuiStorage::GetBool(ImU32 key, bool default_val) const
+{
+ return GetInt(key, default_val ? 1 : 0) != 0;
+}
+
float ImGuiStorage::GetFloat(ImU32 key, float default_val) const
{
ImVector::iterator it = LowerBound(const_cast&>(Data), key);
@@ -1323,6 +1358,11 @@
return &it->val_i;
}
+bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val)
+{
+ return (bool*)GetIntRef(key, default_val ? 1 : 0);
+}
+
float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
{
ImVector::iterator it = LowerBound(Data, key);
@@ -1351,6 +1391,11 @@
it->val_i = val;
}
+void ImGuiStorage::SetBool(ImU32 key, bool val)
+{
+ SetInt(key, val ? 1 : 0);
+}
+
void ImGuiStorage::SetFloat(ImU32 key, float val)
{
ImVector::iterator it = LowerBound(Data, key);
@@ -1565,6 +1610,86 @@
}
//-----------------------------------------------------------------------------
+// ImGuiListClipper
+//-----------------------------------------------------------------------------
+
+static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
+{
+ // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage.
+ // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
+ ImGui::SetCursorPosY(pos_y);
+ ImGuiWindow* window = ImGui::GetCurrentWindow();
+ window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height;
+ window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y);
+}
+
+// Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
+// Use case B: Begin() called from constructor with items_height>0
+// FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style.
+void ImGuiListClipper::Begin(int count, float items_height)
+{
+ StartPosY = ImGui::GetCursorPosY();
+ ItemsHeight = items_height;
+ ItemsCount = count;
+ StepNo = 0;
+ DisplayEnd = DisplayStart = -1;
+ if (ItemsHeight > 0.0f)
+ {
+ ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
+ if (DisplayStart > 0)
+ SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
+ StepNo = 2;
+ }
+}
+
+void ImGuiListClipper::End()
+{
+ if (ItemsCount < 0)
+ return;
+ // In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user.
+ if (ItemsCount < INT_MAX)
+ SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
+ ItemsCount = -1;
+ StepNo = 3;
+}
+
+bool ImGuiListClipper::Step()
+{
+ if (ItemsCount == 0 || ImGui::GetCurrentWindowRead()->SkipItems)
+ {
+ ItemsCount = -1;
+ return false;
+ }
+ if (StepNo == 0) // Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height.
+ {
+ DisplayStart = 0;
+ DisplayEnd = 1;
+ StartPosY = ImGui::GetCursorPosY();
+ StepNo = 1;
+ return true;
+ }
+ if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
+ {
+ if (ItemsCount == 1) { ItemsCount = -1; return false; }
+ float items_height = ImGui::GetCursorPosY() - StartPosY;
+ IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically
+ ImGui::SetCursorPosY(StartPosY); // Rewind cursor so we can Begin() again, this time with a known height.
+ Begin(ItemsCount, items_height);
+ StepNo = 3;
+ return true;
+ }
+ if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
+ {
+ IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0);
+ StepNo = 3;
+ return true;
+ }
+ if (StepNo == 3) // Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop.
+ End();
+ return false;
+}
+
+//-----------------------------------------------------------------------------
// ImGuiWindow
//-----------------------------------------------------------------------------
@@ -1609,10 +1734,11 @@
DrawList->_OwnerName = Name;
RootWindow = NULL;
RootNonPopupWindow = NULL;
+ ParentWindow = NULL;
FocusIdxAllCounter = FocusIdxTabCounter = -1;
- FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = IM_INT_MAX;
- FocusIdxAllRequestNext = FocusIdxTabRequestNext = IM_INT_MAX;
+ FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = INT_MAX;
+ FocusIdxAllRequestNext = FocusIdxTabRequestNext = INT_MAX;
}
ImGuiWindow::~ImGuiWindow()
@@ -1646,7 +1772,7 @@
static void SetCurrentWindow(ImGuiWindow* window)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.CurrentWindow = window;
if (window)
g.FontSize = window->CalcFontSize();
@@ -1654,14 +1780,14 @@
ImGuiWindow* ImGui::GetParentWindow()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(g.CurrentWindowStack.Size >= 2);
return g.CurrentWindowStack[(unsigned int)g.CurrentWindowStack.Size - 2];
}
void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window = NULL)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.ActiveId = id;
g.ActiveIdAllowOverlap = false;
g.ActiveIdIsJustActivated = true;
@@ -1670,14 +1796,14 @@
void ImGui::SetHoveredID(ImGuiID id)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.HoveredId = id;
g.HoveredIdAllowOverlap = false;
}
void ImGui::KeepAliveID(ImGuiID id)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.ActiveId == id)
g.ActiveIdIsAlive = true;
}
@@ -1690,7 +1816,7 @@
return;
// Always align ourselves on pixel boundaries
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const float line_height = ImMax(window->DC.CurrentLineHeight, size.y);
const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y);
window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y);
@@ -1718,55 +1844,47 @@
ImGuiWindow* window = GetCurrentWindow();
window->DC.LastItemID = id ? *id : 0;
window->DC.LastItemRect = bb;
+ window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
if (IsClippedEx(bb, id, false))
- {
- window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
return false;
- }
// This is a sensible default, but widgets are free to override it after calling ItemAdd()
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (IsMouseHoveringRect(bb.Min, bb.Max))
{
- // Matching the behavior of IsHovered() but ignore if ActiveId==window->MoveID (we clicked on the window background)
+ // Matching the behavior of IsHovered() but allow if ActiveId==window->MoveID (we clicked on the window background)
// So that clicking on items with no active id such as Text() still returns true with IsItemHovered()
window->DC.LastItemHoveredRect = true;
- window->DC.LastItemHoveredAndUsable = false;
if (g.HoveredRootWindow == window->RootWindow)
if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveID))
if (IsWindowContentHoverable(window))
window->DC.LastItemHoveredAndUsable = true;
}
- else
- {
- window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
- }
return true;
}
bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindowRead();
if (!bb.Overlaps(window->ClipRect))
- {
if (!id || *id != GImGui->ActiveId)
if (clip_even_when_logged || !g.LogEnabled)
return true;
- }
return false;
}
+// NB: This is an internal helper. The user-facing IsItemHovered() is using data emitted from ItemAdd(), with a slightly different logic.
bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.HoveredId == 0 || g.HoveredId == id || g.HoveredIdAllowOverlap)
{
ImGuiWindow* window = GetCurrentWindowRead();
if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow))
- if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) && ImGui::IsMouseHoveringRect(bb.Min, bb.Max))
+ if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) && IsMouseHoveringRect(bb.Min, bb.Max))
if (IsWindowContentHoverable(g.HoveredRootWindow))
return true;
}
@@ -1775,7 +1893,7 @@
bool ImGui::FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_stop)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus;
window->FocusIdxAllCounter++;
@@ -1784,7 +1902,7 @@
// Process keyboard input at this point: TAB, Shift-TAB switch focus
// We can always TAB out of a widget that doesn't allow tabbing in.
- if (tab_stop && window->FocusIdxAllRequestNext == IM_INT_MAX && window->FocusIdxTabRequestNext == IM_INT_MAX && is_active && IsKeyPressedMap(ImGuiKey_Tab))
+ if (tab_stop && window->FocusIdxAllRequestNext == INT_MAX && window->FocusIdxTabRequestNext == INT_MAX && is_active && IsKeyPressedMap(ImGuiKey_Tab))
{
// Modulo on index will be applied at the end of frame once we've got the total counter of items.
window->FocusIdxTabRequestNext = window->FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1);
@@ -1808,10 +1926,10 @@
ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_x, float default_y)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImVec2 content_max;
if (size.x < 0.0f || size.y < 0.0f)
- content_max = g.CurrentWindow->Pos + ImGui::GetContentRegionMax();
+ content_max = g.CurrentWindow->Pos + GetContentRegionMax();
if (size.x <= 0.0f)
size.x = (size.x == 0.0f) ? default_x : ImMax(content_max.x - g.CurrentWindow->DC.CursorPos.x, 4.0f) + size.x;
if (size.y <= 0.0f)
@@ -1826,7 +1944,7 @@
ImGuiWindow* window = GetCurrentWindowRead();
if (wrap_pos_x == 0.0f)
- wrap_pos_x = ImGui::GetContentRegionMax().x + window->Pos.x;
+ wrap_pos_x = GetContentRegionMax().x + window->Pos.x;
else if (wrap_pos_x > 0.0f)
wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space
@@ -1866,21 +1984,33 @@
// Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself
// Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module
-void* ImGui::GetInternalState()
+ImGuiContext* ImGui::GetCurrentContext()
{
return GImGui;
}
-size_t ImGui::GetInternalStateSize()
+void ImGui::SetCurrentContext(ImGuiContext* ctx)
{
- return sizeof(ImGuiState);
+ GImGui = ctx;
}
-void ImGui::SetInternalState(void* state, bool construct)
+ImGuiContext* ImGui::CreateContext(void* (*malloc_fn)(size_t), void (*free_fn)(void*))
{
- if (construct)
- IM_PLACEMENT_NEW(state) ImGuiState();
- GImGui = (ImGuiState*)state;
+ if (!malloc_fn) malloc_fn = malloc;
+ ImGuiContext* ctx = (ImGuiContext*)malloc_fn(sizeof(ImGuiContext));
+ IM_PLACEMENT_NEW(ctx) ImGuiContext();
+ ctx->IO.MemAllocFn = malloc_fn;
+ ctx->IO.MemFreeFn = free_fn ? free_fn : free;
+ return ctx;
+}
+
+void ImGui::DestroyContext(ImGuiContext* ctx)
+{
+ void (*free_fn)(void*) = ctx->IO.MemFreeFn;
+ ctx->~ImGuiContext();
+ free_fn(ctx);
+ if (GImGui == ctx)
+ GImGui = NULL;
}
ImGuiIO& ImGui::GetIO()
@@ -1911,7 +2041,7 @@
void ImGui::NewFrame()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
// Check user data
IM_ASSERT(g.IO.DeltaTime >= 0.0f); // Need a positive DeltaTime (zero is tolerated but will cause some timing issues)
@@ -2000,8 +2130,35 @@
g.ActiveIdPreviousFrame = g.ActiveId;
g.ActiveIdIsAlive = false;
g.ActiveIdIsJustActivated = false;
- if (!g.ActiveId)
+
+ // Handle user moving window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows.
+ if (g.MovedWindowMoveId && g.MovedWindowMoveId == g.ActiveId)
+ {
+ KeepAliveID(g.MovedWindowMoveId);
+ IM_ASSERT(g.MovedWindow && g.MovedWindow->RootWindow);
+ IM_ASSERT(g.MovedWindow->RootWindow->MoveID == g.MovedWindowMoveId);
+ if (g.IO.MouseDown[0])
+ {
+ if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoMove))
+ {
+ g.MovedWindow->PosFloat += g.IO.MouseDelta;
+ if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings))
+ MarkSettingsDirty();
+ }
+ FocusWindow(g.MovedWindow);
+ }
+ else
+ {
+ SetActiveID(0);
+ g.MovedWindow = NULL;
+ g.MovedWindowMoveId = 0;
+ }
+ }
+ else
+ {
g.MovedWindow = NULL;
+ g.MovedWindowMoveId = 0;
+ }
// Delay saving settings so we don't spam disk too much
if (g.SettingsDirtyTimer > 0.0f)
@@ -2012,16 +2169,19 @@
}
// Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow
- g.HoveredWindow = FindHoveredWindow(g.IO.MousePos, false);
+ g.HoveredWindow = g.MovedWindow ? g.MovedWindow : FindHoveredWindow(g.IO.MousePos, false);
if (g.HoveredWindow && (g.HoveredWindow->Flags & ImGuiWindowFlags_ChildWindow))
g.HoveredRootWindow = g.HoveredWindow->RootWindow;
else
- g.HoveredRootWindow = FindHoveredWindow(g.IO.MousePos, true);
+ g.HoveredRootWindow = g.MovedWindow ? g.MovedWindow->RootWindow : FindHoveredWindow(g.IO.MousePos, true);
if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow())
{
g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f);
- if (g.HoveredRootWindow != modal_window)
+ ImGuiWindow* window = g.HoveredRootWindow;
+ while (window && window != modal_window)
+ window = window->ParentWindow;
+ if (!window)
g.HoveredRootWindow = g.HoveredWindow = NULL;
}
else
@@ -2036,7 +2196,7 @@
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
{
if (g.IO.MouseClicked[i])
- g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenedPopupStack.empty());
+ g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty());
mouse_any_down |= g.IO.MouseDown[i];
if (g.IO.MouseDown[i])
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i])
@@ -2046,7 +2206,7 @@
if (g.CaptureMouseNextFrame != -1)
g.IO.WantCaptureMouse = (g.CaptureMouseNextFrame != 0);
else
- g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenedPopupStack.empty());
+ g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenPopupStack.empty());
g.IO.WantCaptureKeyboard = (g.CaptureKeyboardNextFrame != -1) ? (g.CaptureKeyboardNextFrame != 0) : (g.ActiveId != 0);
g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId);
g.MouseCursor = ImGuiMouseCursor_Arrow;
@@ -2116,7 +2276,7 @@
// NB: behavior of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations.
void ImGui::Shutdown()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
// The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame)
if (g.IO.Fonts) // Testing for NULL to allow user to NULLify in case of running Shutdown() on multiple contexts. Bit hacky.
@@ -2145,7 +2305,7 @@
g.ColorModifiers.clear();
g.StyleModifiers.clear();
g.FontStack.clear();
- g.OpenedPopupStack.clear();
+ g.OpenPopupStack.clear();
g.CurrentPopupStack.clear();
for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++)
g.RenderDrawLists[i].clear();
@@ -2176,7 +2336,7 @@
static ImGuiIniData* FindWindowSettings(const char* name)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiID id = ImHash(name, 0);
for (int i = 0; i != g.Settings.Size; i++)
{
@@ -2203,7 +2363,7 @@
// FIXME: Write something less rubbish
static void LoadSettings()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const char* filename = g.IO.IniFilename;
if (!filename)
return;
@@ -2249,7 +2409,7 @@
static void SaveSettings()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const char* filename = g.IO.IniFilename;
if (!filename)
return;
@@ -2291,7 +2451,7 @@
static void MarkSettingsDirty()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.SettingsDirtyTimer <= 0.0f)
g.SettingsDirtyTimer = g.IO.IniSavingRate;
}
@@ -2369,6 +2529,7 @@
}
}
+// When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result.
void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect)
{
ImGuiWindow* window = GetCurrentWindow();
@@ -2386,7 +2547,7 @@
// This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal.
void ImGui::EndFrame()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame()
IM_ASSERT(g.FrameCountEnded != g.FrameCount); // ImGui::EndFrame() called multiple times, or forgot to call ImGui::NewFrame() again
@@ -2412,8 +2573,6 @@
ImGui::End();
// Click to focus window and start moving (after we're done with all our widgets)
- if (!g.ActiveId)
- g.MovedWindow = NULL;
if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0])
{
if (!(g.FocusedWindow && !g.FocusedWindow->WasActive && g.FocusedWindow->Active)) // Unless we just made a popup appear
@@ -2424,7 +2583,8 @@
if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove))
{
g.MovedWindow = g.HoveredWindow;
- SetActiveID(g.HoveredRootWindow->MoveID, g.HoveredRootWindow);
+ g.MovedWindowMoveId = g.HoveredRootWindow->MoveID;
+ SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow);
}
}
else if (g.FocusedWindow != NULL && GetFrontMostModalRootWindow() == NULL)
@@ -2458,7 +2618,7 @@
void ImGui::Render()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame()
if (g.FrameCountEnded != g.FrameCount)
@@ -2548,7 +2708,7 @@
// Pass text data straight to log (without being displayed)
void ImGui::LogText(const char* fmt, ...)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (!g.LogEnabled)
return;
@@ -2569,7 +2729,7 @@
// We split text into individual lines to add current tree level padding
static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = ImGui::GetCurrentWindowRead();
if (!text_end)
@@ -2620,7 +2780,7 @@
// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
// Hide anything after a '##' string
@@ -2647,7 +2807,7 @@
void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (!text_end)
@@ -2671,12 +2831,12 @@
if (text_len == 0)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
// Perform CPU side clipping for single clipped element to avoid using scissor state
ImVec2 pos = pos_min;
- const ImVec2 text_size = text_size_if_known ? *text_size_if_known : ImGui::CalcTextSize(text, text_display_end, false, 0.0f);
+ const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f);
if (!clip_max) clip_max = &pos_max;
bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
@@ -2715,9 +2875,9 @@
}
// Render a triangle to denote expanded/collapsed state
-void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale, bool shadow)
+void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool is_open, float scale, bool shadow)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
const float h = g.FontSize * 1.00f;
@@ -2725,7 +2885,7 @@
ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale);
ImVec2 a, b, c;
- if (opened)
+ if (is_open)
{
center.y -= r*0.25f;
a = center + ImVec2(0,1)*r;
@@ -2744,9 +2904,15 @@
window->DrawList->AddTriangleFilled(a, b, c, GetColorU32(ImGuiCol_Text));
}
+void ImGui::RenderBullet(ImVec2 pos)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ window->DrawList->AddCircleFilled(pos, GImGui->FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8);
+}
+
void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
ImVec2 a, b, c;
@@ -2769,7 +2935,7 @@
// CalcTextSize("") should return ImVec2(0.0f, GImGui->FontSize)
ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const char* text_display_end;
if (hide_text_after_double_hash)
@@ -2794,21 +2960,11 @@
}
// Helper to calculate coarse clipping of large list of evenly sized items.
-// NB: Prefer using the ImGuiListClipper higher-level helper if you can!
+// NB: Prefer using the ImGuiListClipper higher-level helper if you can! Read comments and instructions there on how those use this sort of pattern.
// NB: 'items_count' is only used to clamp the result, if you don't know your count you can use INT_MAX
-// If you are displaying thousands of items and you have a random access to the list, you can perform clipping yourself to save on CPU.
-// {
-// float item_height = ImGui::GetTextLineHeightWithSpacing();
-// int display_start, display_end;
-// ImGui::CalcListClipping(count, item_height, &display_start, &display_end); // calculate how many to clip/display
-// ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (display_start) * item_height); // advance cursor
-// for (int i = display_start; i < display_end; i++) // display only visible items
-// // TODO: display visible item
-// ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (count - display_end) * item_height); // advance cursor
-// }
void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindowRead();
if (g.LogEnabled)
{
@@ -2817,6 +2973,11 @@
*out_items_display_end = items_count;
return;
}
+ if (window->SkipItems)
+ {
+ *out_items_display_start = *out_items_display_end = 0;
+ return;
+ }
const ImVec2 pos = window->DC.CursorPos;
int start = (int)((window->ClipRect.Min.y - pos.y) / items_height);
@@ -2828,9 +2989,10 @@
}
// Find window given position, search front-to-back
+// FIXME: Note that we have a lag here because WindowRectClipped is updated in Begin() so windows moved by user via SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is called, aka before the next Begin(). Moving window thankfully isn't affected.
static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
for (int i = g.Windows.Size-1; i >= 0; i--)
{
ImGuiWindow* window = g.Windows[i];
@@ -2842,7 +3004,7 @@
continue;
// Using the clipped AABB so a child window will typically be clipped by its parent.
- ImRect bb(window->ClippedWindowRect.Min - g.Style.TouchExtraPadding, window->ClippedWindowRect.Max + g.Style.TouchExtraPadding);
+ ImRect bb(window->WindowRectClipped.Min - g.Style.TouchExtraPadding, window->WindowRectClipped.Max + g.Style.TouchExtraPadding);
if (bb.Contains(pos))
return window;
}
@@ -2854,7 +3016,7 @@
// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindowRead();
// Clip
@@ -2869,13 +3031,13 @@
bool ImGui::IsMouseHoveringWindow()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
return g.HoveredWindow == g.CurrentWindow;
}
bool ImGui::IsMouseHoveringAnyWindow()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
return g.HoveredWindow != NULL;
}
@@ -2905,7 +3067,7 @@
bool ImGui::IsKeyPressed(int key_index, bool repeat)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (key_index < 0) return false;
IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown));
const float t = g.IO.KeysDownDuration[key_index];
@@ -2923,7 +3085,7 @@
bool ImGui::IsKeyReleased(int key_index)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (key_index < 0) return false;
IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown));
if (g.IO.KeysDownDurationPrev[key_index] >= 0.0f && !g.IO.KeysDown[key_index])
@@ -2933,14 +3095,14 @@
bool ImGui::IsMouseDown(int button)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
return g.IO.MouseDown[button];
}
bool ImGui::IsMouseClicked(int button, bool repeat)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
const float t = g.IO.MouseDownDuration[button];
if (t == 0.0f)
@@ -2958,21 +3120,21 @@
bool ImGui::IsMouseReleased(int button)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
return g.IO.MouseReleased[button];
}
bool ImGui::IsMouseDoubleClicked(int button)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
return g.IO.MouseDoubleClicked[button];
}
bool ImGui::IsMouseDragging(int button, float lock_threshold)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
if (!g.IO.MouseDown[button])
return false;
@@ -2989,15 +3151,15 @@
// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed!
ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.CurrentPopupStack.Size > 0)
- return g.OpenedPopupStack[g.CurrentPopupStack.Size-1].MousePosOnOpen;
+ return g.OpenPopupStack[g.CurrentPopupStack.Size-1].MousePosOnOpen;
return g.IO.MousePos;
}
ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
if (lock_threshold < 0.0f)
lock_threshold = g.IO.MouseDragThreshold;
@@ -3009,7 +3171,7 @@
void ImGui::ResetMouseDragDelta(int button)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
// NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr
g.IO.MouseClickedPos[button] = g.IO.MousePos;
@@ -3049,7 +3211,7 @@
bool ImGui::IsItemActive()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.ActiveId)
{
ImGuiWindow* window = GetCurrentWindowRead();
@@ -3058,6 +3220,11 @@
return false;
}
+bool ImGui::IsItemClicked(int mouse_button)
+{
+ return IsMouseClicked(mouse_button) && IsItemHovered();
+}
+
bool ImGui::IsAnyItemHovered()
{
return GImGui->HoveredId != 0 || GImGui->HoveredIdPreviousFrame != 0;
@@ -3078,7 +3245,7 @@
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
void ImGui::SetItemAllowOverlap()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.HoveredId == g.CurrentWindow->DC.LastItemID)
g.HoveredIdAllowOverlap = true;
if (g.ActiveId == g.CurrentWindow->DC.LastItemID)
@@ -3114,7 +3281,7 @@
// Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value.
void ImGui::SetTooltipV(const char* fmt, va_list args)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImFormatStringV(g.Tooltip, IM_ARRAYSIZE(g.Tooltip), fmt, args);
}
@@ -3128,7 +3295,7 @@
static ImRect GetVisibleRect()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y)
return ImRect(g.IO.DisplayVisibleMin, g.IO.DisplayVisibleMax);
return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
@@ -3148,9 +3315,9 @@
static bool IsPopupOpen(ImGuiID id)
{
- ImGuiState& g = *GImGui;
- const bool opened = g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].PopupID == id;
- return opened;
+ ImGuiContext& g = *GImGui;
+ const bool is_open = g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupID == id;
+ return is_open;
}
// Mark popup as open (toggle toward open state).
@@ -3159,17 +3326,17 @@
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
void ImGui::OpenPopupEx(const char* str_id, bool reopen_existing)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiID id = window->GetID(str_id);
int current_stack_size = g.CurrentPopupStack.Size;
ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here)
- if (g.OpenedPopupStack.Size < current_stack_size + 1)
- g.OpenedPopupStack.push_back(popup_ref);
- else if (reopen_existing || g.OpenedPopupStack[current_stack_size].PopupID != id)
+ if (g.OpenPopupStack.Size < current_stack_size + 1)
+ g.OpenPopupStack.push_back(popup_ref);
+ else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupID != id)
{
- g.OpenedPopupStack.resize(current_stack_size+1);
- g.OpenedPopupStack[current_stack_size] = popup_ref;
+ g.OpenPopupStack.resize(current_stack_size+1);
+ g.OpenPopupStack[current_stack_size] = popup_ref;
}
}
@@ -3180,8 +3347,8 @@
static void CloseInactivePopups()
{
- ImGuiState& g = *GImGui;
- if (g.OpenedPopupStack.empty())
+ ImGuiContext& g = *GImGui;
+ if (g.OpenPopupStack.empty())
return;
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
@@ -3189,9 +3356,9 @@
int n = 0;
if (g.FocusedWindow)
{
- for (n = 0; n < g.OpenedPopupStack.Size; n++)
+ for (n = 0; n < g.OpenPopupStack.Size; n++)
{
- ImGuiPopupRef& popup = g.OpenedPopupStack[n];
+ ImGuiPopupRef& popup = g.OpenPopupStack[n];
if (!popup.Window)
continue;
IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0);
@@ -3199,21 +3366,21 @@
continue;
bool has_focus = false;
- for (int m = n; m < g.OpenedPopupStack.Size && !has_focus; m++)
- has_focus = (g.OpenedPopupStack[m].Window && g.OpenedPopupStack[m].Window->RootWindow == g.FocusedWindow->RootWindow);
+ for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++)
+ has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.FocusedWindow->RootWindow);
if (!has_focus)
break;
}
}
- if (n < g.OpenedPopupStack.Size) // This test is not required but it allows to set a useful breakpoint on the line below
- g.OpenedPopupStack.resize(n);
+ if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a useful breakpoint on the line below
+ g.OpenPopupStack.resize(n);
}
static ImGuiWindow* GetFrontMostModalRootWindow()
{
- ImGuiState& g = *GImGui;
- if (!g.OpenedPopupStack.empty())
- if (ImGuiWindow* front_most_popup = g.OpenedPopupStack.back().Window)
+ ImGuiContext& g = *GImGui;
+ for (int n = g.OpenPopupStack.Size-1; n >= 0; n--)
+ if (ImGuiWindow* front_most_popup = g.OpenPopupStack.Data[n].Window)
if (front_most_popup->Flags & ImGuiWindowFlags_Modal)
return front_most_popup;
return NULL;
@@ -3221,44 +3388,44 @@
static void ClosePopupToLevel(int remaining)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (remaining > 0)
- ImGui::FocusWindow(g.OpenedPopupStack[remaining-1].Window);
+ ImGui::FocusWindow(g.OpenPopupStack[remaining-1].Window);
else
- ImGui::FocusWindow(g.OpenedPopupStack[0].ParentWindow);
- g.OpenedPopupStack.resize(remaining);
+ ImGui::FocusWindow(g.OpenPopupStack[0].ParentWindow);
+ g.OpenPopupStack.resize(remaining);
}
static void ClosePopup(ImGuiID id)
{
if (!IsPopupOpen(id))
return;
- ImGuiState& g = *GImGui;
- ClosePopupToLevel(g.OpenedPopupStack.Size - 1);
+ ImGuiContext& g = *GImGui;
+ ClosePopupToLevel(g.OpenPopupStack.Size - 1);
}
// Close the popup we have begin-ed into.
void ImGui::CloseCurrentPopup()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
int popup_idx = g.CurrentPopupStack.Size - 1;
- if (popup_idx < 0 || popup_idx > g.OpenedPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupID != g.OpenedPopupStack[popup_idx].PopupID)
+ if (popup_idx < 0 || popup_idx > g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupID != g.OpenPopupStack[popup_idx].PopupID)
return;
- while (popup_idx > 0 && g.OpenedPopupStack[popup_idx].Window && (g.OpenedPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu))
+ while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu))
popup_idx--;
ClosePopupToLevel(popup_idx);
}
static inline void ClearSetNextWindowData()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowPosCond = g.SetNextWindowSizeCond = g.SetNextWindowContentSizeCond = g.SetNextWindowCollapsedCond = 0;
- g.SetNextWindowFocus = false;
+ g.SetNextWindowSizeConstraint = g.SetNextWindowFocus = false;
}
static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
const ImGuiID id = window->GetID(str_id);
if (!IsPopupOpen(id))
@@ -3276,18 +3443,18 @@
else
ImFormatString(name, 20, "##popup_%08x", id); // Not recycling, so we can close/open during the same frame
- bool opened = ImGui::Begin(name, NULL, flags);
+ bool is_open = ImGui::Begin(name, NULL, flags);
if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders;
- if (!opened) // opened can be 'false' when the popup is completely clipped (e.g. zero size display)
+ if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
ImGui::EndPopup();
- return opened;
+ return is_open;
}
bool ImGui::BeginPopup(const char* str_id)
{
- if (GImGui->OpenedPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance
+ if (GImGui->OpenPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance
{
ClearSetNextWindowData(); // We behave like Begin() and need to consume those values
return false;
@@ -3295,9 +3462,9 @@
return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders);
}
-bool ImGui::BeginPopupModal(const char* name, bool* p_opened, ImGuiWindowFlags extra_flags)
+bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags extra_flags)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
const ImGuiID id = window->GetID(name);
if (!IsPopupOpen(id))
@@ -3307,16 +3474,16 @@
}
ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings;
- bool opened = ImGui::Begin(name, p_opened, flags);
- if (!opened || (p_opened && !*p_opened)) // Opened can be 'false' when the popup is completely clipped (e.g. zero size display)
+ bool is_open = ImGui::Begin(name, p_open, flags);
+ if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
{
ImGui::EndPopup();
- if (opened)
+ if (is_open)
ClosePopup(id);
return false;
}
- return opened;
+ return is_open;
}
void ImGui::EndPopup()
@@ -3339,26 +3506,26 @@
// driven by click position.
bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button)
{
- if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(mouse_button))
- ImGui::OpenPopupEx(str_id, false);
- return ImGui::BeginPopup(str_id);
+ if (IsItemHovered() && IsMouseClicked(mouse_button))
+ OpenPopupEx(str_id, false);
+ return BeginPopup(str_id);
}
bool ImGui::BeginPopupContextWindow(bool also_over_items, const char* str_id, int mouse_button)
{
if (!str_id) str_id = "window_context_menu";
- if (ImGui::IsMouseHoveringWindow() && ImGui::IsMouseClicked(mouse_button))
- if (also_over_items || !ImGui::IsAnyItemHovered())
- ImGui::OpenPopupEx(str_id, true);
- return ImGui::BeginPopup(str_id);
+ if (IsMouseHoveringWindow() && IsMouseClicked(mouse_button))
+ if (also_over_items || !IsAnyItemHovered())
+ OpenPopupEx(str_id, true);
+ return BeginPopup(str_id);
}
bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button)
{
if (!str_id) str_id = "void_context_menu";
- if (!ImGui::IsMouseHoveringAnyWindow() && ImGui::IsMouseClicked(mouse_button))
- ImGui::OpenPopupEx(str_id, true);
- return ImGui::BeginPopup(str_id);
+ if (!IsMouseHoveringAnyWindow() && IsMouseClicked(mouse_button))
+ OpenPopupEx(str_id, true);
+ return BeginPopup(str_id);
}
bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
@@ -3366,7 +3533,7 @@
ImGuiWindow* window = GetCurrentWindow();
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
- const ImVec2 content_avail = ImGui::GetContentRegionAvail();
+ const ImVec2 content_avail = GetContentRegionAvail();
ImVec2 size = ImFloor(size_arg);
if (size.x <= 0.0f)
{
@@ -3415,7 +3582,7 @@
else
{
// When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting.
- ImVec2 sz = ImGui::GetWindowSize();
+ ImVec2 sz = GetWindowSize();
if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f
sz.x = ImMax(4.0f, sz.x);
if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY)
@@ -3433,7 +3600,7 @@
// Helper to create a child window / scrolling region that looks like a normal widget frame.
bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]);
ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding);
@@ -3452,14 +3619,14 @@
static void CheckStacksSize(ImGuiWindow* window, bool write)
{
// NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
int* p_backup = &window->DC.StackSizesBackup[0];
- { int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot PopID()
- { int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot EndGroup()
- { int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot EndPopup()/EndMenu()
- { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot PopStyleColor()
- { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot PopStyleVar()
- { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot PopFont()
+ { int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID Mismatch!"); p_backup++; } // User forgot PopID()
+ { int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // User forgot EndGroup()
+ { int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++; }// User forgot EndPopup()/EndMenu()
+ { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // User forgot PopStyleColor()
+ { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // User forgot PopStyleVar()
+ { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); p_backup++; } // User forgot PopFont()
IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
}
@@ -3494,7 +3661,7 @@
ImGuiWindow* ImGui::FindWindowByName(const char* name)
{
// FIXME-OPT: Store sorted hashes -> pointers so we can do a bissection in a contiguous block
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiID id = ImHash(name, 0);
for (int i = 0; i < g.Windows.Size; i++)
if (g.Windows[i]->ID == id)
@@ -3504,7 +3671,7 @@
static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
// Create window the first time
ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
@@ -3568,6 +3735,31 @@
return window;
}
+static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size)
+{
+ ImGuiContext& g = *GImGui;
+ if (g.SetNextWindowSizeConstraint)
+ {
+ // Using -1,-1 on either X/Y axis to preserve the current size.
+ ImRect cr = g.SetNextWindowSizeConstraintRect;
+ new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x;
+ new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y;
+ if (g.SetNextWindowSizeConstraintCallback)
+ {
+ ImGuiSizeConstraintCallbackData data;
+ data.UserData = g.SetNextWindowSizeConstraintCallbackUserData;
+ data.Pos = window->Pos;
+ data.CurrentSize = window->SizeFull;
+ data.DesiredSize = new_size;
+ g.SetNextWindowSizeConstraintCallback(&data);
+ new_size = data.DesiredSize;
+ }
+ }
+ if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize)))
+ new_size = ImMax(new_size, g.Style.WindowMinSize);
+ window->SizeFull = new_size;
+}
+
// Push a new ImGui window to add widgets to.
// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair.
// - Begin/End can be called multiple times during the frame with the same window name to append content.
@@ -3575,16 +3767,16 @@
// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file).
// You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file.
// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned.
-// - Passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
+// - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin().
-bool ImGui::Begin(const char* name, bool* p_opened, ImGuiWindowFlags flags)
+bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
- return ImGui::Begin(name, p_opened, ImVec2(0.f, 0.f), -1.0f, flags);
+ return ImGui::Begin(name, p_open, ImVec2(0.f, 0.f), -1.0f, flags);
}
-bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags)
+bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
IM_ASSERT(name != NULL); // Window name required
IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame()
@@ -3619,7 +3811,7 @@
bool window_was_active = (window->LastFrameActive == current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on
if (flags & ImGuiWindowFlags_Popup)
{
- ImGuiPopupRef& popup_ref = g.OpenedPopupStack[g.CurrentPopupStack.Size];
+ ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size];
window_was_active &= (window->PopupID == popup_ref.PopupID);
window_was_active &= (window == popup_ref.Window);
popup_ref.Window = window;
@@ -3633,7 +3825,7 @@
bool window_pos_set_by_api = false, window_size_set_by_api = false;
if (g.SetNextWindowPosCond)
{
- const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this anymore :( need to look into that.
+ const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this saving/restore anymore :( need to look into that.
if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowPosAllowFlags |= ImGuiSetCond_Appearing;
window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0;
if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f)
@@ -3684,6 +3876,7 @@
for (root_non_popup_idx = root_idx; root_non_popup_idx > 0; root_non_popup_idx--)
if (!(g.CurrentWindowStack[root_non_popup_idx]->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)))
break;
+ window->ParentWindow = parent_window;
window->RootWindow = g.CurrentWindowStack[root_idx];
window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // This is merely for displaying the TitleBgActive color.
@@ -3693,12 +3886,12 @@
window->Active = true;
window->IndexWithinParent = 0;
window->BeginCount = 0;
- window->DrawList->Clear();
window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
window->LastFrameActive = current_frame;
window->IDStack.resize(1);
- // Setup texture, outer clipping rectangle
+ // Clear draw list, setup texture, outer clipping rectangle
+ window->DrawList->Clear();
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
ImRect fullscreen_rect(GetVisibleRect());
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ComboBox|ImGuiWindowFlags_Popup)))
@@ -3789,7 +3982,6 @@
window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
if (window->AutoFitFramesY > 0)
window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
- window->Size = window->TitleBarRect().GetSize();
}
else
{
@@ -3807,17 +3999,12 @@
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
}
- window->Size = window->SizeFull;
}
- // Minimum window size
- if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize)))
- {
- window->SizeFull = ImMax(window->SizeFull, style.WindowMinSize);
- if (!window->Collapsed)
- window->Size = window->SizeFull;
- }
-
+ // Apply minimum/maximum window size constraints and final size
+ ApplySizeFullWithConstraint(window, window->SizeFull);
+ window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull;
+
// POSITION
// Position child window
@@ -3829,7 +4016,7 @@
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup))
{
window->Pos = window->PosFloat = parent_window->DC.CursorPos;
- window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user.
+ window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user passed via BeginChild()->Begin().
}
bool window_pos_center = false;
@@ -3865,28 +4052,6 @@
window->PosFloat = g.IO.MousePos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
}
- // User moving window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows.
- KeepAliveID(window->MoveID);
- if (g.ActiveId == window->MoveID)
- {
- if (g.IO.MouseDown[0])
- {
- if (!(flags & ImGuiWindowFlags_NoMove))
- {
- window->PosFloat += g.IO.MouseDelta;
- if (!(flags & ImGuiWindowFlags_NoSavedSettings))
- MarkSettingsDirty();
- }
- IM_ASSERT(g.MovedWindow != NULL);
- FocusWindow(g.MovedWindow);
- }
- else
- {
- SetActiveID(0);
- g.MovedWindow = NULL; // Not strictly necessary but doing it for sanity.
- }
- }
-
// Clamp position so it stays visible
if (!(flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip))
{
@@ -3906,10 +4071,10 @@
window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f);
// Prepare for focus requests
- window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext == IM_INT_MAX || window->FocusIdxAllCounter == -1) ? IM_INT_MAX : (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1);
- window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext == IM_INT_MAX || window->FocusIdxTabCounter == -1) ? IM_INT_MAX : (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1);
+ window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext == INT_MAX || window->FocusIdxAllCounter == -1) ? INT_MAX : (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1);
+ window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext == INT_MAX || window->FocusIdxTabCounter == -1) ? INT_MAX : (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1);
window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1;
- window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX;
+ window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX;
// Apply scrolling
if (window->ScrollTarget.x < FLT_MAX)
@@ -3959,14 +4124,15 @@
if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0])
{
// Manual auto-fit when double-clicking
- window->SizeFull = size_auto_fit;
+ ApplySizeFullWithConstraint(window, size_auto_fit);
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
SetActiveID(0);
}
else if (held)
{
- window->SizeFull = ImMax(window->SizeFull + g.IO.MouseDelta, style.WindowMinSize);
+ // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
+ ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos);
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
}
@@ -3995,7 +4161,7 @@
bg_color.w = bg_alpha;
bg_color.w *= style.Alpha;
if (bg_color.w > 0.0f)
- window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding);
+ window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 15 : 4|8);
// Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar))
@@ -4037,6 +4203,12 @@
}
}
+ // Update ContentsRegionMax. All the variable it depends on are set above in this function.
+ window->ContentsRegionRect.Min.x = -window->Scroll.x + window->WindowPadding.x;
+ window->ContentsRegionRect.Min.x = -window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight();
+ window->ContentsRegionRect.Max.x = -window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x));
+ window->ContentsRegionRect.Max.y = -window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y));
+
// Setup drawing context
window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x;
window->DC.ColumnsOffsetX = 0.0f;
@@ -4076,12 +4248,12 @@
// Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar))
{
- if (p_opened != NULL)
+ if (p_open != NULL)
{
const float pad = 2.0f;
const float rad = (window->TitleBarHeight() - pad*2.0f) * 0.5f;
if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-pad - rad, pad + rad), rad))
- *p_opened = false;
+ *p_open = false;
}
const ImVec2 text_size = CalcTextSize(name, NULL, true);
@@ -4090,9 +4262,9 @@
ImVec2 text_min = window->Pos + style.FramePadding;
ImVec2 text_max = window->Pos + ImVec2(window->Size.x - style.FramePadding.x, style.FramePadding.y*2 + text_size.y);
- ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_opened ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton()
+ ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton()
bool pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0;
- bool pad_right = (p_opened != NULL);
+ bool pad_right = (p_open != NULL);
if (style.WindowTitleAlign & ImGuiAlign_Center) pad_right = pad_left;
if (pad_left) text_min.x += g.FontSize + style.ItemInnerSpacing.x;
if (pad_right) text_max.x -= g.FontSize + style.ItemInnerSpacing.x;
@@ -4100,8 +4272,8 @@
}
// Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
- window->ClippedWindowRect = window->Rect();
- window->ClippedWindowRect.Clip(window->ClipRect);
+ window->WindowRectClipped = window->Rect();
+ window->WindowRectClipped.Clip(window->ClipRect);
// Pressing CTRL+C while holding on a window copy its content to the clipboard
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
@@ -4118,17 +4290,18 @@
// Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior.
const ImRect title_bar_rect = window->TitleBarRect();
const float border_size = window->BorderSize;
- ImRect clip_rect;
- clip_rect.Min.x = title_bar_rect.Min.x + ImMax(border_size, (float)(int)(window->WindowPadding.x*0.5f));
- clip_rect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + border_size;
- clip_rect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, (float)(int)(window->WindowPadding.x*0.5f));
- clip_rect.Max.y = window->Pos.y + window->Size.y - border_size - window->ScrollbarSizes.y;
+ ImRect clip_rect; // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
+ clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
+ clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size);
+ clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
+ clip_rect.Max.y = ImFloor(0.5f + window->Pos.y + window->Size.y - window->ScrollbarSizes.y - border_size);
PushClipRect(clip_rect.Min, clip_rect.Max, true);
// Clear 'accessed' flag last thing
if (first_begin_of_the_frame)
window->Accessed = false;
window->BeginCount++;
+ g.SetNextWindowSizeConstraint = false;
// Child window can be out of sight and have "negative" clip windows.
// Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar).
@@ -4138,7 +4311,7 @@
window->Collapsed = parent_window && parent_window->Collapsed;
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
- window->Collapsed |= (window->ClippedWindowRect.Min.x >= window->ClippedWindowRect.Max.x || window->ClippedWindowRect.Min.y >= window->ClippedWindowRect.Max.y);
+ window->Collapsed |= (window->WindowRectClipped.Min.x >= window->WindowRectClipped.Max.x || window->WindowRectClipped.Min.y >= window->WindowRectClipped.Max.y);
// We also hide the window from rendering because we've already added its border to the command list.
// (we could perform the check earlier in the function but it is simpler at this point)
@@ -4155,15 +4328,15 @@
void ImGui::End()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
- ImGui::Columns(1, "#CloseColumns");
+ Columns(1, "#CloseColumns");
PopClipRect(); // inner window clip rectangle
// Stop logging
if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging
- ImGui::LogFinish();
+ LogFinish();
// Pop
// NB: we don't clear 'window->RootWindow'. The pointer is allowed to live until the next call to Begin().
@@ -4181,7 +4354,7 @@
// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal.
static void Scrollbar(ImGuiWindow* window, bool horizontal)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY");
@@ -4279,7 +4452,7 @@
// Moving window to front of display (which happens to be back of our sorted list)
void ImGui::FocusWindow(ImGuiWindow* window)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
// Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing.
g.FocusedWindow = window;
@@ -4295,7 +4468,7 @@
// Steal focus on active widgets
if (window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement should be unnecessary. Need further testing before removing it..
if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != window)
- ImGui::SetActiveID(0);
+ SetActiveID(0);
// Bring to front
if ((window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) || g.Windows.back() == window)
@@ -4344,7 +4517,7 @@
if (w < 0.0f)
{
// Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well.
- float width_to_right_edge = ImGui::GetContentRegionAvail().x;
+ float width_to_right_edge = GetContentRegionAvail().x;
w = ImMax(1.0f, width_to_right_edge + w);
}
w = (float)(int)w;
@@ -4353,7 +4526,7 @@
static void SetCurrentFont(ImFont* font)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?
IM_ASSERT(font->Scale > 0.0f);
g.Font = font;
@@ -4364,7 +4537,7 @@
void ImGui::PushFont(ImFont* font)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (!font)
font = g.IO.Fonts->Fonts[0];
SetCurrentFont(font);
@@ -4374,7 +4547,7 @@
void ImGui::PopFont()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.CurrentWindow->DrawList->PopTextureID();
g.FontStack.pop_back();
SetCurrentFont(g.FontStack.empty() ? g.IO.Fonts->Fonts[0] : g.FontStack.back());
@@ -4424,7 +4597,7 @@
void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiColMod backup;
backup.Col = idx;
backup.PreviousValue = g.Style.Colors[idx];
@@ -4434,7 +4607,7 @@
void ImGui::PopStyleColor(int count)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
while (count > 0)
{
ImGuiColMod& backup = g.ColorModifiers.back();
@@ -4446,7 +4619,7 @@
static float* GetStyleVarFloatAddr(ImGuiStyleVar idx)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
switch (idx)
{
case ImGuiStyleVar_Alpha: return &g.Style.Alpha;
@@ -4461,7 +4634,7 @@
static ImVec2* GetStyleVarVec2Addr(ImGuiStyleVar idx)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
switch (idx)
{
case ImGuiStyleVar_WindowPadding: return &g.Style.WindowPadding;
@@ -4475,7 +4648,7 @@
void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
float* pvar = GetStyleVarFloatAddr(idx);
IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a float.
ImGuiStyleMod backup;
@@ -4488,7 +4661,7 @@
void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImVec2* pvar = GetStyleVarVec2Addr(idx);
IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a ImVec2.
ImGuiStyleMod backup;
@@ -4500,7 +4673,7 @@
void ImGui::PopStyleVar(int count)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
while (count > 0)
{
ImGuiStyleMod& backup = g.StyleModifiers.back();
@@ -4568,28 +4741,32 @@
bool ImGui::IsWindowHovered()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow);
}
bool ImGui::IsWindowFocused()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
return g.FocusedWindow == g.CurrentWindow;
}
bool ImGui::IsRootWindowFocused()
{
- ImGuiState& g = *GImGui;
- ImGuiWindow* root_window = g.CurrentWindow->RootWindow;
- return g.FocusedWindow == root_window;
+ ImGuiContext& g = *GImGui;
+ return g.FocusedWindow == g.CurrentWindow->RootWindow;
}
bool ImGui::IsRootWindowOrAnyChildFocused()
{
- ImGuiState& g = *GImGui;
- ImGuiWindow* root_window = g.CurrentWindow->RootWindow;
- return g.FocusedWindow && g.FocusedWindow->RootWindow == root_window;
+ ImGuiContext& g = *GImGui;
+ return g.FocusedWindow && g.FocusedWindow->RootWindow == g.CurrentWindow->RootWindow;
+}
+
+bool ImGui::IsRootWindowOrAnyChildHovered()
+{
+ ImGuiContext& g = *GImGui;
+ return g.HoveredRootWindow && (g.HoveredRootWindow == g.CurrentWindow->RootWindow) && IsWindowContentHoverable(g.HoveredRootWindow);
}
float ImGui::GetWindowWidth()
@@ -4606,7 +4783,7 @@
ImVec2 ImGui::GetWindowPos()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
return window->Pos;
}
@@ -4744,61 +4921,68 @@
void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowPosVal = pos;
g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always;
}
void ImGui::SetNextWindowPosCenter(ImGuiSetCond cond)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowPosVal = ImVec2(-FLT_MAX, -FLT_MAX);
g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always;
}
void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowSizeVal = size;
g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCond_Always;
}
+void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback, void* custom_callback_user_data)
+{
+ ImGuiContext& g = *GImGui;
+ g.SetNextWindowSizeConstraint = true;
+ g.SetNextWindowSizeConstraintRect = ImRect(size_min, size_max);
+ g.SetNextWindowSizeConstraintCallback = custom_callback;
+ g.SetNextWindowSizeConstraintCallbackUserData = custom_callback_user_data;
+}
+
void ImGui::SetNextWindowContentSize(const ImVec2& size)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowContentSizeVal = size;
g.SetNextWindowContentSizeCond = ImGuiSetCond_Always;
}
void ImGui::SetNextWindowContentWidth(float width)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowContentSizeVal = ImVec2(width, g.SetNextWindowContentSizeCond ? g.SetNextWindowContentSizeVal.y : 0.0f);
g.SetNextWindowContentSizeCond = ImGuiSetCond_Always;
}
void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowCollapsedVal = collapsed;
g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCond_Always;
}
void ImGui::SetNextWindowFocus()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
g.SetNextWindowFocus = true;
}
// In window space (not screen space!)
-// FIXME-OPT: Could cache and maintain it (pretty much only change on columns change)
ImVec2 ImGui::GetContentRegionMax()
{
ImGuiWindow* window = GetCurrentWindowRead();
- ImVec2 content_region_size = ImVec2(window->SizeContentsExplicit.x ? window->SizeContentsExplicit.x : window->Size.x - window->ScrollbarSizes.x, window->SizeContentsExplicit.y ? window->SizeContentsExplicit.y : window->Size.y - window->ScrollbarSizes.y);
- ImVec2 mx = content_region_size - window->Scroll - window->WindowPadding;
+ ImVec2 mx = window->ContentsRegionRect.Max;
if (window->DC.ColumnsCount != 1)
- mx.x = ImGui::GetColumnOffset(window->DC.ColumnsCurrent + 1) - window->WindowPadding.x;
+ mx.x = GetColumnOffset(window->DC.ColumnsCurrent + 1) - window->WindowPadding.x;
return mx;
}
@@ -4817,37 +5001,36 @@
ImVec2 ImGui::GetWindowContentRegionMin()
{
ImGuiWindow* window = GetCurrentWindowRead();
- return ImVec2(-window->Scroll.x, -window->Scroll.y + window->TitleBarHeight() + window->MenuBarHeight()) + window->WindowPadding;
+ return window->ContentsRegionRect.Min;
}
ImVec2 ImGui::GetWindowContentRegionMax()
{
ImGuiWindow* window = GetCurrentWindowRead();
- ImVec2 content_region_size = ImVec2(window->SizeContentsExplicit.x ? window->SizeContentsExplicit.x : window->Size.x, window->SizeContentsExplicit.y ? window->SizeContentsExplicit.y : window->Size.y);
- ImVec2 m = content_region_size - window->Scroll - window->WindowPadding - window->ScrollbarSizes;
- return m;
+ return window->ContentsRegionRect.Max;
}
float ImGui::GetWindowContentRegionWidth()
{
- return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x;
+ ImGuiWindow* window = GetCurrentWindowRead();
+ return window->ContentsRegionRect.Max.x - window->ContentsRegionRect.Min.x;
}
float ImGui::GetTextLineHeight()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
return g.FontSize;
}
float ImGui::GetTextLineHeightWithSpacing()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
return g.FontSize + g.Style.ItemSpacing.y;
}
float ImGui::GetItemsLineHeightWithSpacing()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y;
}
@@ -4874,7 +5057,7 @@
void ImGui::SetWindowFontScale(float scale)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
window->FontWindowScale = scale;
g.FontSize = window->CalcFontSize();
@@ -4991,14 +5174,14 @@
{
ImGuiWindow* window = GetCurrentWindow();
float target_y = window->DC.CursorPosPrevLine.y + (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
- ImGui::SetScrollFromPosY(target_y - window->Pos.y, center_y_ratio);
+ SetScrollFromPosY(target_y - window->Pos.y, center_y_ratio);
}
void ImGui::SetKeyboardFocusHere(int offset)
{
ImGuiWindow* window = GetCurrentWindow();
window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset;
- window->FocusIdxTabRequestNext = IM_INT_MAX;
+ window->FocusIdxTabRequestNext = INT_MAX;
}
void ImGui::SetStateStorage(ImGuiStorage* tree)
@@ -5019,7 +5202,7 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
TextUnformatted(g.TempBuffer, text_end);
}
@@ -5034,9 +5217,9 @@
void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args)
{
- ImGui::PushStyleColor(ImGuiCol_Text, col);
+ PushStyleColor(ImGuiCol_Text, col);
TextV(fmt, args);
- ImGui::PopStyleColor();
+ PopStyleColor();
}
void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
@@ -5049,9 +5232,9 @@
void ImGui::TextDisabledV(const char* fmt, va_list args)
{
- ImGui::PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]);
+ PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]);
TextV(fmt, args);
- ImGui::PopStyleColor();
+ PopStyleColor();
}
void ImGui::TextDisabled(const char* fmt, ...)
@@ -5064,9 +5247,9 @@
void ImGui::TextWrappedV(const char* fmt, va_list args)
{
- ImGui::PushTextWrapPos(0.0f);
+ PushTextWrapPos(0.0f);
TextV(fmt, args);
- ImGui::PopTextWrapPos();
+ PopTextWrapPos();
}
void ImGui::TextWrapped(const char* fmt, ...)
@@ -5083,7 +5266,7 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(text != NULL);
const char* text_begin = text;
if (text_end == NULL)
@@ -5098,7 +5281,7 @@
// From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled.
// We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line.
const char* line = text;
- const float line_height = ImGui::GetTextLineHeight();
+ const float line_height = GetTextLineHeight();
const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset);
const ImRect clip_rect = window->ClipRect;
ImVec2 text_size(0,0);
@@ -5129,7 +5312,7 @@
// Lines to render
if (line < text_end)
{
- ImRect line_rect(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height));
+ ImRect line_rect(pos, pos + ImVec2(GetWindowWidth(), line_height));
while (line < text_end)
{
const char* line_end = strchr(line, '\n');
@@ -5193,9 +5376,9 @@
return;
// Declare a dummy item size to that upcoming items that are smaller will center-align on the newly expanded line height.
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ItemSize(ImVec2(0, g.FontSize + g.Style.FramePadding.y*2), g.Style.FramePadding.y);
- ImGui::SameLine(0, 0);
+ SameLine(0, 0);
}
// Add a label+text combo aligned to other label+value widgets
@@ -5205,7 +5388,7 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const float w = CalcItemWidth();
@@ -5235,7 +5418,7 @@
static inline bool IsWindowContentHoverable(ImGuiWindow* window)
{
// An active popup disable hovering on other windows (apart from its own children)
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (ImGuiWindow* focused_window = g.FocusedWindow)
if (ImGuiWindow* focused_root_window = focused_window->RootWindow)
if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow)
@@ -5246,7 +5429,7 @@
bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (flags & ImGuiButtonFlags_Disabled)
@@ -5257,39 +5440,44 @@
return false;
}
+ if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0)
+ flags |= ImGuiButtonFlags_PressedOnClickRelease;
+
bool pressed = false;
- const bool hovered = IsHovered(bb, id, (flags & ImGuiButtonFlags_FlattenChilds) != 0);
+ bool hovered = IsHovered(bb, id, (flags & ImGuiButtonFlags_FlattenChilds) != 0);
if (hovered)
{
SetHoveredID(id);
if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt))
{
- if (g.IO.MouseDoubleClicked[0] && (flags & ImGuiButtonFlags_PressedOnDoubleClick))
+ // | CLICKING | HOLDING with ImGuiButtonFlags_Repeat
+ // PressedOnClickRelease | * | .. (NOT on release) <-- MOST COMMON! (*) only if both click/release were over bounds
+ // PressedOnClick | | ..
+ // PressedOnRelease | | .. (NOT on release)
+ // PressedOnDoubleClick | | ..
+ if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0])
{
- pressed = true;
- }
- else if (g.IO.MouseClicked[0])
- {
- if (flags & ImGuiButtonFlags_PressedOnClick)
- {
- pressed = true;
- SetActiveID(0);
- }
- else
- {
- SetActiveID(id, window);
- }
+ SetActiveID(id, window); // Hold on ID
FocusWindow(window);
+ g.ActiveIdClickOffset = g.IO.MousePos - bb.Min;
}
- else if (g.IO.MouseReleased[0] && (flags & ImGuiButtonFlags_PressedOnRelease))
+ if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0]))
{
pressed = true;
SetActiveID(0);
+ FocusWindow(window);
}
- else if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && ImGui::IsMouseClicked(0, true))
+ if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0])
{
- pressed = true;
+ if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps
+ pressed = true;
+ SetActiveID(0);
}
+
+ // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above).
+ // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings.
+ if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && g.IO.MouseDownDuration[0] > 0.0f && IsMouseClicked(0, true))
+ pressed = true;
}
}
@@ -5302,12 +5490,17 @@
}
else
{
- if (hovered)
- pressed = true;
+ if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease))
+ if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps
+ pressed = true;
SetActiveID(0);
}
}
+ // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one.
+ if (hovered && (flags & ImGuiButtonFlags_AllowOverlapMode) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0))
+ hovered = pressed = held = false;
+
if (out_hovered) *out_hovered = hovered;
if (out_held) *out_held = held;
@@ -5320,7 +5513,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
@@ -5346,7 +5539,7 @@
// Automatically close popups
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
- // ImGui::CloseCurrentPopup();
+ // CloseCurrentPopup();
return pressed;
}
@@ -5359,7 +5552,7 @@
// Small buttons fits within text without additional vertical spacing.
bool ImGui::SmallButton(const char* label)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
float backup_padding_y = g.Style.FramePadding.y;
g.Style.FramePadding.y = 0.0f;
bool pressed = ButtonEx(label, ImVec2(0,0), ImGuiButtonFlags_AlignTextBaseLine);
@@ -5391,23 +5584,23 @@
// Upper-right button to close a window.
bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius)
{
- ImGuiWindow* window = ImGui::GetCurrentWindow();
+ ImGuiWindow* window = GetCurrentWindow();
const ImRect bb(pos - ImVec2(radius,radius), pos + ImVec2(radius,radius));
bool hovered, held;
- bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held);
+ bool pressed = ButtonBehavior(bb, id, &hovered, &held);
// Render
- const ImU32 col = ImGui::GetColorU32((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton);
+ const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton);
const ImVec2 center = bb.GetCenter();
window->DrawList->AddCircleFilled(center, ImMax(2.0f, radius), col, 12);
const float cross_extent = (radius * 0.7071f) - 1.0f;
if (hovered)
{
- window->DrawList->AddLine(center + ImVec2(+cross_extent,+cross_extent), center + ImVec2(-cross_extent,-cross_extent), ImGui::GetColorU32(ImGuiCol_Text));
- window->DrawList->AddLine(center + ImVec2(+cross_extent,-cross_extent), center + ImVec2(-cross_extent,+cross_extent), ImGui::GetColorU32(ImGuiCol_Text));
+ window->DrawList->AddLine(center + ImVec2(+cross_extent,+cross_extent), center + ImVec2(-cross_extent,-cross_extent), GetColorU32(ImGuiCol_Text));
+ window->DrawList->AddLine(center + ImVec2(+cross_extent,-cross_extent), center + ImVec2(-cross_extent,+cross_extent), GetColorU32(ImGuiCol_Text));
}
return pressed;
@@ -5447,14 +5640,14 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
// Default to using texture ID as ID. User can still push string/integer prefixes.
// We could hash the size/uv to create a unique ID but that would prevent the user from animating UV.
- ImGui::PushID((void *)user_texture_id);
+ PushID((void *)user_texture_id);
const ImGuiID id = window->GetID("#image");
- ImGui::PopID();
+ PopID();
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding;
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2);
@@ -5479,7 +5672,7 @@
// Start logging ImGui output to TTY
void ImGui::LogToTTY(int max_depth)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.LogEnabled)
return;
ImGuiWindow* window = GetCurrentWindowRead();
@@ -5494,7 +5687,7 @@
// Start logging ImGui output to given file
void ImGui::LogToFile(int max_depth, const char* filename)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.LogEnabled)
return;
ImGuiWindow* window = GetCurrentWindowRead();
@@ -5521,7 +5714,7 @@
// Start logging ImGui output to clipboard
void ImGui::LogToClipboard(int max_depth)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.LogEnabled)
return;
ImGuiWindow* window = GetCurrentWindowRead();
@@ -5535,11 +5728,11 @@
void ImGui::LogFinish()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (!g.LogEnabled)
return;
- ImGui::LogText(IM_NEWLINE);
+ LogText(IM_NEWLINE);
g.LogEnabled = false;
if (g.LogFile != NULL)
{
@@ -5560,22 +5753,18 @@
// Helper to display logging buttons
void ImGui::LogButtons()
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
- ImGui::PushID("LogButtons");
- const bool log_to_tty = ImGui::Button("Log To TTY");
- ImGui::SameLine();
- const bool log_to_file = ImGui::Button("Log To File");
- ImGui::SameLine();
- const bool log_to_clipboard = ImGui::Button("Log To Clipboard");
- ImGui::SameLine();
-
- ImGui::PushItemWidth(80.0f);
- ImGui::PushAllowKeyboardFocus(false);
- ImGui::SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL);
- ImGui::PopAllowKeyboardFocus();
- ImGui::PopItemWidth();
- ImGui::PopID();
+ PushID("LogButtons");
+ const bool log_to_tty = Button("Log To TTY"); SameLine();
+ const bool log_to_file = Button("Log To File"); SameLine();
+ const bool log_to_clipboard = Button("Log To Clipboard"); SameLine();
+ PushItemWidth(80.0f);
+ PushAllowKeyboardFocus(false);
+ SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL);
+ PopAllowKeyboardFocus();
+ PopItemWidth();
+ PopID();
// Start logging at the end of the function so that the buttons don't appear in the log
if (log_to_tty)
@@ -5586,20 +5775,23 @@
LogToClipboard(g.LogAutoExpandMaxDepth);
}
-bool ImGui::TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags)
+bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
{
+ if (flags & ImGuiTreeNodeFlags_Leaf)
+ return true;
+
// We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions)
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiStorage* storage = window->DC.StateStorage;
- bool opened;
- if (g.SetNextTreeNodeOpenedCond != 0)
+ bool is_open;
+ if (g.SetNextTreeNodeOpenCond != 0)
{
- if (g.SetNextTreeNodeOpenedCond & ImGuiSetCond_Always)
+ if (g.SetNextTreeNodeOpenCond & ImGuiSetCond_Always)
{
- opened = g.SetNextTreeNodeOpenedVal;
- storage->SetInt(id, opened);
+ is_open = g.SetNextTreeNodeOpenVal;
+ storage->SetInt(id, is_open);
}
else
{
@@ -5607,52 +5799,47 @@
const int stored_value = storage->GetInt(id, -1);
if (stored_value == -1)
{
- opened = g.SetNextTreeNodeOpenedVal;
- storage->SetInt(id, opened);
+ is_open = g.SetNextTreeNodeOpenVal;
+ storage->SetInt(id, is_open);
}
else
{
- opened = stored_value != 0;
+ is_open = stored_value != 0;
}
}
- g.SetNextTreeNodeOpenedCond = 0;
+ g.SetNextTreeNodeOpenCond = 0;
}
else
{
- opened = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0;
+ is_open = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0;
}
// When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior).
// NB- If we are above max depth we still allow manually opened nodes to be logged.
- if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoExpandOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
- opened = true;
+ if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
+ is_open = true;
- return opened;
+ return is_open;
}
-// FIXME: Split into CollapsingHeader(label, default_open?) and TreeNodeBehavior(label), obsolete the 4 parameters function.
-bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display_frame, bool default_open)
+bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
+ const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0;
const ImVec2 padding = display_frame ? style.FramePadding : ImVec2(style.FramePadding.x, 0.0f);
- IM_ASSERT(str_id != NULL || label != NULL);
- if (str_id == NULL)
- str_id = label;
- if (label == NULL)
- label = str_id;
- const bool label_hide_text_after_double_hash = (label == str_id); // Only search and hide text after ## if we have passed label and ID separately, otherwise allow "##" within format string.
- const ImGuiID id = window->GetID(str_id);
- const ImVec2 label_size = CalcTextSize(label, NULL, label_hide_text_after_double_hash);
+ if (!label_end)
+ label_end = FindRenderedTextEnd(label);
+ const ImVec2 label_size = CalcTextSize(label, label_end, false);
// We vertically grow up to current line height up the typical widget height.
const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset - padding.y); // Latch before ItemSize changes it
- const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), label_size.y + padding.y*2);
+ const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2);
ImRect bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height));
if (display_frame)
{
@@ -5661,135 +5848,225 @@
bb.Max.x += (float)(int)(window->WindowPadding.x*0.5f) - 1;
}
- const float collapser_width = g.FontSize + (display_frame ? padding.x*2 : padding.x);
+ const float text_offset_x = (g.FontSize + (display_frame ? padding.x*3 : padding.x*2)); // Collapser arrow width + Spacing
const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x*2 : 0.0f); // Include collapser
ItemSize(ImVec2(text_width, frame_height), text_base_offset_y);
// For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing
// (Ideally we'd want to add a flag for the user to specify we want want the hit test to be done up to the right side of the content or not)
const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y);
- bool opened = TreeNodeBehaviorIsOpened(id, (default_open ? ImGuiTreeNodeFlags_DefaultOpen : 0) | (display_frame ? ImGuiTreeNodeFlags_NoAutoExpandOnLog : 0));
+ bool is_open = TreeNodeBehaviorIsOpen(id, flags);
if (!ItemAdd(interact_bb, &id))
- return opened;
-
- bool hovered, held;
- bool pressed = ButtonBehavior(interact_bb, id, &hovered, &held, ImGuiButtonFlags_NoKeyModifiers);
- if (pressed)
{
- opened = !opened;
- window->DC.StateStorage->SetInt(id, opened);
+ if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
+ TreePushRawID(id);
+ return is_open;
}
+ // Flags that affects opening behavior:
+ // - 0(default) ..................... single-click anywhere to open
+ // - OpenOnDoubleClick .............. double-click anywhere to open
+ // - OpenOnArrow .................... single-click on arrow to open
+ // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open
+ ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowOverlapMode : 0);
+ if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
+ button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0);
+ bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags);
+ if (pressed && !(flags & ImGuiTreeNodeFlags_Leaf))
+ {
+ bool toggled = !(flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick));
+ if (flags & ImGuiTreeNodeFlags_OpenOnArrow)
+ toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + text_offset_x, interact_bb.Max.y));
+ if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
+ toggled |= g.IO.MouseDoubleClicked[0];
+ if (toggled)
+ {
+ is_open = !is_open;
+ window->DC.StateStorage->SetInt(id, is_open);
+ }
+ }
+ if (flags & ImGuiTreeNodeFlags_AllowOverlapMode)
+ SetItemAllowOverlap();
+
// Render
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
- const ImVec2 text_pos = bb.Min + padding + ImVec2(collapser_width, text_base_offset_y);
+ const ImVec2 text_pos = bb.Min + ImVec2(text_offset_x, padding.y + text_base_offset_y);
if (display_frame)
{
// Framed type
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
- RenderCollapseTriangle(bb.Min + padding + ImVec2(0.0f, text_base_offset_y), opened, 1.0f, true);
+ RenderCollapseTriangle(bb.Min + padding + ImVec2(0.0f, text_base_offset_y), is_open, 1.0f, true);
if (g.LogEnabled)
{
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
const char log_prefix[] = "\n##";
const char log_suffix[] = "##";
LogRenderedText(text_pos, log_prefix, log_prefix+3);
- RenderTextClipped(text_pos, bb.Max, label, NULL, &label_size);
+ RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size);
LogRenderedText(text_pos, log_suffix+1, log_suffix+3);
}
else
{
- RenderTextClipped(text_pos, bb.Max, label, NULL, &label_size);
+ RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size);
}
}
else
{
// Unframed typed for tree nodes
- if (hovered)
+ if (hovered || (flags & ImGuiTreeNodeFlags_Selected))
RenderFrame(bb.Min, bb.Max, col, false);
- RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), opened, 0.70f, false);
+ if (flags & ImGuiTreeNodeFlags_Bullet)
+ RenderBullet(bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y));
+ else if (!(flags & ImGuiTreeNodeFlags_Leaf))
+ RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open, 0.70f, false);
if (g.LogEnabled)
LogRenderedText(text_pos, ">");
- RenderText(text_pos, label, NULL, label_hide_text_after_double_hash);
+ RenderText(text_pos, label, label_end, false);
}
- return opened;
+ if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
+ TreePushRawID(id);
+ return is_open;
}
-// If returning 'true' the node is open and the user is responsible for calling TreePop
-bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args)
+// CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag).
+// This is basically the same as calling TreeNodeEx(label, ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen). You can remove the _NoTreePushOnOpen flag if you want behavior closer to normal TreeNode().
+bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
- ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
- if (!str_id || !str_id[0])
- str_id = fmt;
+ return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen, label);
+}
- ImGui::PushID(str_id);
- const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false);
- ImGui::PopID();
+bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
- if (opened)
- ImGui::TreePush(str_id);
+ if (p_open && !*p_open)
+ return false;
- return opened;
+ ImGuiID id = window->GetID(label);
+ bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowOverlapMode : 0), label);
+ if (p_open)
+ {
+ // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
+ ImGuiContext& g = *GImGui;
+ float button_sz = g.FontSize * 0.5f;
+ if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz))
+ *p_open = false;
+ }
+
+ return is_open;
+}
+
+bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
+
+ return TreeNodeBehavior(window->GetID(label), flags, label, NULL);
+}
+
+bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
+
+ ImGuiContext& g = *GImGui;
+ const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
+ return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end);
+}
+
+bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
+
+ ImGuiContext& g = *GImGui;
+ const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
+ return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end);
+}
+
+bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args)
+{
+ return TreeNodeExV(str_id, 0, fmt, args);
+}
+
+bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args)
+{
+ return TreeNodeExV(ptr_id, 0, fmt, args);
+}
+
+bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ bool is_open = TreeNodeExV(str_id, flags, fmt, args);
+ va_end(args);
+ return is_open;
+}
+
+bool ImGui::TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ bool is_open = TreeNodeExV(ptr_id, flags, fmt, args);
+ va_end(args);
+ return is_open;
}
bool ImGui::TreeNode(const char* str_id, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
- bool s = TreeNodeV(str_id, fmt, args);
+ bool is_open = TreeNodeExV(str_id, 0, fmt, args);
va_end(args);
- return s;
-}
-
-// If returning 'true' the node is open and the user is responsible for calling TreePop
-bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args)
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return false;
-
- ImGuiState& g = *GImGui;
- ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
-
- if (!ptr_id)
- ptr_id = fmt;
-
- ImGui::PushID(ptr_id);
- const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false);
- ImGui::PopID();
-
- if (opened)
- ImGui::TreePush(ptr_id);
-
- return opened;
+ return is_open;
}
bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
- bool s = TreeNodeV(ptr_id, fmt, args);
+ bool is_open = TreeNodeExV(ptr_id, 0, fmt, args);
va_end(args);
- return s;
+ return is_open;
}
-bool ImGui::TreeNode(const char* str_label_id)
+bool ImGui::TreeNode(const char* label)
{
- return TreeNode(str_label_id, "%s", str_label_id);
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
+ return TreeNodeBehavior(window->GetID(label), 0, label, NULL);
}
-void ImGui::SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond)
+void ImGui::TreeAdvanceToLabelPos()
{
- ImGuiState& g = *GImGui;
- g.SetNextTreeNodeOpenedVal = opened;
- g.SetNextTreeNodeOpenedCond = cond ? cond : ImGuiSetCond_Always;
+ ImGuiContext& g = *GImGui;
+ g.CurrentWindow->DC.CursorPos.x += GetTreeNodeToLabelSpacing();
+}
+
+// Horizontal distance preceeding label when using TreeNode() or Bullet()
+float ImGui::GetTreeNodeToLabelSpacing()
+{
+ ImGuiContext& g = *GImGui;
+ return g.FontSize + (g.Style.FramePadding.x * 2.0f);
+}
+
+void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond)
+{
+ ImGuiContext& g = *GImGui;
+ g.SetNextTreeNodeOpenVal = is_open;
+ g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiSetCond_Always;
}
void ImGui::PushID(const char* str_id)
@@ -5844,23 +6121,20 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height));
ItemSize(bb);
if (!ItemAdd(bb, NULL))
{
- ImGui::SameLine(0, style.FramePadding.x*2);
+ SameLine(0, style.FramePadding.x*2);
return;
}
- // Render
- const float bullet_size = g.FontSize*0.15f;
- window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f), bullet_size, GetColorU32(ImGuiCol_Text));
-
- // Stay on same line
- ImGui::SameLine(0, style.FramePadding.x*2);
+ // Render and stay on same line
+ RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f));
+ SameLine(0, style.FramePadding.x*2);
}
// Text with a little bullet aligned to the typical tree node.
@@ -5870,7 +6144,7 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const char* text_begin = g.TempBuffer;
@@ -5884,8 +6158,7 @@
return;
// Render
- const float bullet_size = g.FontSize*0.15f;
- window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f), bullet_size, GetColorU32(ImGuiCol_Text));
+ RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f));
RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end);
}
@@ -6007,7 +6280,7 @@
// Create text input in place of a slider (when CTRL+Clicking on slider)
bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
// Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen)
@@ -6075,7 +6348,7 @@
bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
const ImGuiStyle& style = g.Style;
@@ -6137,7 +6410,7 @@
{
// Positive: rescale to the positive range before powering
float a;
- if (fabsf(linear_zero_pos - 1.0f) > 1.e-6)
+ if (fabsf(linear_zero_pos - 1.0f) > 1.e-6f)
a = (normalized_pos - linear_zero_pos) / (1.0f - linear_zero_pos);
else
a = normalized_pos;
@@ -6212,7 +6485,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const float w = CalcItemWidth();
@@ -6275,7 +6548,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
@@ -6318,7 +6591,7 @@
bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max)
{
float v_deg = (*v_rad) * 360.0f / (2*IM_PI);
- bool value_changed = ImGui::SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f);
+ bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f);
*v_rad = v_deg * (2*IM_PI) / 360.0f;
return value_changed;
}
@@ -6328,7 +6601,7 @@
if (!display_format)
display_format = "%.0f";
float v_f = (float)*v;
- bool value_changed = ImGui::SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f);
+ bool value_changed = SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f);
*v = (int)v_f;
return value_changed;
}
@@ -6338,7 +6611,7 @@
if (!display_format)
display_format = "%.0f";
float v_f = (float)*v;
- bool value_changed = ImGui::VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f);
+ bool value_changed = VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f);
*v = (int)v_f;
return value_changed;
}
@@ -6350,23 +6623,23 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
bool value_changed = false;
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
PushMultiItemsWidths(components);
for (int i = 0; i < components; i++)
{
- ImGui::PushID(i);
- value_changed |= ImGui::SliderFloat("##v", &v[i], v_min, v_max, display_format, power);
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::PopID();
- ImGui::PopItemWidth();
+ PushID(i);
+ value_changed |= SliderFloat("##v", &v[i], v_min, v_max, display_format, power);
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ PopID();
+ PopItemWidth();
}
- ImGui::PopID();
+ PopID();
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
return value_changed;
}
@@ -6392,23 +6665,23 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
bool value_changed = false;
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
PushMultiItemsWidths(components);
for (int i = 0; i < components; i++)
{
- ImGui::PushID(i);
- value_changed |= ImGui::SliderInt("##v", &v[i], v_min, v_max, display_format);
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::PopID();
- ImGui::PopItemWidth();
+ PushID(i);
+ value_changed |= SliderInt("##v", &v[i], v_min, v_max, display_format);
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ PopID();
+ PopItemWidth();
}
- ImGui::PopID();
+ PopID();
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
return value_changed;
}
@@ -6430,7 +6703,7 @@
bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
// Draw frame
@@ -6452,7 +6725,7 @@
}
float v_cur = g.DragCurrentValue;
- const ImVec2 mouse_drag_delta = ImGui::GetMouseDragDelta(0, 1.0f);
+ const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f);
if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f)
{
float speed = v_speed;
@@ -6509,7 +6782,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const float w = CalcItemWidth();
@@ -6572,23 +6845,23 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
bool value_changed = false;
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
PushMultiItemsWidths(components);
for (int i = 0; i < components; i++)
{
- ImGui::PushID(i);
- value_changed |= ImGui::DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power);
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::PopID();
- ImGui::PopItemWidth();
+ PushID(i);
+ value_changed |= DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power);
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ PopID();
+ PopItemWidth();
}
- ImGui::PopID();
+ PopID();
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
return value_changed;
}
@@ -6614,21 +6887,21 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
- ImGui::PushID(label);
- ImGui::BeginGroup();
+ ImGuiContext& g = *GImGui;
+ PushID(label);
+ BeginGroup();
PushMultiItemsWidths(2);
- bool value_changed = ImGui::DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power);
- ImGui::PopItemWidth();
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- value_changed |= ImGui::DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power);
- ImGui::PopItemWidth();
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
+ bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power);
+ PopItemWidth();
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power);
+ PopItemWidth();
+ SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
- ImGui::PopID();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
+ PopID();
return value_changed;
}
@@ -6639,7 +6912,7 @@
if (!display_format)
display_format = "%.0f";
float v_f = (float)*v;
- bool value_changed = ImGui::DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format);
+ bool value_changed = DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format);
*v = (int)v_f;
return value_changed;
}
@@ -6650,23 +6923,23 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
bool value_changed = false;
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
PushMultiItemsWidths(components);
for (int i = 0; i < components; i++)
{
- ImGui::PushID(i);
- value_changed |= ImGui::DragInt("##v", &v[i], v_speed, v_min, v_max, display_format);
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::PopID();
- ImGui::PopItemWidth();
+ PushID(i);
+ value_changed |= DragInt("##v", &v[i], v_speed, v_min, v_max, display_format);
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ PopID();
+ PopItemWidth();
}
- ImGui::PopID();
+ PopID();
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
return value_changed;
}
@@ -6692,21 +6965,21 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
- ImGui::PushID(label);
- ImGui::BeginGroup();
+ ImGuiContext& g = *GImGui;
+ PushID(label);
+ BeginGroup();
PushMultiItemsWidths(2);
- bool value_changed = ImGui::DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? IM_INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format);
- ImGui::PopItemWidth();
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- value_changed |= ImGui::DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? IM_INT_MAX : v_max, display_format_max ? display_format_max : display_format);
- ImGui::PopItemWidth();
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
+ bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format);
+ PopItemWidth();
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, display_format_max ? display_format_max : display_format);
+ PopItemWidth();
+ SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
- ImGui::PopID();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
+ PopID();
return value_changed;
}
@@ -6717,7 +6990,7 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImVec2 label_size = CalcTextSize(label, NULL, true);
@@ -6766,9 +7039,9 @@
const float v0 = values_getter(data, (v_idx + values_offset) % values_count);
const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count);
if (plot_type == ImGuiPlotType_Lines)
- ImGui::SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1);
+ SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1);
else if (plot_type == ImGuiPlotType_Histogram)
- ImGui::SetTooltip("%d: %8.4g", v_idx, v0);
+ SetTooltip("%d: %8.4g", v_idx, v0);
v_hovered = v_idx;
}
@@ -6859,7 +7132,7 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
ImVec2 pos = window->DC.CursorPos;
@@ -6894,7 +7167,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
@@ -6939,7 +7212,7 @@
bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
{
bool v = ((*flags & flags_value) == flags_value);
- bool pressed = ImGui::Checkbox(label, &v);
+ bool pressed = Checkbox(label, &v);
if (pressed)
{
if (v)
@@ -6957,7 +7230,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
@@ -7010,7 +7283,7 @@
bool ImGui::RadioButton(const char* label, int* v, int v_button)
{
- const bool pressed = ImGui::RadioButton(label, *v == v_button);
+ const bool pressed = RadioButton(label, *v == v_button);
if (pressed)
{
*v = v_button;
@@ -7281,7 +7554,7 @@
IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys)
IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key)
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiIO& io = g.IO;
const ImGuiStyle& style = g.Style;
@@ -7291,18 +7564,18 @@
const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0;
const ImVec2 label_size = CalcTextSize(label, NULL, true);
- ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? ImGui::GetTextLineHeight() * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line
+ ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? GetTextLineHeight() * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size);
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f));
ImGuiWindow* draw_window = window;
if (is_multiline)
{
- ImGui::BeginGroup();
- if (!ImGui::BeginChildFrame(id, frame_bb.GetSize()))
+ BeginGroup();
+ if (!BeginChildFrame(id, frame_bb.GetSize()))
{
- ImGui::EndChildFrame();
- ImGui::EndGroup();
+ EndChildFrame();
+ EndGroup();
return false;
}
draw_window = GetCurrentWindow();
@@ -7329,7 +7602,7 @@
password_font->FallbackGlyph = glyph;
password_font->FallbackXAdvance = glyph->XAdvance;
IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexXAdvance.empty() && password_font->IndexLookup.empty());
- ImGui::PushFont(password_font);
+ PushFont(password_font);
}
// NB: we are only allowed to access 'edit_state' if we are the active widget.
@@ -7795,9 +8068,9 @@
// Draw blinking cursor
bool cursor_is_visible = (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f;
ImVec2 cursor_screen_pos = render_pos + cursor_offset - render_scroll;
- ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y-g.FontSize+0.5f, cursor_screen_pos.x, cursor_screen_pos.y-1.5f);
+ ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y-g.FontSize+0.5f, cursor_screen_pos.x+1.0f, cursor_screen_pos.y-1.5f);
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
- draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.Max, GetColorU32(ImGuiCol_Text));
+ draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text));
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
if (is_editable)
@@ -7814,13 +8087,13 @@
if (is_multiline)
{
- ImGui::Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line
- ImGui::EndChildFrame();
- ImGui::EndGroup();
+ Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line
+ EndChildFrame();
+ EndGroup();
}
if (is_password)
- ImGui::PopFont();
+ PopFont();
// Log as text
if (g.LogEnabled && !is_password)
@@ -7855,15 +8128,15 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImVec2 label_size = CalcTextSize(label, NULL, true);
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
const ImVec2 button_sz = ImVec2(g.FontSize, g.FontSize) + style.FramePadding*2.0f;
if (step_ptr)
- ImGui::PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2));
+ PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2));
char buf[64];
DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf));
@@ -7872,35 +8145,35 @@
if (!(extra_flags & ImGuiInputTextFlags_CharsHexadecimal))
extra_flags |= ImGuiInputTextFlags_CharsDecimal;
extra_flags |= ImGuiInputTextFlags_AutoSelectAll;
- if (ImGui::InputText("", buf, IM_ARRAYSIZE(buf), extra_flags))
+ if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags))
value_changed = DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format);
// Step buttons
if (step_ptr)
{
- ImGui::PopItemWidth();
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
+ PopItemWidth();
+ SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups))
{
DataTypeApplyOp(data_type, '-', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr);
value_changed = true;
}
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
+ SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups))
{
DataTypeApplyOp(data_type, '+', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr);
value_changed = true;
}
}
- ImGui::PopID();
+ PopID();
if (label_size.x > 0)
{
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
+ SameLine(0, style.ItemInnerSpacing.x);
RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label);
ItemSize(label_size, style.FramePadding.y);
}
- ImGui::EndGroup();
+ EndGroup();
return value_changed;
}
@@ -7928,24 +8201,24 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
bool value_changed = false;
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
PushMultiItemsWidths(components);
for (int i = 0; i < components; i++)
{
- ImGui::PushID(i);
- value_changed |= ImGui::InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags);
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::PopID();
- ImGui::PopItemWidth();
+ PushID(i);
+ value_changed |= InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags);
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ PopID();
+ PopItemWidth();
}
- ImGui::PopID();
+ PopID();
window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
return value_changed;
}
@@ -7971,24 +8244,24 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
bool value_changed = false;
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
PushMultiItemsWidths(components);
for (int i = 0; i < components; i++)
{
- ImGui::PushID(i);
- value_changed |= ImGui::InputInt("##v", &v[i], 0, 0, extra_flags);
- ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
- ImGui::PopID();
- ImGui::PopItemWidth();
+ PushID(i);
+ value_changed |= InputInt("##v", &v[i], 0, 0, extra_flags);
+ SameLine(0, g.Style.ItemInnerSpacing.x);
+ PopID();
+ PopItemWidth();
}
- ImGui::PopID();
+ PopID();
window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
- ImGui::TextUnformatted(label, FindRenderedTextEnd(label));
- ImGui::EndGroup();
+ TextUnformatted(label, FindRenderedTextEnd(label));
+ EndGroup();
return value_changed;
}
@@ -8064,7 +8337,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const float w = CalcItemWidth();
@@ -8078,12 +8351,12 @@
const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f);
const bool hovered = IsHovered(frame_bb, id);
- bool popup_opened = IsPopupOpen(id);
+ bool popup_open = IsPopupOpen(id);
bool popup_opened_now = false;
const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
- RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_opened || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING
+ RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING
RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true);
if (*current_item >= 0 && *current_item < items_count)
@@ -8110,7 +8383,7 @@
{
FocusWindow(window);
OpenPopup(label);
- popup_opened = popup_opened_now = true;
+ popup_open = popup_opened_now = true;
}
}
}
@@ -8132,35 +8405,35 @@
popup_y2 = frame_bb.Min.y;
}
ImRect popup_rect(ImVec2(frame_bb.Min.x, popup_y1), ImVec2(frame_bb.Max.x, popup_y2));
- ImGui::SetNextWindowPos(popup_rect.Min);
- ImGui::SetNextWindowSize(popup_rect.GetSize());
- ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
+ SetNextWindowPos(popup_rect.Min);
+ SetNextWindowSize(popup_rect.GetSize());
+ PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0);
if (BeginPopupEx(label, flags))
{
// Display items
- ImGui::Spacing();
+ Spacing();
for (int i = 0; i < items_count; i++)
{
- ImGui::PushID((void*)(intptr_t)i);
+ PushID((void*)(intptr_t)i);
const bool item_selected = (i == *current_item);
const char* item_text;
if (!items_getter(data, i, &item_text))
item_text = "*Unknown item*";
- if (ImGui::Selectable(item_text, item_selected))
+ if (Selectable(item_text, item_selected))
{
SetActiveID(0);
value_changed = true;
*current_item = i;
}
if (item_selected && popup_opened_now)
- ImGui::SetScrollHere();
- ImGui::PopID();
+ SetScrollHere();
+ PopID();
}
- ImGui::EndPopup();
+ EndPopup();
}
- ImGui::PopStyleVar();
+ PopStyleVar();
}
return value_changed;
}
@@ -8173,7 +8446,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
@@ -8189,7 +8462,7 @@
// Fill horizontal space.
ImVec2 window_padding = window->WindowPadding;
- float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? ImGui::GetWindowContentRegionMax().x : ImGui::GetContentRegionMax().x;
+ float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x : GetContentRegionMax().x;
float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x);
ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y);
ImRect bb_with_spacing(pos, pos + size_draw);
@@ -8216,7 +8489,7 @@
if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick;
if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnClick|ImGuiButtonFlags_PressedOnRelease;
if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled;
- if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick;
+ if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick;
bool hovered, held;
bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, button_flags);
if (flags & ImGuiSelectableFlags_Disabled)
@@ -8232,22 +8505,22 @@
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
{
PushColumnClipRect();
- bb_with_spacing.Max.x -= (ImGui::GetContentRegionMax().x - max_x);
+ bb_with_spacing.Max.x -= (GetContentRegionMax().x - max_x);
}
- if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
+ if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size);
- if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor();
+ if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor();
// Automatically close popups
if (pressed && !(flags & ImGuiSelectableFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
- ImGui::CloseCurrentPopup();
+ CloseCurrentPopup();
return pressed;
}
bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size_arg)
{
- if (ImGui::Selectable(label, *p_selected, flags, size_arg))
+ if (Selectable(label, *p_selected, flags, size_arg))
{
*p_selected = !*p_selected;
return true;
@@ -8263,22 +8536,22 @@
if (window->SkipItems)
return false;
- const ImGuiStyle& style = ImGui::GetStyle();
- const ImGuiID id = ImGui::GetID(label);
+ const ImGuiStyle& style = GetStyle();
+ const ImGuiID id = GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
// Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
- ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
+ ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
window->DC.LastItemRect = bb;
- ImGui::BeginGroup();
+ BeginGroup();
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
- ImGui::BeginChildFrame(id, frame_bb.GetSize());
+ BeginChildFrame(id, frame_bb.GetSize());
return true;
}
@@ -8294,24 +8567,24 @@
// We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild().
ImVec2 size;
size.x = 0.0f;
- size.y = ImGui::GetTextLineHeightWithSpacing() * height_in_items_f + ImGui::GetStyle().ItemSpacing.y;
- return ImGui::ListBoxHeader(label, size);
+ size.y = GetTextLineHeightWithSpacing() * height_in_items_f + GetStyle().ItemSpacing.y;
+ return ListBoxHeader(label, size);
}
void ImGui::ListBoxFooter()
{
ImGuiWindow* parent_window = GetParentWindow();
const ImRect bb = parent_window->DC.LastItemRect;
- const ImGuiStyle& style = ImGui::GetStyle();
+ const ImGuiStyle& style = GetStyle();
- ImGui::EndChildFrame();
+ EndChildFrame();
// Redeclare item size so that it includes the label (we have stored the full size in LastItemRect)
// We call SameLine() to restore DC.CurrentLine* data
- ImGui::SameLine();
+ SameLine();
parent_window->DC.CursorPos = bb.Min;
ItemSize(bb, style.FramePadding.y);
- ImGui::EndGroup();
+ EndGroup();
}
bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items)
@@ -8322,29 +8595,29 @@
bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items)
{
- if (!ImGui::ListBoxHeader(label, items_count, height_in_items))
+ if (!ListBoxHeader(label, items_count, height_in_items))
return false;
// Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper.
bool value_changed = false;
- ImGuiListClipper clipper(items_count, ImGui::GetTextLineHeightWithSpacing());
- for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
- {
- const bool item_selected = (i == *current_item);
- const char* item_text;
- if (!items_getter(data, i, &item_text))
- item_text = "*Unknown item*";
-
- ImGui::PushID(i);
- if (ImGui::Selectable(item_text, item_selected))
+ ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing());
+ while (clipper.Step())
+ for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{
- *current_item = i;
- value_changed = true;
+ const bool item_selected = (i == *current_item);
+ const char* item_text;
+ if (!items_getter(data, i, &item_text))
+ item_text = "*Unknown item*";
+
+ PushID(i);
+ if (Selectable(item_text, item_selected))
+ {
+ *current_item = i;
+ value_changed = true;
+ }
+ PopID();
}
- ImGui::PopID();
- }
- clipper.End();
- ImGui::ListBoxFooter();
+ ListBoxFooter();
return value_changed;
}
@@ -8354,30 +8627,30 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImVec2 pos = window->DC.CursorPos;
ImVec2 label_size = CalcTextSize(label, NULL, true);
ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f);
float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame
- float extra_w = ImMax(0.0f, ImGui::GetContentRegionAvail().x - w);
+ float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w);
- bool pressed = ImGui::Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
+ bool pressed = Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f));
if (shortcut_size.x > 0.0f)
{
- ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
+ PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false);
- ImGui::PopStyleColor();
+ PopStyleColor();
}
if (selected)
- RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(ImGuiCol_Text));
+ RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled));
return pressed;
}
bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled)
{
- if (ImGui::MenuItem(label, shortcut, p_selected ? *p_selected : false, enabled))
+ if (MenuItem(label, shortcut, p_selected ? *p_selected : false, enabled))
{
if (p_selected)
*p_selected = !*p_selected;
@@ -8388,16 +8661,16 @@
bool ImGui::BeginMainMenuBar()
{
- ImGuiState& g = *GImGui;
- ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));
- ImGui::SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.FontBaseSize + g.Style.FramePadding.y * 2.0f));
- ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
- ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0,0));
- if (!ImGui::Begin("##MainMenuBar", NULL, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_MenuBar)
- || !ImGui::BeginMenuBar())
+ ImGuiContext& g = *GImGui;
+ SetNextWindowPos(ImVec2(0.0f, 0.0f));
+ SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.FontBaseSize + g.Style.FramePadding.y * 2.0f));
+ PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
+ PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0,0));
+ if (!Begin("##MainMenuBar", NULL, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_MenuBar)
+ || !BeginMenuBar())
{
- ImGui::End();
- ImGui::PopStyleVar(2);
+ End();
+ PopStyleVar(2);
return false;
}
g.CurrentWindow->DC.MenuBarOffsetX += g.Style.DisplaySafeAreaPadding.x;
@@ -8406,9 +8679,9 @@
void ImGui::EndMainMenuBar()
{
- ImGui::EndMenuBar();
- ImGui::End();
- ImGui::PopStyleVar(2);
+ EndMenuBar();
+ End();
+ PopStyleVar(2);
}
bool ImGui::BeginMenuBar()
@@ -8420,14 +8693,14 @@
return false;
IM_ASSERT(!window->DC.MenuBarAppending);
- ImGui::BeginGroup(); // Save position
- ImGui::PushID("##menubar");
+ BeginGroup(); // Save position
+ PushID("##menubar");
ImRect rect = window->MenuBarRect();
- PushClipRect(ImVec2(rect.Min.x, rect.Min.y + window->BorderSize), ImVec2(rect.Max.x, rect.Max.y), false);
+ PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->BorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false);
window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.MenuBarAppending = true;
- ImGui::AlignFirstTextHeightToWidgets();
+ AlignFirstTextHeightToWidgets();
return true;
}
@@ -8440,10 +8713,10 @@
IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar);
IM_ASSERT(window->DC.MenuBarAppending);
PopClipRect();
- ImGui::PopID();
+ PopID();
window->DC.MenuBarOffsetX = window->DC.CursorPos.x - window->MenuBarRect().Min.x;
window->DC.GroupStack.back().AdvanceCursor = false;
- ImGui::EndGroup();
+ EndGroup();
window->DC.LayoutType = ImGuiLayoutType_Vertical;
window->DC.MenuBarAppending = false;
}
@@ -8454,7 +8727,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
@@ -8462,9 +8735,9 @@
ImGuiWindow* backed_focused_window = g.FocusedWindow;
bool pressed;
- bool opened = IsPopupOpen(id);
- bool menuset_opened = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus"));
- if (menuset_opened)
+ bool menu_is_open = IsPopupOpen(id);
+ bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus"));
+ if (menuset_is_open)
g.FocusedWindow = window;
ImVec2 popup_pos, pos = window->DC.CursorPos;
@@ -8472,26 +8745,26 @@
{
popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight());
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f);
+ PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f);
float w = label_size.x;
- pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
- ImGui::PopStyleVar();
- ImGui::SameLine();
+ pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
+ PopStyleVar();
+ SameLine();
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
}
else
{
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame
- float extra_w = ImMax(0.0f, ImGui::GetContentRegionAvail().x - w);
- pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
- if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
+ float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w);
+ pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
+ if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false);
- if (!enabled) ImGui::PopStyleColor();
+ if (!enabled) PopStyleColor();
}
bool hovered = enabled && IsHovered(window->DC.LastItemRect, id);
- if (menuset_opened)
+ if (menuset_is_open)
g.FocusedWindow = backed_focused_window;
bool want_open = false, want_close = false;
@@ -8499,9 +8772,9 @@
{
// Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive.
bool moving_within_opened_triangle = false;
- if (g.HoveredWindow == window && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentWindow == window)
+ if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentWindow == window)
{
- if (ImGuiWindow* next_window = g.OpenedPopupStack[g.CurrentPopupStack.Size].Window)
+ if (ImGuiWindow* next_window = g.OpenPopupStack[g.CurrentPopupStack.Size].Window)
{
ImRect next_window_rect = next_window->Rect();
ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
@@ -8509,51 +8782,52 @@
ImVec2 tc = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR();
float extra = ImClamp(fabsf(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack.
ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues
- tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus
+ tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f);
moving_within_opened_triangle = ImIsPointInTriangle(g.IO.MousePos, ta, tb, tc);
//window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? 0x80008000 : 0x80000080); window->DrawList->PopClipRect(); // Debug
}
}
- want_close = (opened && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle);
- want_open = (!opened && hovered && !moving_within_opened_triangle) || (!opened && hovered && pressed);
+ want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle);
+ want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed);
}
- else if (opened && pressed && menuset_opened) // menu-bar: click open menu to close
+ else if (menu_is_open && pressed && menuset_is_open) // menu-bar: click open menu to close
{
want_close = true;
- want_open = opened = false;
+ want_open = menu_is_open = false;
}
- else if (pressed || (hovered && menuset_opened && !opened)) // menu-bar: first click to open, then hover to open others
+ else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // menu-bar: first click to open, then hover to open others
want_open = true;
-
+ if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
+ want_close = true;
if (want_close && IsPopupOpen(id))
ClosePopupToLevel(GImGui->CurrentPopupStack.Size);
- if (!opened && want_open && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size)
+ if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size)
{
// Don't recycle same menu level in the same frame, first close the other menu and yield for a frame.
- ImGui::OpenPopup(label);
+ OpenPopup(label);
return false;
}
- opened |= want_open;
+ menu_is_open |= want_open;
if (want_open)
- ImGui::OpenPopup(label);
+ OpenPopup(label);
- if (opened)
+ if (menu_is_open)
{
- ImGui::SetNextWindowPos(popup_pos, ImGuiSetCond_Always);
+ SetNextWindowPos(popup_pos, ImGuiSetCond_Always);
ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu);
- opened = BeginPopupEx(label, flags); // opened can be 'false' when the popup is completely clipped (e.g. zero size display)
+ menu_is_open = BeginPopupEx(label, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
}
- return opened;
+ return menu_is_open;
}
void ImGui::EndMenu()
{
- ImGui::EndPopup();
+ EndPopup();
}
// A little colored square. Return true when clicked.
@@ -8564,7 +8838,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID("#colorbutton");
const float square_size = g.FontSize;
@@ -8578,7 +8852,7 @@
RenderFrame(bb.Min, bb.Max, GetColorU32(col), outline_border, style.FrameRounding);
if (hovered)
- ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8(col.x), IM_F32_TO_INT8(col.y), IM_F32_TO_INT8(col.z), IM_F32_TO_INT8(col.z));
+ SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8(col.x), IM_F32_TO_INT8(col.y), IM_F32_TO_INT8(col.z), IM_F32_TO_INT8(col.z));
return pressed;
}
@@ -8600,7 +8874,7 @@
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const float w_full = CalcItemWidth();
@@ -8623,7 +8897,7 @@
float f[4] = { col[0], col[1], col[2], col[3] };
if (flags & ImGuiColorEditFlags_HSV)
- ImGui::ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
+ ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
int i[4] = { IM_F32_TO_INT8(f[0]), IM_F32_TO_INT8(f[1]), IM_F32_TO_INT8(f[2]), IM_F32_TO_INT8(f[3]) };
@@ -8631,8 +8905,8 @@
bool value_changed = false;
int components = alpha ? 4 : 3;
- ImGui::BeginGroup();
- ImGui::PushID(label);
+ BeginGroup();
+ PushID(label);
if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoSliders) == 0)
{
@@ -8651,17 +8925,17 @@
};
const char** fmt = hide_prefix ? fmt_table[0] : (flags & ImGuiColorEditFlags_HSV) ? fmt_table[2] : fmt_table[1];
- ImGui::PushItemWidth(w_item_one);
+ PushItemWidth(w_item_one);
for (int n = 0; n < components; n++)
{
if (n > 0)
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
+ SameLine(0, style.ItemInnerSpacing.x);
if (n + 1 == components)
- ImGui::PushItemWidth(w_item_last);
- value_changed |= ImGui::DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]);
+ PushItemWidth(w_item_last);
+ value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]);
}
- ImGui::PopItemWidth();
- ImGui::PopItemWidth();
+ PopItemWidth();
+ PopItemWidth();
}
else if ((flags & ImGuiColorEditFlags_HEX) != 0 && (flags & ImGuiColorEditFlags_NoSliders) == 0)
{
@@ -8685,7 +8959,7 @@
else
sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
}
- ImGui::PopItemWidth();
+ PopItemWidth();
}
const char* label_display_end = FindRenderedTextEnd(label);
@@ -8694,50 +8968,50 @@
if (!(flags & ImGuiColorEditFlags_NoColorSquare))
{
if (!(flags & ImGuiColorEditFlags_NoSliders))
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
+ SameLine(0, style.ItemInnerSpacing.x);
const ImVec4 col_display(col[0], col[1], col[2], 1.0f);
- if (ImGui::ColorButton(col_display))
+ if (ColorButton(col_display))
{
if (!(flags & ImGuiColorEditFlags_NoPicker))
{
- ImGui::OpenPopup("picker");
- ImGui::SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y));
+ OpenPopup("picker");
+ SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y));
}
}
- else if (!(flags & ImGuiColorEditFlags_NoOptions) && ImGui::IsItemHovered() && ImGui::IsMouseClicked(1))
+ else if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1))
{
- ImGui::OpenPopup("context");
+ OpenPopup("context");
}
- if (ImGui::BeginPopup("picker"))
+ if (BeginPopup("picker"))
{
picker_active = true;
if (label != label_display_end)
- ImGui::TextUnformatted(label, label_display_end);
- ImGui::PushItemWidth(256.0f + (alpha ? 2 : 1) * (style.ItemInnerSpacing.x));
- value_changed |= ImGui::ColorPicker4("##picker", col, (flags & ImGuiColorEditFlags_Alpha) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX));
- ImGui::PopItemWidth();
- ImGui::EndPopup();
+ TextUnformatted(label, label_display_end);
+ PushItemWidth(256.0f + (alpha ? 2 : 1) * (style.ItemInnerSpacing.x));
+ value_changed |= ColorPicker4("##picker", col, (flags & ImGuiColorEditFlags_Alpha) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX));
+ PopItemWidth();
+ EndPopup();
}
- if (!(flags & ImGuiColorEditFlags_NoOptions) && ImGui::BeginPopup("context"))
+ if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context"))
{
// FIXME-LOCALIZATION
- if (ImGui::MenuItem("Edit as RGB", NULL, (flags & ImGuiColorEditFlags_RGB)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_RGB));
- if (ImGui::MenuItem("Edit as HSV", NULL, (flags & ImGuiColorEditFlags_HSV)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HSV));
- if (ImGui::MenuItem("Edit as Hexadecimal", NULL, (flags & ImGuiColorEditFlags_HEX)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HEX));
- ImGui::EndPopup();
+ if (MenuItem("Edit as RGB", NULL, (flags & ImGuiColorEditFlags_RGB)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_RGB));
+ if (MenuItem("Edit as HSV", NULL, (flags & ImGuiColorEditFlags_HSV)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HSV));
+ if (MenuItem("Edit as Hexadecimal", NULL, (flags & ImGuiColorEditFlags_HEX)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HEX));
+ EndPopup();
}
// Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here
- if (ImGui::IsItemHovered())
- ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8(col[0]), IM_F32_TO_INT8(col[1]), IM_F32_TO_INT8(col[2]), IM_F32_TO_INT8(col[3]));
+ if (IsItemHovered())
+ SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8(col[0]), IM_F32_TO_INT8(col[1]), IM_F32_TO_INT8(col[2]), IM_F32_TO_INT8(col[3]));
}
if (label != label_display_end)
{
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
- ImGui::TextUnformatted(label, label_display_end);
+ SameLine(0, style.ItemInnerSpacing.x);
+ TextUnformatted(label, label_display_end);
}
// Convert back
@@ -8746,7 +9020,7 @@
for (int n = 0; n < 4; n++)
f[n] = i[n] / 255.0f;
if (flags & ImGuiColorEditFlags_HSV)
- ImGui::ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
+ ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
if (value_changed)
{
col[0] = f[0];
@@ -8757,8 +9031,8 @@
}
}
- ImGui::PopID();
- ImGui::EndGroup();
+ PopID();
+ EndGroup();
return value_changed;
}
@@ -8807,9 +9081,9 @@
}
// Hue bar logic
- ImGui::SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
- ImGui::InvisibleButton("hue", ImVec2(bars_width, sv_picker_size));
- if (ImGui::IsItemActive())
+ SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
+ InvisibleButton("hue", ImVec2(bars_width, sv_picker_size));
+ if (IsItemActive())
{
H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1));
value_changed = hsv_changed = true;
@@ -8818,9 +9092,9 @@
// Alpha bar logic
if (alpha)
{
- ImGui::SetCursorScreenPos(ImVec2(bar1_pos_x, picker_pos.y));
- ImGui::InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size));
- if (ImGui::IsItemActive())
+ SetCursorScreenPos(ImVec2(bar1_pos_x, picker_pos.y));
+ InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size));
+ if (IsItemActive())
{
col[3] = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1));
value_changed = true;
@@ -8830,13 +9104,13 @@
const char* label_display_end = FindRenderedTextEnd(label);
if (label != label_display_end)
{
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
- ImGui::TextUnformatted(label, label_display_end);
+ SameLine(0, style.ItemInnerSpacing.x);
+ TextUnformatted(label, label_display_end);
}
// Convert back color to RGB
if (hsv_changed)
- ImGui::ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]);
+ ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]);
// R,G,B and H,S,V slider color editor
if (!(flags & ImGuiColorEditFlags_NoSliders))
@@ -8870,7 +9144,7 @@
// Render hue bar
ImVec4 hue_color_f(1, 1, 1, 1);
- ImGui::ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z);
+ ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z);
ImU32 hue_colors[] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) };
for (int i = 0; i < 6; ++i)
{
@@ -8892,7 +9166,7 @@
}
// Render color matrix
- ImU32 hue_color32 = ImGui::ColorConvertFloat4ToU32(hue_color_f);
+ ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f);
draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE);
draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK);
@@ -8904,8 +9178,8 @@
draw_list->AddLine(ImVec2(p.x, p.y + CROSSHAIR_SIZE), ImVec2(p.x, p.y + 2), IM_COL32_WHITE);
draw_list->AddLine(ImVec2(p.x, p.y - CROSSHAIR_SIZE), ImVec2(p.x, p.y - 2), IM_COL32_WHITE);
- ImGui::EndGroup();
- ImGui::PopID();
+ EndGroup();
+ PopID();
return value_changed;
}
@@ -8936,9 +9210,9 @@
window->DrawList->AddLine(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border));
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.LogEnabled)
- ImGui::LogText(IM_NEWLINE "--------------------------------");
+ LogText(IM_NEWLINE "--------------------------------");
if (window->DC.ColumnsCount > 1)
{
@@ -8987,7 +9261,7 @@
group_data.BackupLogLinePosY = window->DC.LogLinePosY;
group_data.AdvanceCursor = true;
- window->DC.IndentX = window->DC.CursorPos.x - window->Pos.x;
+ window->DC.IndentX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX;
window->DC.CursorMaxPos = window->DC.CursorPos;
window->DC.CurrentLineHeight = 0.0f;
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f;
@@ -8996,7 +9270,7 @@
void ImGui::EndGroup()
{
ImGuiWindow* window = GetCurrentWindow();
- ImGuiStyle& style = ImGui::GetStyle();
+ ImGuiStyle& style = GetStyle();
IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls
@@ -9036,7 +9310,7 @@
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (pos_x != 0.0f)
{
if (spacing_w < 0.0f) spacing_w = 0.0f;
@@ -9053,23 +9327,34 @@
window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
}
+void ImGui::NewLine()
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return;
+ if (window->DC.CurrentLineHeight > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
+ ItemSize(ImVec2(0,0));
+ else
+ ItemSize(ImVec2(0.0f, GImGui->FontSize));
+}
+
void ImGui::NextColumn()
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return;
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (window->DC.ColumnsCount > 1)
{
- ImGui::PopItemWidth();
+ PopItemWidth();
PopClipRect();
window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y);
if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount)
{
// Columns 1+ cancel out IndentX
- window->DC.ColumnsOffsetX = ImGui::GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x;
+ window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x;
window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent);
}
else
@@ -9085,7 +9370,7 @@
window->DC.CurrentLineTextBaseOffset = 0.0f;
PushColumnClipRect();
- ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); // FIXME: Move on columns setup
+ PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup
}
}
@@ -9105,12 +9390,12 @@
{
// Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
// window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = ImGui::GetCurrentWindowRead();
IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets.
IM_ASSERT(g.ActiveId == window->DC.ColumnsSetID + ImGuiID(column_index));
- float x = g.IO.MousePos.x + g.ActiveClickDeltaToCenter.x - window->Pos.x;
+ float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x;
x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing);
return (float)(int)x;
@@ -9118,7 +9403,7 @@
float ImGui::GetColumnOffset(int column_index)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindowRead();
if (column_index < 0)
column_index = window->DC.ColumnsCurrent;
@@ -9156,7 +9441,7 @@
if (column_index < 0)
column_index = window->DC.ColumnsCurrent;
- const float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index);
+ float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index);
return w;
}
@@ -9166,14 +9451,14 @@
if (column_index < 0)
column_index = window->DC.ColumnsCurrent;
- const float x1 = window->Pos.x + ImGui::GetColumnOffset(column_index) - 1;
- const float x2 = window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1;
+ float x1 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index) - 1.0f);
+ float x2 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1.0f);
ImGui::PushClipRect(ImVec2(x1,-FLT_MAX), ImVec2(x2,+FLT_MAX), true);
}
void ImGui::Columns(int columns_count, const char* id, bool border)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count >= 1);
@@ -9181,7 +9466,7 @@
{
if (window->DC.ColumnsCurrent != 0)
ItemSize(ImVec2(0,0)); // Advance to column 0
- ImGui::PopItemWidth();
+ PopItemWidth();
PopClipRect();
window->DrawList->ChannelsMerge();
@@ -9203,7 +9488,7 @@
continue;
bool hovered, held;
- ButtonBehavior(column_rect, column_id, &hovered, &held, true);
+ ButtonBehavior(column_rect, column_id, &hovered, &held);
if (hovered || held)
g.MouseCursor = ImGuiMouseCursor_ResizeEW;
@@ -9215,7 +9500,7 @@
if (held)
{
if (g.ActiveIdIsJustActivated)
- g.ActiveClickDeltaToCenter.x = x - g.IO.MousePos.x;
+ g.ActiveIdClickOffset.x -= 4; // Store from center of column line
x = GetDraggedColumnOffset(i);
SetColumnOffset(i, x);
}
@@ -9224,16 +9509,16 @@
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
// In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
- ImGui::PushID(0x11223347 + (id ? 0 : columns_count));
+ PushID(0x11223347 + (id ? 0 : columns_count));
window->DC.ColumnsSetID = window->GetID(id ? id : "columns");
- ImGui::PopID();
+ PopID();
// Set state for first column
window->DC.ColumnsCurrent = 0;
window->DC.ColumnsCount = columns_count;
window->DC.ColumnsShowBorders = border;
- const float content_region_width = window->SizeContentsExplicit.x ? window->SizeContentsExplicit.x : window->Size.x;
+ const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x;
window->DC.ColumnsMinX = window->DC.IndentX; // Lock our horizontal range
window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x;
window->DC.ColumnsStartPosY = window->DC.CursorPos.y;
@@ -9255,7 +9540,7 @@
}
window->DrawList->ChannelsSplit(window->DC.ColumnsCount);
PushColumnClipRect();
- ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f);
+ PushItemWidth(GetColumnWidth() * 0.65f);
}
else
{
@@ -9263,26 +9548,26 @@
}
}
-void ImGui::Indent()
+void ImGui::Indent(float indent_w)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
- window->DC.IndentX += g.Style.IndentSpacing;
+ window->DC.IndentX += (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing;
window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX;
}
-void ImGui::Unindent()
+void ImGui::Unindent(float indent_w)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
- window->DC.IndentX -= g.Style.IndentSpacing;
+ window->DC.IndentX -= (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing;
window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX;
}
void ImGui::TreePush(const char* str_id)
{
ImGuiWindow* window = GetCurrentWindow();
- ImGui::Indent();
+ Indent();
window->DC.TreeDepth++;
PushID(str_id ? str_id : "#TreePush");
}
@@ -9290,32 +9575,40 @@
void ImGui::TreePush(const void* ptr_id)
{
ImGuiWindow* window = GetCurrentWindow();
- ImGui::Indent();
+ Indent();
window->DC.TreeDepth++;
PushID(ptr_id ? ptr_id : (const void*)"#TreePush");
}
+void ImGui::TreePushRawID(ImGuiID id)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ Indent();
+ window->DC.TreeDepth++;
+ window->IDStack.push_back(id);
+}
+
void ImGui::TreePop()
{
ImGuiWindow* window = GetCurrentWindow();
- ImGui::Unindent();
+ Unindent();
window->DC.TreeDepth--;
PopID();
}
void ImGui::Value(const char* prefix, bool b)
{
- ImGui::Text("%s: %s", prefix, (b ? "true" : "false"));
+ Text("%s: %s", prefix, (b ? "true" : "false"));
}
void ImGui::Value(const char* prefix, int v)
{
- ImGui::Text("%s: %d", prefix, v);
+ Text("%s: %d", prefix, v);
}
void ImGui::Value(const char* prefix, unsigned int v)
{
- ImGui::Text("%s: %d", prefix, v);
+ Text("%s: %d", prefix, v);
}
void ImGui::Value(const char* prefix, float v, const char* float_format)
@@ -9324,33 +9617,33 @@
{
char fmt[64];
ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format);
- ImGui::Text(fmt, prefix, v);
+ Text(fmt, prefix, v);
}
else
{
- ImGui::Text("%s: %.3f", prefix, v);
+ Text("%s: %.3f", prefix, v);
}
}
// FIXME: May want to remove those helpers?
void ImGui::ValueColor(const char* prefix, const ImVec4& v)
{
- ImGui::Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w);
- ImGui::SameLine();
- ImGui::ColorButton(v, true);
+ Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w);
+ SameLine();
+ ColorButton(v, true);
}
void ImGui::ValueColor(const char* prefix, unsigned int v)
{
- ImGui::Text("%s: %08X", prefix, v);
- ImGui::SameLine();
+ Text("%s: %08X", prefix, v);
+ SameLine();
ImVec4 col;
col.x = (float)((v >> 0) & 0xFF) / 255.0f;
col.y = (float)((v >> 8) & 0xFF) / 255.0f;
col.z = (float)((v >> 16) & 0xFF) / 255.0f;
col.w = (float)((v >> 24) & 0xFF) / 255.0f;
- ImGui::ColorButton(col, true);
+ ColorButton(col, true);
}
//-----------------------------------------------------------------------------
@@ -9422,7 +9715,7 @@
// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
static void SetClipboardTextFn_DefaultImpl(const char* text)
{
- ImGuiState& g = *GImGui;
+ ImGuiContext& g = *GImGui;
if (g.PrivateClipboard)
{
ImGui::MemFree(g.PrivateClipboard);
@@ -9468,9 +9761,9 @@
// HELP
//-----------------------------------------------------------------------------
-void ImGui::ShowMetricsWindow(bool* opened)
+void ImGui::ShowMetricsWindow(bool* p_open)
{
- if (ImGui::Begin("ImGui Metrics", opened))
+ if (ImGui::Begin("ImGui Metrics", p_open))
{
ImGui::Text("ImGui %s", ImGui::GetVersion());
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
@@ -9484,15 +9777,15 @@
{
static void NodeDrawList(ImDrawList* draw_list, const char* label)
{
- bool node_opened = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size);
+ bool node_open = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size);
if (draw_list == ImGui::GetWindowDrawList())
{
ImGui::SameLine();
ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered)
- if (node_opened) ImGui::TreePop();
+ if (node_open) ImGui::TreePop();
return;
}
- if (!node_opened)
+ if (!node_open)
return;
ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list
@@ -9505,33 +9798,35 @@
ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData);
continue;
}
- bool draw_opened = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
+ ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
+ bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
if (show_clip_rects && ImGui::IsItemHovered())
{
ImRect clip_rect = pcmd->ClipRect;
ImRect vtxs_rect;
- ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
- clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, ImColor(255,255,0));
- vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, ImColor(255,0,255));
+ clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255));
+ vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255));
}
- if (!draw_opened)
+ if (!pcmd_node_open)
continue;
- for (int i = elem_offset; i+2 < elem_offset + (int)pcmd->ElemCount; i += 3)
- {
- ImVec2 triangles_pos[3];
- char buf[300], *buf_p = buf;
- for (int n = 0; n < 3; n++)
+ ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible.
+ while (clipper.Step())
+ for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++)
{
- ImDrawVert& v = draw_list->VtxBuffer[(draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data[i+n] : i+n];
- triangles_pos[n] = v.pos;
- buf_p += sprintf(buf_p, "vtx %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", i+n, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
+ char buf[300], *buf_p = buf;
+ ImVec2 triangles_pos[3];
+ for (int n = 0; n < 3; n++, vtx_i++)
+ {
+ ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[vtx_i] : vtx_i];
+ triangles_pos[n] = v.pos;
+ buf_p += sprintf(buf_p, "%s %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
+ }
+ ImGui::Selectable(buf, false);
+ if (ImGui::IsItemHovered())
+ overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle
}
- ImGui::Selectable(buf, false);
- if (ImGui::IsItemHovered())
- overlay_draw_list->AddPolyline(triangles_pos, 3, ImColor(255,255,0), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle
- }
ImGui::TreePop();
}
overlay_draw_list->PopClipRect();
@@ -9559,7 +9854,7 @@
}
};
- ImGuiState& g = *GImGui; // Access private state
+ ImGuiContext& g = *GImGui; // Access private state
Funcs::NodeWindows(g.Windows, "Windows");
if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.RenderDrawLists[0].Size))
{
@@ -9567,12 +9862,12 @@
Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList");
ImGui::TreePop();
}
- if (ImGui::TreeNode("Popups", "Opened Popups Stack (%d)", g.OpenedPopupStack.Size))
+ if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size))
{
- for (int i = 0; i < g.OpenedPopupStack.Size; i++)
+ for (int i = 0; i < g.OpenPopupStack.Size; i++)
{
- ImGuiWindow* window = g.OpenedPopupStack[i].Window;
- ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenedPopupStack[i].PopupID, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : "");
+ ImGuiWindow* window = g.OpenPopupStack[i].Window;
+ ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupID, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : "");
}
ImGui::TreePop();
}
diff --git a/README.md b/README.md
index 88c7f4e..9e32e9e 100644
--- a/README.md
+++ b/README.md
@@ -95,12 +95,15 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
diff --git a/examples/README.txt b/examples/README.txt
index df6fe87..df2e86d 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -71,7 +71,7 @@
sdl_opengl_example/
SDL2 + OpenGL example.
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp
index f0e57f7..bccee87 100644
--- a/examples/directx10_example/imgui_impl_dx10.cpp
+++ b/examples/directx10_example/imgui_impl_dx10.cpp
@@ -34,6 +34,7 @@
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
+static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -125,6 +126,8 @@
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
@@ -141,6 +144,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
@@ -176,6 +180,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -208,6 +213,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
@@ -337,6 +343,12 @@
if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -447,6 +459,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D10_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX10_CreateFontsTexture();
return true;
@@ -463,6 +489,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp
index f47f9d5..fb98cad 100644
--- a/examples/directx10_example/main.cpp
+++ b/examples/directx10_example/main.cpp
@@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h"
#include
#include
-#include
#define DIRECTINPUT_VERSION 0x0800
#include
#include
@@ -63,27 +62,6 @@
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
- // Setup rasterizer
- {
- D3D10_RASTERIZER_DESC RSDesc;
- memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
- RSDesc.FillMode = D3D10_FILL_SOLID;
- RSDesc.CullMode = D3D10_CULL_NONE;
- RSDesc.FrontCounterClockwise = FALSE;
- RSDesc.DepthBias = 0;
- RSDesc.SlopeScaledDepthBias = 0.0f;
- RSDesc.DepthBiasClamp = 0;
- RSDesc.DepthClipEnable = TRUE;
- RSDesc.ScissorEnable = TRUE;
- RSDesc.AntialiasedLineEnable = FALSE;
- RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
-
- ID3D10RasterizerState* pRState = NULL;
- g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
- g_pd3dDevice->RSSetState(pRState);
- pRState->Release();
- }
-
CreateRenderTarget();
return S_OK;
diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp
index 5f209bc..11f66f0 100644
--- a/examples/directx11_example/imgui_impl_dx11.cpp
+++ b/examples/directx11_example/imgui_impl_dx11.cpp
@@ -34,6 +34,7 @@
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
+static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
@@ -127,6 +128,8 @@
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
+ UINT StencilRef;
+ ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
@@ -145,6 +148,7 @@
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
+ ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
@@ -181,6 +185,7 @@
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists
@@ -213,6 +218,7 @@
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
+ ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
@@ -339,6 +345,12 @@
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
+ // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
+ // If you would like to use this DX11 sample code but remove this dependency you can:
+ // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
+ // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
+ // See https://github.com/ocornut/imgui/pull/638 for sources and details.
+
// Create the vertex shader
{
static const char* vertexShader =
@@ -448,6 +460,20 @@
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
+ // Create depth-stencil State
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.DepthEnable = false;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ desc.StencilEnable = false;
+ desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ desc.BackFace = desc.FrontFace;
+ g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ }
+
ImGui_ImplDX11_CreateFontsTexture();
return true;
@@ -464,6 +490,7 @@
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
+ if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp
index d90f49c..e3fe5aa 100644
--- a/examples/directx11_example/main.cpp
+++ b/examples/directx11_example/main.cpp
@@ -4,7 +4,6 @@
#include
#include "imgui_impl_dx11.h"
#include