parent
929522febe
commit
0e83d74698
70
imgui.cpp
70
imgui.cpp
@ -448,26 +448,46 @@
|
||||
It could be an identifier to your OpenGL texture (cast GLuint to void*), a pointer to your custom engine material (cast MyMaterial* to void*), etc.
|
||||
At the end of the chain, your renderer takes this void* to cast it back into whatever it needs to select a current texture to render.
|
||||
Refer to examples applications, where each renderer (in a imgui_impl_xxxx.cpp file) is treating ImTextureID as a different thing.
|
||||
(C++ tip: OpenGL uses integers to identify textures. You can safely store an integer into a void*, just cast it to void*, don't take it's address!)
|
||||
|
||||
// The example OpenGL back-end uses integers to identify textures.
|
||||
// You can safely store an integer into a void* by casting it. e.g. (void*)(intptr_t)MY_GL_UINT to cast to void*.
|
||||
GLuint my_opengl_texture;
|
||||
glGenTextures(1, &my_opengl_texture);
|
||||
// [...] load image, render to texture, etc.
|
||||
ImGui::Image((void*)(intptr_t)my_opengl_texture, ImVec2(512,512));
|
||||
|
||||
// The example DirectX11 back-end uses ID3D11ShaderResourceView* to identify textures.
|
||||
ID3D11ShaderResourceView* my_texture_view;
|
||||
device->CreateShaderResourceView(my_texture, &my_shader_resource_view_desc, &my_texture_view);
|
||||
ImGui::Image((void*)my_texture_view, ImVec2(512,512));
|
||||
|
||||
To display a custom image/texture within an ImGui window, you may use ImGui::Image(), ImGui::ImageButton(), ImDrawList::AddImage() functions.
|
||||
Dear ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use.
|
||||
You may call ImGui::ShowMetricsWindow() to explore active draw lists and visualize/understand how the draw data is generated.
|
||||
It is your responsibility to get textures uploaded to your GPU.
|
||||
|
||||
Q: How can I have multiple widgets with the same label or without a label?
|
||||
Q: I have multiple widgets with the same label, and only the first one works. Why is that?
|
||||
A: A primer on labels and the ID Stack...
|
||||
|
||||
- Elements that are typically not clickable, such as Text() items don't need an ID.
|
||||
Dear ImGui internally need to uniquely identify UI elements.
|
||||
Elements that are typically not clickable (such as calls to the Text functions) don't need an ID.
|
||||
Interactive widgets (such as calls to Button buttons) need a unique ID.
|
||||
Unique ID are used internally to track active widgets and occasionally associate state to widgets.
|
||||
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.
|
||||
|
||||
- Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui
|
||||
often needs to remember what is the "active" widget). To do so they need a unique ID. Unique ID
|
||||
are typically derived from a string label, an integer index or a pointer.
|
||||
- Unique ID are often derived from a string label:
|
||||
|
||||
Button("OK"); // Label = "OK", ID = top of id stack + hash of "OK"
|
||||
Button("Cancel"); // Label = "Cancel", ID = top of id stack + hash of "Cancel"
|
||||
Button("OK"); // Label = "OK", ID = hash of (..., "OK")
|
||||
Button("Cancel"); // Label = "Cancel", ID = hash of (..., "Cancel")
|
||||
|
||||
- ID are uniquely scoped within windows, tree nodes, etc. which all pushes to the ID stack. Having
|
||||
two buttons labeled "OK" in different windows or different tree locations is fine.
|
||||
We used "..." above to signify whatever was already pushed to the ID stack previously:
|
||||
|
||||
Begin("MyWindow");
|
||||
Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK")
|
||||
End();
|
||||
|
||||
- If you have a same ID twice in the same location, you'll have a conflict:
|
||||
|
||||
@ -482,20 +502,22 @@
|
||||
This helps solving the simple collision cases when you know e.g. at compilation time which items
|
||||
are going to be created:
|
||||
|
||||
Button("Play"); // Label = "Play", ID = top of id stack + hash of "Play"
|
||||
Button("Play##foo1"); // Label = "Play", ID = top of id stack + hash of "Play##foo1" (different from above)
|
||||
Button("Play##foo2"); // Label = "Play", ID = top of id stack + hash of "Play##foo2" (different from above)
|
||||
Begin("MyWindow");
|
||||
Button("Play"); // Label = "Play", ID = hash of ("MyWindow", "Play")
|
||||
Button("Play##foo1"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo1") // Different from above
|
||||
Button("Play##foo2"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo2") // Different from above
|
||||
End();
|
||||
|
||||
- If you want to completely hide the label, but still need an ID:
|
||||
|
||||
Checkbox("##On", &b); // Label = "", ID = top of id stack + hash of "##On" (no label!)
|
||||
Checkbox("##On", &b); // Label = "", ID = hash of (..., "##On") // No visible label!
|
||||
|
||||
- Occasionally/rarely you might want change a label while preserving a constant ID. This allows
|
||||
you to animate labels. For example you may want to include varying information in a window title bar,
|
||||
but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID:
|
||||
|
||||
Button("Hello###ID"; // Label = "Hello", ID = top of id stack + hash of "ID"
|
||||
Button("World###ID"; // Label = "World", ID = top of id stack + hash of "ID" (same as above)
|
||||
Button("Hello###ID"; // Label = "Hello", ID = hash of (..., "ID")
|
||||
Button("World###ID"; // Label = "World", ID = hash of (..., "ID") // Same as above, even though the label looks different
|
||||
|
||||
sprintf(buf, "My game (%f FPS)###MyGame", fps);
|
||||
Begin(buf); // Variable label, ID = hash of "MyGame"
|
||||
@ -507,45 +529,45 @@
|
||||
You can push a pointer, a string or an integer value into the ID stack.
|
||||
Remember that ID are formed from the concatenation of _everything_ in the ID stack!
|
||||
|
||||
Begin("Window");
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
PushID(i);
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of integer + hash of "Click"
|
||||
PushID(i); // Push i to the id tack
|
||||
Button("Click"); // Label = "Click", ID = Hash of ("Window", i, "Click")
|
||||
PopID();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
MyObject* obj = Objects[i];
|
||||
PushID(obj);
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of pointer + hash of "Click"
|
||||
Button("Click"); // Label = "Click", ID = Hash of ("Window", obj pointer, "Click")
|
||||
PopID();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
MyObject* obj = Objects[i];
|
||||
PushID(obj->Name);
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of string + hash of "Click"
|
||||
Button("Click"); // Label = "Click", ID = Hash of ("Window", obj->Name, "Click")
|
||||
PopID();
|
||||
}
|
||||
End();
|
||||
|
||||
- More example showing that you can stack multiple prefixes into the ID stack:
|
||||
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of "Click"
|
||||
Button("Click"); // Label = "Click", ID = hash of (..., "Click")
|
||||
PushID("node");
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of "node" + hash of "Click"
|
||||
Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
|
||||
PushID(my_ptr);
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of "node" + hash of ptr + hash of "Click"
|
||||
Button("Click"); // Label = "Click", ID = hash of (..., "node", my_ptr, "Click")
|
||||
PopID();
|
||||
PopID();
|
||||
|
||||
- Tree nodes implicitly creates a scope for you by calling PushID().
|
||||
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of "Click"
|
||||
Button("Click"); // Label = "Click", ID = hash of (..., "Click")
|
||||
if (TreeNode("node"))
|
||||
{
|
||||
Button("Click"); // Label = "Click", ID = top of id stack + hash of "node" + hash of "Click"
|
||||
Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
|
||||
TreePop();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ In this document:
|
||||
FONTS LOADING INSTRUCTIONS
|
||||
---------------------------------------
|
||||
|
||||
Load default font with:
|
||||
Load default font:
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->AddFontDefault();
|
||||
@ -78,15 +78,22 @@ In this document:
|
||||
Load .TTF/.OTF file with:
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
|
||||
ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
|
||||
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels);
|
||||
|
||||
For advanced options create a ImFontConfig structure and pass it to the AddFont function (it will be copied internally)
|
||||
// Select font at runtime
|
||||
ImGui::Text("Hello"); // use the default font (which is the first loaded font)
|
||||
ImGui::PushFont(font2);
|
||||
ImGui::Text("Hello with another font");
|
||||
ImGui::PopFont();
|
||||
|
||||
For advanced options create a ImFontConfig structure and pass it to the AddFont function (it will be copied internally):
|
||||
|
||||
ImFontConfig config;
|
||||
config.OversampleH = 3;
|
||||
config.OversampleV = 1;
|
||||
config.GlyphExtraSpacing.x = 1.0f;
|
||||
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
|
||||
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
|
||||
|
||||
If you have very large number of glyphs or multiple fonts:
|
||||
|
||||
@ -99,7 +106,7 @@ In this document:
|
||||
Combine two fonts into one:
|
||||
|
||||
// Load a first font
|
||||
io.Fonts->AddFontDefault();
|
||||
ImFont* font = io.Fonts->AddFontDefault();
|
||||
|
||||
// Add character ranges and merge into the previous font
|
||||
// The ranges array is not copied by the AddFont* functions and is used lazily
|
||||
@ -144,7 +151,7 @@ In this document:
|
||||
---------------------------------------
|
||||
|
||||
You can use the ImFontAtlas::GlyphRangesBuilder helper to create glyph ranges based on text input.
|
||||
For exemple: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
|
||||
For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
|
||||
|
||||
ImVector<ImWchar> ranges;
|
||||
ImFontAtlas::GlyphRangesBuilder builder;
|
||||
|
Loading…
Reference in New Issue
Block a user