Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	examples/imgui_impl_opengl3.cpp
#	imgui.h
This commit is contained in:
omar 2020-07-14 18:38:47 +02:00
commit f79f0e42f7
16 changed files with 289 additions and 103 deletions

View File

@ -394,7 +394,9 @@ jobs:
- name: Build example_emscripten - name: Build example_emscripten
run: | run: |
source emsdk-master/emsdk_env.sh pushd emsdk-master
source ./emsdk_env.sh
popd
make -C examples/example_emscripten make -C examples/example_emscripten
Static-Analysis: Static-Analysis:

View File

@ -100,6 +100,32 @@ Other changes:
to make the examples main.cpp easier to read. to make the examples main.cpp easier to read.
-----------------------------------------------------------------------
VERSION 1.78 WIP (In Progress)
-----------------------------------------------------------------------
Other Changes:
- Nav: Fixed clicking on void from not clearing focused window.
This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard
flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880)
- InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more
than ~16 KB characters. (Note that current code is going to show corrupted display if after
clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText
call. ImGui-level functions such as TextUnformatted() are not affected. This is quite rare
but it will be addressed later). (#3349)
- ImDrawList: Thick anti-aliased strokes (> 1.0f) with integer thickness now use a texture-based
path, reducing the amount of vertices/indices and CPU/GPU usage. (#3245) [@Shironekoben]
- This change will facilitate the wider use of thick borders in future style changes.
- Requires an extra bit of texture space (~64x64 by default), relies on GPU bilinear filtering.
- Clear io.AntiAliasedLinesUseTex = false; to disable rendering using this method.
- Clear ImFontAtlasFlags_NoBakedLines in ImFontAtlas::Flags to disable baking data in texture.
- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would generate
an extra vertex. (This bug was mistakenly marked as fixed in earlier 1.77 release). [@ShironekoBen]
- Backends: OpenGL3: Added support for glad2 loader. (#3330) [@moritz-h]
>>>>>>> master
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.77 (Released 2020-06-29) VERSION 1.77 (Released 2020-06-29)
----------------------------------------------------------------------- -----------------------------------------------------------------------
@ -109,7 +135,7 @@ Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.77
Breaking Changes: Breaking Changes:
- Removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please - Removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please
note that this is a Beta api and will likely be reworked in order to support multi-DPI accross note that this is a Beta api and will likely be reworked in order to support multi-DPI across
multiple monitors. multiple monitors.
- Renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete). - Renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete).
- Removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor - Removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor
@ -167,8 +193,6 @@ Other Changes:
VtxOffset was not zero would lead to draw commands with wrong VtxOffset. (#2591) VtxOffset was not zero would lead to draw commands with wrong VtxOffset. (#2591)
- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after - ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after
a callback draw command would incorrectly override the callback draw command. a callback draw command would incorrectly override the callback draw command.
- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would
generate an extra unrequired vertex. [@ShironekoBen]
- Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeeds but FT_Load_Glyph() fails. - Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeeds but FT_Load_Glyph() fails.
- Docs: Improved and moved font documentation to docs/FONTS.md so it can be readable on the web. - Docs: Improved and moved font documentation to docs/FONTS.md so it can be readable on the web.
Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut] Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut]

View File

@ -336,7 +336,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. - font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise - font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
- font/draw: need to be able to specify wrap start position. - font/draw: need to be able to specify wrap start position.
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines) - font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines). also see #3349.
- font/draw: fix for drawing 16k+ visible characters in same call.
- font/draw: underline, squiggle line rendering helpers. - font/draw: underline, squiggle line rendering helpers.
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line. - font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list? - font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?

View File

@ -1,5 +1,5 @@
----------------------------------------------------------------------- -----------------------------------------------------------------------
dear imgui, v1.77 dear imgui, v1.78 WIP
----------------------------------------------------------------------- -----------------------------------------------------------------------
examples/README.txt examples/README.txt
(This is the README file for the examples/ folder. See docs/ for more documentation) (This is the README file for the examples/ folder. See docs/ for more documentation)
@ -211,7 +211,7 @@ example_glfw_opengl2/
GLFW + OpenGL2 example (legacy, fixed pipeline). GLFW + OpenGL2 example (legacy, fixed pipeline).
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp = main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** **DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
**Prefer using OPENGL3 code (with gl3w/glew/glad/glbinding, you can replace the OpenGL function loader)** **Prefer using OPENGL3 code (with gl3w/glew/glad/glad2/glbinding, you can replace the OpenGL function loader)**
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter. This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
make things more complicated, will require your code to reset many OpenGL attributes to their initial make things more complicated, will require your code to reset many OpenGL attributes to their initial
@ -260,7 +260,7 @@ example_sdl_opengl2/
SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline). SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline).
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp = main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** **DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
**Prefer using OPENGL3 code (with gl3w/glew/glad/glbinding, you can replace the OpenGL function loader)** **Prefer using OPENGL3 code (with gl3w/glew/glad/glad2/glbinding, you can replace the OpenGL function loader)**
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter. This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
make things more complicated, will require your code to reset many OpenGL attributes to their initial make things more complicated, will require your code to reset many OpenGL attributes to their initial

View File

@ -42,6 +42,10 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
# SOURCES += ../libs/glad/src/glad.c # SOURCES += ../libs/glad/src/glad.c
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD # CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD
## Using OpenGL loader: glad2
# SOURCES += ../libs/glad/src/gl.c
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD2
## Using OpenGL loader: glbinding ## Using OpenGL loader: glbinding
## This assumes a system-wide installation ## This assumes a system-wide installation
## of either version 3.0.0 (or newer) ## of either version 3.0.0 (or newer)

View File

@ -17,6 +17,8 @@
#include <GL/glew.h> // Initialize with glewInit() #include <GL/glew.h> // Initialize with glewInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h> // Initialize with gladLoadGL() #include <glad/glad.h> // Initialize with gladLoadGL()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
#include <glad/gl.h> // Initialize with gladLoadGL(...) or gladLoaderLoadGL()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
#include <glbinding/Binding.h> // Initialize with glbinding::Binding::initialize() #include <glbinding/Binding.h> // Initialize with glbinding::Binding::initialize()
@ -84,6 +86,8 @@ int main(int, char**)
bool err = glewInit() != GLEW_OK; bool err = glewInit() != GLEW_OK;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
bool err = gladLoadGL() == 0; bool err = gladLoadGL() == 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
bool err = gladLoadGL(glfwGetProcAddress) == 0; // glad2 recommend using the windowing library loader instead of the (optionally) bundled one.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
bool err = false; bool err = false;
glbinding::Binding::initialize(); glbinding::Binding::initialize();

View File

@ -42,6 +42,10 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
# SOURCES += ../libs/glad/src/glad.c # SOURCES += ../libs/glad/src/glad.c
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD # CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD
## Using OpenGL loader: glad2
# SOURCES += ../libs/glad/src/gl.c
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD2
## Using OpenGL loader: glbinding ## Using OpenGL loader: glbinding
## This assumes a system-wide installation ## This assumes a system-wide installation
## of either version 3.0.0 (or newer) ## of either version 3.0.0 (or newer)

View File

@ -19,6 +19,8 @@
#include <GL/glew.h> // Initialize with glewInit() #include <GL/glew.h> // Initialize with glewInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h> // Initialize with gladLoadGL() #include <glad/glad.h> // Initialize with gladLoadGL()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
#include <glad/gl.h> // Initialize with gladLoadGL(...) or gladLoaderLoadGL()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
#include <glbinding/Binding.h> // Initialize with glbinding::Binding::initialize() #include <glbinding/Binding.h> // Initialize with glbinding::Binding::initialize()
@ -79,6 +81,8 @@ int main(int, char**)
bool err = glewInit() != GLEW_OK; bool err = glewInit() != GLEW_OK;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
bool err = gladLoadGL() == 0; bool err = gladLoadGL() == 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
bool err = gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress) == 0; // glad2 recommend using the windowing library loader instead of the (optionally) bundled one.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
bool err = false; bool err = false;
glbinding::Binding::initialize(); glbinding::Binding::initialize();

View File

@ -15,6 +15,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX. // 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix. // 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
// 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset. // 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset.
@ -103,6 +104,8 @@
#include <GL/glew.h> // Needs to be initialized with glewInit() in user's code. #include <GL/glew.h> // Needs to be initialized with glewInit() in user's code.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h> // Needs to be initialized with gladLoadGL() in user's code. #include <glad/glad.h> // Needs to be initialized with gladLoadGL() in user's code.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
#include <glad/gl.h> // Needs to be initialized with gladLoadGL(...) or gladLoaderLoadGL() in user's code.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
#ifndef GLFW_INCLUDE_NONE #ifndef GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
@ -196,6 +199,8 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
gl_loader = "GLEW"; gl_loader = "GLEW";
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
gl_loader = "GLAD"; gl_loader = "GLAD";
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
gl_loader = "GLAD2";
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
gl_loader = "glbinding2"; gl_loader = "glbinding2";
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)

View File

@ -50,6 +50,7 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
@ -69,6 +70,8 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
#define IMGUI_IMPL_OPENGL_LOADER_GLEW #define IMGUI_IMPL_OPENGL_LOADER_GLEW
#elif __has_include(<glad/glad.h>) #elif __has_include(<glad/glad.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GLAD #define IMGUI_IMPL_OPENGL_LOADER_GLAD
#elif __has_include(<glad/gl.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GLAD2
#elif __has_include(<GL/gl3w.h>) #elif __has_include(<GL/gl3w.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GL3W #define IMGUI_IMPL_OPENGL_LOADER_GL3W
#elif __has_include(<glbinding/glbinding.h>) #elif __has_include(<glbinding/glbinding.h>)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.77 // dear imgui, v1.78 WIP
// (main code and documentation) // (main code and documentation)
// Help: // Help:
@ -961,8 +961,9 @@ ImGuiStyle::ImGuiStyle()
DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU.
AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require back-end to render with bilinear filtering.
AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
CircleSegmentMaxError = 1.60f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. CircleSegmentMaxError = 1.60f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
@ -3518,7 +3519,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0])) if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
g.MovingWindow = NULL; g.MovingWindow = NULL;
} }
else if (root_window != NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL) else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
{ {
// Clicking on void disable focus // Clicking on void disable focus
FocusWindow(NULL); FocusWindow(NULL);
@ -3871,6 +3872,8 @@ void ImGui::NewFrame()
g.DrawListSharedData.InitialFlags = ImDrawListFlags_None; g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
if (g.Style.AntiAliasedLines) if (g.Style.AntiAliasedLines)
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines; g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
if (g.Style.AntiAliasedLinesUseTex && !(g.Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines))
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex;
if (g.Style.AntiAliasedFill) if (g.Style.AntiAliasedFill)
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill; g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
@ -6816,6 +6819,7 @@ void ImGui::SetCurrentFont(ImFont* font)
ImFontAtlas* atlas = g.Font->ContainerAtlas; ImFontAtlas* atlas = g.Font->ContainerAtlas;
g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel; g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel;
g.DrawListSharedData.TexUvLines = atlas->TexUvLines;
g.DrawListSharedData.Font = g.Font; g.DrawListSharedData.Font = g.Font;
g.DrawListSharedData.FontSize = g.FontSize; g.DrawListSharedData.FontSize = g.FontSize;
} }

45
imgui.h
View File

@ -1,4 +1,4 @@
// dear imgui, v1.77 // dear imgui, v1.78 WIP
// (headers) // (headers)
// Help: // Help:
@ -60,8 +60,8 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.77" #define IMGUI_VERSION "1.78 WIP"
#define IMGUI_VERSION_NUM 17701 #define IMGUI_VERSION_NUM 17703
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch #define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch
#define IMGUI_HAS_DOCK 1 // Docking WIP branch #define IMGUI_HAS_DOCK 1 // Docking WIP branch
@ -158,7 +158,7 @@ typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A
typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling
typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: for ImDrawList::AddRect(), AddRectFilled() etc. typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: for ImDrawList::AddRect(), AddRectFilled() etc.
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build
typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags
typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc. typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc.
typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags
@ -770,7 +770,7 @@ namespace ImGui
IMGUI_API bool IsMouseDown(ImGuiMouseButton button); // is mouse button held? IMGUI_API bool IsMouseDown(ImGuiMouseButton button); // is mouse button held?
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down) IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down)
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down) IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? (note that a double-click will also report IsMouseClicked() == true)
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block. IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
IMGUI_API bool IsAnyMouseDown(); // is any mouse button held? IMGUI_API bool IsAnyMouseDown(); // is any mouse button held?
@ -1513,8 +1513,9 @@ struct ImGuiStyle
ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly! ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly!
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later. float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require back-end to render with bilinear filtering. Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
float CircleSegmentMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. float CircleSegmentMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
ImVec4 Colors[ImGuiCol_COUNT]; ImVec4 Colors[ImGuiCol_COUNT];
@ -2000,6 +2001,11 @@ struct ImColor
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList. // Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (63)
#endif
// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h] // ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
// NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering, // NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering,
// you can poke into the draw list for that! Draw callback may be useful for example to: // you can poke into the draw list for that! Draw callback may be useful for example to:
@ -2096,12 +2102,15 @@ enum ImDrawCornerFlags_
ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience
}; };
// Flags for ImDrawList. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly.
// It is however possible to temporarily alter flags between calls to ImDrawList:: functions.
enum ImDrawListFlags_ enum ImDrawListFlags_
{ {
ImDrawListFlags_None = 0, ImDrawListFlags_None = 0,
ImDrawListFlags_AntiAliasedLines = 1 << 0, // Lines are anti-aliased (*2 the number of triangles for 1.0f wide line, otherwise *3 the number of triangles) ImDrawListFlags_AntiAliasedLines = 1 << 0, // Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines thin enough to be drawn using textures, otherwise *3 the number of triangles)
ImDrawListFlags_AntiAliasedFill = 1 << 1, // Filled shapes have anti-aliased edges (*2 the number of vertices) ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require back-end to render with bilinear filtering.
ImDrawListFlags_AllowVtxOffset = 1 << 2 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled. ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles).
ImDrawListFlags_AllowVtxOffset = 1 << 3 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
}; };
// Draw command list // Draw command list
@ -2316,11 +2325,13 @@ struct ImFontAtlasCustomRect
bool IsPacked() const { return X != 0xFFFF; } bool IsPacked() const { return X != 0xFFFF; }
}; };
// Flags for ImFontAtlas build
enum ImFontAtlasFlags_ enum ImFontAtlasFlags_
{ {
ImFontAtlasFlags_None = 0, ImFontAtlasFlags_None = 0,
ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two
ImFontAtlasFlags_NoMouseCursors = 1 << 1 // Don't build software mouse cursors into the atlas ImFontAtlasFlags_NoMouseCursors = 1 << 1, // Don't build software mouse cursors into the atlas (save a little texture memory)
ImFontAtlasFlags_NoBakedLines = 1 << 2 // Don't build thick line textures into the atlas (save a little texture memory). The AntiAliasedLinesUseTex features uses them, otherwise they will be rendered using polygons (more expensive for CPU/GPU).
}; };
// Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding: // Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding:
@ -2394,7 +2405,7 @@ struct ImFontAtlas
// Note: this API may be redesigned later in order to support multi-monitor varying DPI settings. // Note: this API may be redesigned later in order to support multi-monitor varying DPI settings.
IMGUI_API int AddCustomRectRegular(int width, int height); IMGUI_API int AddCustomRectRegular(int width, int height);
IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0, 0)); IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0, 0));
const ImFontAtlasCustomRect*GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; } ImFontAtlasCustomRect* GetCustomRectByIndex(int index) { IM_ASSERT(index >= 0); return &CustomRects[index]; }
// [Internal] // [Internal]
IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const; IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const;
@ -2420,8 +2431,12 @@ struct ImFontAtlas
ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel
ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
ImVector<ImFontAtlasCustomRect> CustomRects; // Rectangles for packing custom texture data into the atlas. ImVector<ImFontAtlasCustomRect> CustomRects; // Rectangles for packing custom texture data into the atlas.
ImVector<ImFontConfig> ConfigData; // Internal data ImVector<ImFontConfig> ConfigData; // Configuration data
int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
// [Internal] Packing data
int PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors
int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+ typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+

View File

@ -1,4 +1,4 @@
// dear imgui, v1.77 // dear imgui, v1.78 WIP
// (demo code) // (demo code)
// Help: // Help:
@ -456,6 +456,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly); ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something).");
ImGui::Text("Also see Style->Rendering for rendering options.");
ImGui::TreePop(); ImGui::TreePop();
ImGui::Separator(); ImGui::Separator();
} }
@ -3284,7 +3285,7 @@ static void ShowDemoWindowMisc()
ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y); ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y);
ImGui::Text("Mouse down:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } ImGui::Text("Mouse down:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
ImGui::Text("Mouse clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } ImGui::Text("Mouse clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); }
ImGui::Text("Mouse dblclick:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } ImGui::Text("Mouse dblclick:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); }
ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); }
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
@ -3911,6 +3912,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
{ {
ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
ImGui::Checkbox("Anti-aliased lines use texture", &style.AntiAliasedLinesUseTex);
ImGui::SameLine(); HelpMarker("Faster lines using texture data. Require back-end to render with bilinear filtering (not point/nearest filtering).");
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f"); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f");

View File

@ -1,4 +1,4 @@
// dear imgui, v1.77 // dear imgui, v1.78 WIP
// (drawing and font code) // (drawing and font code)
/* /*
@ -364,6 +364,7 @@ ImDrawListSharedData::ImDrawListSharedData()
ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a)); ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a));
} }
memset(CircleSegmentCounts, 0, sizeof(CircleSegmentCounts)); // This will be set by SetCircleSegmentMaxError() memset(CircleSegmentCounts, 0, sizeof(CircleSegmentCounts)); // This will be set by SetCircleSegmentMaxError()
TexUvLines = NULL;
} }
void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error) void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
@ -522,7 +523,7 @@ void ImDrawList::_OnChangedVtxOffset()
// We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this. // We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this.
_VtxCurrentIdx = 0; _VtxCurrentIdx = 0;
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset); //IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset); // See #3349
if (curr_cmd->ElemCount != 0) if (curr_cmd->ElemCount != 0)
{ {
AddDrawCmd(); AddDrawCmd();
@ -587,6 +588,9 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0); IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
if (sizeof(ImDrawIdx) == 2 && (_VtxCurrentIdx + vtx_count >= (1 << 16)) && (Flags & ImDrawListFlags_AllowVtxOffset)) if (sizeof(ImDrawIdx) == 2 && (_VtxCurrentIdx + vtx_count >= (1 << 16)) && (Flags & ImDrawListFlags_AllowVtxOffset))
{ {
// FIXME: In theory we should be testing that vtx_count <64k here.
// In practice, RenderText() relies on reserving ahead for a worst case scenario so it is currently useful for us
// to not make that check until we rework the text functions to handle clipping and large horizontal lines better.
_CmdHeader.VtxOffset = VtxBuffer.Size; _CmdHeader.VtxOffset = VtxBuffer.Size;
_OnChangedVtxOffset(); _OnChangedVtxOffset();
} }
@ -672,25 +676,38 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
return; return;
const ImVec2 opaque_uv = _Data->TexUvWhitePixel; const ImVec2 opaque_uv = _Data->TexUvWhitePixel;
int count = points_count; const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
if (!closed)
count = points_count - 1;
const bool thick_line = (thickness > 1.0f); const bool thick_line = (thickness > 1.0f);
if (Flags & ImDrawListFlags_AntiAliasedLines) if (Flags & ImDrawListFlags_AntiAliasedLines)
{ {
// Anti-aliased stroke // Anti-aliased stroke
const float AA_SIZE = 1.0f; const float AA_SIZE = 1.0f;
const ImU32 col_trans = col & ~IM_COL32_A_MASK; const ImU32 col_trans = col & ~IM_COL32_A_MASK;
const int idx_count = thick_line ? count * 18 : count * 12; // Thicknesses <1.0 should behave like thickness 1.0
const int vtx_count = thick_line ? points_count * 4 : points_count * 3; thickness = ImMax(thickness, 1.0f);
const int integer_thickness = (int)thickness;
const float fractional_thickness = thickness - integer_thickness;
// Do we want to draw this line using a texture?
// - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved.
// - If AA_SIZE is not 1.0f we cannot use the texture path.
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f);
// We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off
IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines));
const int idx_count = use_texture ? (count * 6) : (thick_line ? count * 18 : count * 12);
const int vtx_count = use_texture ? (points_count * 2) : (thick_line ? points_count * 4 : points_count * 3);
PrimReserve(idx_count, vtx_count); PrimReserve(idx_count, vtx_count);
// Temporary buffer // Temporary buffer
ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); //-V630 // The first <points_count> items are normals at each line point, then after that there are either 2 or 4 temp points for each line point
ImVec2* temp_normals = (ImVec2*)alloca(points_count * ((use_texture || !thick_line) ? 3 : 5) * sizeof(ImVec2)); //-V630
ImVec2* temp_points = temp_normals + points_count; ImVec2* temp_points = temp_normals + points_count;
// Calculate normals (tangents) for each line segment
for (int i1 = 0; i1 < count; i1++) for (int i1 = 0; i1 < count; i1++)
{ {
const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1;
@ -703,59 +720,111 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
if (!closed) if (!closed)
temp_normals[points_count - 1] = temp_normals[points_count - 2]; temp_normals[points_count - 1] = temp_normals[points_count - 2];
if (!thick_line) // If we are drawing a one-pixel-wide line without a texture, or a textured line of any width, we only need 2 or 3 vertices per point
if (use_texture || !thick_line)
{ {
// [PATH 1] Texture-based lines (thick or non-thick)
// [PATH 2] Non texture-based lines (non-thick)
// The width of the geometry we need to draw - this is essentially <thickness> pixels for the line itself, plus "one pixel" for AA.
// - In the texture-based path, we don't use AA_SIZE here because the +1 is tied to the generated texture
// (see ImFontAtlasBuildRenderLinesTexData() function), and so alternate values won't work without changes to that code.
// - In the non texture-based paths, we would allow AA_SIZE to potentially be != 1.0f with a patch (e.g. fringe_scale patch to
// allow scaling geometry while preserving one-screen-pixel AA fringe).
const float half_draw_size = use_texture ? ((thickness * 0.5f) + 1) : AA_SIZE;
// If line is not closed, the first and last points need to be generated differently as there are no normals to blend
if (!closed) if (!closed)
{ {
temp_points[0] = points[0] + temp_normals[0] * AA_SIZE; temp_points[0] = points[0] + temp_normals[0] * half_draw_size;
temp_points[1] = points[0] - temp_normals[0] * AA_SIZE; temp_points[1] = points[0] - temp_normals[0] * half_draw_size;
temp_points[(points_count-1)*2+0] = points[points_count-1] + temp_normals[points_count-1] * AA_SIZE; temp_points[(points_count-1)*2+0] = points[points_count-1] + temp_normals[points_count-1] * half_draw_size;
temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * AA_SIZE; temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * half_draw_size;
} }
// Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges
// This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps)
// FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer.
unsigned int idx1 = _VtxCurrentIdx; unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment
for (int i1 = 0; i1 < count; i1++) for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment
{ {
const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; // i2 is the second point of the line segment
unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : idx1 + 3; const unsigned int idx2 = ((i1 + 1) == points_count) ? _VtxCurrentIdx : (idx1 + (use_texture ? 2 : 3)); // Vertex index for end of segment
// Average normals // Average normals
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f; float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
IM_FIXNORMAL2F(dm_x, dm_y); IM_FIXNORMAL2F(dm_x, dm_y);
dm_x *= AA_SIZE; dm_x *= half_draw_size; // dm_x, dm_y are offset to the outer edge of the AA area
dm_y *= AA_SIZE; dm_y *= half_draw_size;
// Add temporary vertices // Add temporary vertexes for the outer edges
ImVec2* out_vtx = &temp_points[i2 * 2]; ImVec2* out_vtx = &temp_points[i2 * 2];
out_vtx[0].x = points[i2].x + dm_x; out_vtx[0].x = points[i2].x + dm_x;
out_vtx[0].y = points[i2].y + dm_y; out_vtx[0].y = points[i2].y + dm_y;
out_vtx[1].x = points[i2].x - dm_x; out_vtx[1].x = points[i2].x - dm_x;
out_vtx[1].y = points[i2].y - dm_y; out_vtx[1].y = points[i2].y - dm_y;
// Add indexes if (use_texture)
_IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); {
_IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+0); // Add indices for two triangles
_IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 1); // Right tri
_IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10]= (ImDrawIdx)(idx2+0); _IdxWritePtr[11]= (ImDrawIdx)(idx2+1); _IdxWritePtr[3] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[4] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 0); // Left tri
_IdxWritePtr += 12; _IdxWritePtr += 6;
}
else
{
// Add indexes for four triangles
_IdxWritePtr[0] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2); // Right tri 1
_IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 0); // Right tri 2
_IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0); // Left tri 1
_IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1); // Left tri 2
_IdxWritePtr += 12;
}
idx1 = idx2; idx1 = idx2;
} }
// Add vertices // Add vertexes for each point on the line
for (int i = 0; i < points_count; i++) if (use_texture)
{ {
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; // If we're using textures we only need to emit the left/right edge vertices
_VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans; ImVec4 tex_uvs = _Data->TexUvLines[integer_thickness];
_VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans; if (fractional_thickness != 0.0f)
_VtxWritePtr += 3; {
const ImVec4 tex_uvs_1 = _Data->TexUvLines[integer_thickness + 1];
tex_uvs.x = tex_uvs.x + (tex_uvs_1.x - tex_uvs.x) * fractional_thickness; // inlined ImLerp()
tex_uvs.y = tex_uvs.y + (tex_uvs_1.y - tex_uvs.y) * fractional_thickness;
tex_uvs.z = tex_uvs.z + (tex_uvs_1.z - tex_uvs.z) * fractional_thickness;
tex_uvs.w = tex_uvs.w + (tex_uvs_1.w - tex_uvs.w) * fractional_thickness;
}
ImVec2 tex_uv0(tex_uvs.x, tex_uvs.y);
ImVec2 tex_uv1(tex_uvs.z, tex_uvs.w);
for (int i = 0; i < points_count; i++)
{
_VtxWritePtr[0].pos = temp_points[i * 2 + 0]; _VtxWritePtr[0].uv = tex_uv0; _VtxWritePtr[0].col = col; // Left-side outer edge
_VtxWritePtr[1].pos = temp_points[i * 2 + 1]; _VtxWritePtr[1].uv = tex_uv1; _VtxWritePtr[1].col = col; // Right-side outer edge
_VtxWritePtr += 2;
}
}
else
{
// If we're not using a texture, we need the center vertex as well
for (int i = 0; i < points_count; i++)
{
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; // Center of line
_VtxWritePtr[1].pos = temp_points[i * 2 + 0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans; // Left-side outer edge
_VtxWritePtr[2].pos = temp_points[i * 2 + 1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans; // Right-side outer edge
_VtxWritePtr += 3;
}
} }
} }
else else
{ {
// [PATH 2] Non texture-based lines (thick): we need to draw the solid line core and thus require four vertices per point
const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
// If line is not closed, the first and last points need to be generated differently as there are no normals to blend
if (!closed) if (!closed)
{ {
const int points_last = points_count - 1; const int points_last = points_count - 1;
@ -769,9 +838,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
temp_points[points_last * 4 + 3] = points[points_last] - temp_normals[points_last] * (half_inner_thickness + AA_SIZE); temp_points[points_last * 4 + 3] = points[points_last] - temp_normals[points_last] * (half_inner_thickness + AA_SIZE);
} }
// Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges
// This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps)
// FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer.
unsigned int idx1 = _VtxCurrentIdx; unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment
for (int i1 = 0; i1 < count; i1++) for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment
{ {
const int i2 = (i1 + 1) == points_count ? 0 : (i1 + 1); // i2 is the second point of the line segment const int i2 = (i1 + 1) == points_count ? 0 : (i1 + 1); // i2 is the second point of the line segment
const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : (idx1 + 4); // Vertex index for end of segment const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : (idx1 + 4); // Vertex index for end of segment
@ -822,7 +893,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
} }
else else
{ {
// Non Anti-aliased Stroke // [PATH 4] Non texture-based, Non anti-aliased lines
const int idx_count = count * 6; const int idx_count = count * 6;
const int vtx_count = count * 4; // FIXME-OPT: Not sharing edges const int vtx_count = count * 4; // FIXME-OPT: Not sharing edges
PrimReserve(idx_count, vtx_count); PrimReserve(idx_count, vtx_count);
@ -1176,7 +1247,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
// Because we are filling a closed shape we remove 1 from the count of segments/points // Because we are filling a closed shape we remove 1 from the count of segments/points
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
if (num_segments == 12) if (num_segments == 12)
PathArcToFast(center, radius - 0.5f, 0, 12); PathArcToFast(center, radius - 0.5f, 0, 12 - 1);
else else
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1); PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
PathStroke(col, true, thickness); PathStroke(col, true, thickness);
@ -1206,7 +1277,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col,
// Because we are filling a closed shape we remove 1 from the count of segments/points // Because we are filling a closed shape we remove 1 from the count of segments/points
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
if (num_segments == 12) if (num_segments == 12)
PathArcToFast(center, radius, 0, 12); PathArcToFast(center, radius, 0, 12 - 1);
else else
PathArcTo(center, radius, 0.0f, a_max, num_segments - 1); PathArcTo(center, radius, 0.0f, a_max, num_segments - 1);
PathFillConvex(col); PathFillConvex(col);
@ -1662,8 +1733,7 @@ ImFontAtlas::ImFontAtlas()
TexWidth = TexHeight = 0; TexWidth = TexHeight = 0;
TexUvScale = ImVec2(0.0f, 0.0f); TexUvScale = ImVec2(0.0f, 0.0f);
TexUvWhitePixel = ImVec2(0.0f, 0.0f); TexUvWhitePixel = ImVec2(0.0f, 0.0f);
for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) PackIdMouseCursors = PackIdLines = -1;
CustomRectIds[n] = -1;
} }
ImFontAtlas::~ImFontAtlas() ImFontAtlas::~ImFontAtlas()
@ -1691,8 +1761,7 @@ void ImFontAtlas::ClearInputData()
} }
ConfigData.clear(); ConfigData.clear();
CustomRects.clear(); CustomRects.clear();
for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) PackIdMouseCursors = PackIdLines = -1;
CustomRectIds[n] = -1;
} }
void ImFontAtlas::ClearTexData() void ImFontAtlas::ClearTexData()
@ -1932,9 +2001,9 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou
if (Flags & ImFontAtlasFlags_NoMouseCursors) if (Flags & ImFontAtlasFlags_NoMouseCursors)
return false; return false;
IM_ASSERT(CustomRectIds[0] != -1); IM_ASSERT(PackIdMouseCursors != -1);
ImFontAtlasCustomRect& r = CustomRects[CustomRectIds[0]]; ImFontAtlasCustomRect* r = GetCustomRectByIndex(PackIdMouseCursors);
ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r->X, (float)r->Y);
ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1];
*out_size = size; *out_size = size;
*out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2];
@ -2262,17 +2331,6 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
return true; return true;
} }
// Register default custom rectangles (this is called/shared by both the stb_truetype and the FreeType builder)
void ImFontAtlasBuildInit(ImFontAtlas* atlas)
{
if (atlas->CustomRectIds[0] >= 0)
return;
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H);
else
atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(2, 2);
}
void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
{ {
if (!font_config->MergeMode) if (!font_config->MergeMode)
@ -2316,20 +2374,18 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
{ {
IM_ASSERT(atlas->CustomRectIds[0] >= 0); ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors);
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); IM_ASSERT(r->IsPacked());
ImFontAtlasCustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]];
IM_ASSERT(r.IsPacked());
const int w = atlas->TexWidth; const int w = atlas->TexWidth;
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
{ {
// Render/copy pixels // Render/copy pixels
IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++)
for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++)
{ {
const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * w; const int offset0 = (int)(r->X + x) + (int)(r->Y + y) * w;
const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1;
atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00;
atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00;
@ -2337,29 +2393,85 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
} }
else else
{ {
IM_ASSERT(r.Width == 2 && r.Height == 2); // Render 4 white pixels
const int offset = (int)(r.X) + (int)(r.Y) * w; IM_ASSERT(r->Width == 2 && r->Height == 2);
const int offset = (int)r->X + (int)r->Y * w;
atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF; atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
} }
atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * atlas->TexUvScale.x, (r.Y + 0.5f) * atlas->TexUvScale.y); atlas->TexUvWhitePixel = ImVec2((r->X + 0.5f) * atlas->TexUvScale.x, (r->Y + 0.5f) * atlas->TexUvScale.y);
} }
static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
{
if (atlas->Flags & ImFontAtlasFlags_NoBakedLines)
return;
// This generates a triangular shape in the texture, with the various line widths stacked on top of each other to allow interpolation between them
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdLines);
IM_ASSERT(r->IsPacked());
for (unsigned int n = 0; n < IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1; n++) // +1 because of the zero-width row
{
// Each line consists of at least two empty pixels at the ends, with a line of solid pixels in the middle
unsigned int y = n;
unsigned int line_width = n;
unsigned int pad_left = (r->Width - line_width) / 2;
unsigned int pad_right = r->Width - (pad_left + line_width);
// Write each slice
IM_ASSERT(pad_left + line_width + pad_right == r->Width && y < r->Height); // Make sure we're inside the texture bounds before we start writing pixels
unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)];
memset(write_ptr, 0x00, pad_left);
memset(write_ptr + pad_left, 0xFF, line_width);
memset(write_ptr + pad_left + line_width, 0x00, pad_right);
// Calculate UVs for this line
ImVec2 uv0 = ImVec2((float)(r->X + pad_left - 1), (float)(r->Y + y)) * atlas->TexUvScale;
ImVec2 uv1 = ImVec2((float)(r->X + pad_left + line_width + 1), (float)(r->Y + y + 1)) * atlas->TexUvScale;
float half_v = (uv0.y + uv1.y) * 0.5f; // Calculate a constant V in the middle of the row to avoid sampling artifacts
atlas->TexUvLines[n] = ImVec4(uv0.x, half_v, uv1.x, half_v);
}
}
// Note: this is called / shared by both the stb_truetype and the FreeType builder
void ImFontAtlasBuildInit(ImFontAtlas* atlas)
{
// Register texture region for mouse cursors or standard white pixels
if (atlas->PackIdMouseCursors < 0)
{
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H);
else
atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(2, 2);
}
// Register texture region for thick lines
// The +2 here is to give space for the end caps, whilst height +1 is to accommodate the fact we have a zero-width row
if (atlas->PackIdLines < 0)
{
if (!(atlas->Flags & ImFontAtlasFlags_NoBakedLines))
atlas->PackIdLines = atlas->AddCustomRectRegular(IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 2, IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1);
}
}
// This is called/shared by both the stb_truetype and the FreeType builder.
void ImFontAtlasBuildFinish(ImFontAtlas* atlas) void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
{ {
// Render into our custom data block // Render into our custom data blocks
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL);
ImFontAtlasBuildRenderDefaultTexData(atlas); ImFontAtlasBuildRenderDefaultTexData(atlas);
ImFontAtlasBuildRenderLinesTexData(atlas);
// Register custom rectangle glyphs // Register custom rectangle glyphs
for (int i = 0; i < atlas->CustomRects.Size; i++) for (int i = 0; i < atlas->CustomRects.Size; i++)
{ {
const ImFontAtlasCustomRect& r = atlas->CustomRects[i]; const ImFontAtlasCustomRect* r = &atlas->CustomRects[i];
if (r.Font == NULL || r.GlyphID == 0) if (r->Font == NULL || r->GlyphID == 0)
continue; continue;
IM_ASSERT(r.Font->ContainerAtlas == atlas); IM_ASSERT(r->Font->ContainerAtlas == atlas);
ImVec2 uv0, uv1; ImVec2 uv0, uv1;
atlas->CalcCustomRectUV(&r, &uv0, &uv1); atlas->CalcCustomRectUV(r, &uv0, &uv1);
r.Font->AddGlyph((ImWchar)r.GlyphID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); r->Font->AddGlyph((ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX);
} }
// Build all fonts lookup tables // Build all fonts lookup tables

View File

@ -1,4 +1,4 @@
// dear imgui, v1.77 // dear imgui, v1.78 WIP
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -560,6 +560,7 @@ struct IMGUI_API ImDrawListSharedData
// [Internal] Lookup tables // [Internal] Lookup tables
ImVec2 ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER]; // FIXME: Bake rounded corners fill/borders in atlas ImVec2 ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER]; // FIXME: Bake rounded corners fill/borders in atlas
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius (array index + 1) before we calculate it dynamically (to avoid calculation overhead) ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius (array index + 1) before we calculate it dynamically (to avoid calculation overhead)
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas
ImDrawListSharedData(); ImDrawListSharedData();
void SetCircleSegmentMaxError(float max_error); void SetCircleSegmentMaxError(float max_error);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.77 // dear imgui, v1.78 WIP
// (widgets code) // (widgets code)
/* /*