Update BGFX and BX (nw)

This commit is contained in:
Miodrag Milanovic 2016-05-27 20:57:02 +02:00
parent 5469ca3760
commit 913861105b
19 changed files with 435 additions and 191 deletions

View File

@ -457,7 +457,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.
@ -611,6 +610,7 @@
#include <math.h> // sqrtf, fabsf, fmodf, powf, cosf, sinf, floorf, ceilf
#include <stdlib.h> // NULL, malloc, free, qsort, atoi
#include <stdio.h> // vsnprintf, sscanf, printf
#include <limits.h> // INT_MIN, INT_MAX
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
@ -867,9 +867,6 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
#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"
@ -1611,6 +1608,86 @@ float ImGuiSimpleColumns::CalcExtraSpace(float avail_w)
return ImMax(0.0f, avail_w - Width);
}
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
@ -1659,8 +1736,8 @@ ImGuiWindow::ImGuiWindow(const char* name)
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()
@ -1824,7 +1901,7 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_
// 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);
@ -2882,18 +2959,8 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
}
// 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)
{
ImGuiContext& g = *GImGui;
@ -2905,6 +2972,11 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
*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);
@ -3347,7 +3419,7 @@ static inline void ClearSetNextWindowData()
{
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)
@ -3548,12 +3620,12 @@ 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)
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));
}
@ -3662,6 +3734,31 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
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.
@ -3727,7 +3824,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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)
@ -3788,12 +3885,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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)))
@ -3884,7 +3981,6 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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
{
@ -3902,17 +3998,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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
@ -3924,7 +4015,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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;
@ -3979,10 +4070,10 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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)
@ -4032,14 +4123,15 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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();
}
@ -4203,6 +4295,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
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).
@ -4369,7 +4462,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
// 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)
@ -4842,6 +4935,15 @@ void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond)
g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCond_Always;
}
void ImGui::SetNextWindowSizeConstraint(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)
{
ImGuiContext& g = *GImGui;
@ -5077,7 +5179,7 @@ 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)
@ -5355,6 +5457,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
{
SetActiveID(id, window); // Hold on ID
FocusWindow(window);
g.ActiveIdClickOffset = g.IO.MousePos - bb.Min;
}
if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0]))
{
@ -6866,10 +6969,10 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_
ImGui::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);
bool value_changed = ImGui::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);
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);
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) ? INT_MAX : v_max, display_format_max ? display_format_max : display_format);
ImGui::PopItemWidth();
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
@ -7964,9 +8067,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// 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)
@ -8497,22 +8600,22 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
// 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))
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*";
ImGui::PushID(i);
if (ImGui::Selectable(item_text, item_selected))
{
*current_item = i;
value_changed = true;
}
ImGui::PopID();
}
ImGui::PopID();
}
clipper.End();
ImGui::ListBoxFooter();
return value_changed;
}
@ -9052,6 +9155,17 @@ void ImGui::SameLine(float pos_x, float spacing_w)
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();
@ -9109,7 +9223,7 @@ static float GetDraggedColumnOffset(int column_index)
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;
@ -9214,7 +9328,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
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);
}
@ -9525,22 +9639,22 @@ void ImGui::ShowMetricsWindow(bool* p_open)
}
if (!pcmd_node_open)
continue;
ImGuiListClipper clipper(pcmd->ElemCount/3, ImGui::GetTextLineHeight()*3 + ImGui::GetStyle().ItemSpacing.y); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible.
for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++)
{
char buf[300], *buf_p = buf;
ImVec2 triangles_pos[3];
for (int n = 0; n < 3; n++, vtx_i++)
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[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);
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, IM_COL32(255,255,0,255), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle
}
clipper.End();
ImGui::TreePop();
}
overlay_draw_list->PopClipRect();

View File

@ -52,7 +52,8 @@ struct ImGuiStorage; // Simple custom key value storage
struct ImGuiStyle; // Runtime data for styling/colors
struct ImGuiTextFilter; // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
struct ImGuiTextBuffer; // Text buffer for logging/accumulating text
struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom callbacks (advanced)
struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom ImGuiTextEditCallback (rare/advanced use)
struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window size in custom ways when using custom ImGuiSizeConstraintCallback (rare/advanced use)
struct ImGuiListClipper; // Helper to manually clip large list of items
struct ImGuiContext; // ImGui context (opaque)
@ -73,6 +74,7 @@ typedef int ImGuiInputTextFlags; // flags for InputText*() // e
typedef int ImGuiSelectableFlags; // flags for Selectable() // enum ImGuiSelectableFlags_
typedef int ImGuiTreeNodeFlags; // flags for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_
typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data);
// Others helpers at bottom of the file:
// class ImVector<> // Lightweight std::vector like class.
@ -138,6 +140,7 @@ namespace ImGui
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position. call before Begin()
IMGUI_API void SetNextWindowPosCenter(ImGuiSetCond cond = 0); // set next window position to be centered on screen. call before Begin()
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin()
IMGUI_API void SetNextWindowSizeConstraint(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints.
IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin()
IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin()
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state. call before Begin()
@ -191,6 +194,7 @@ namespace ImGui
// Cursor / Layout
IMGUI_API void Separator(); // horizontal line
IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally
IMGUI_API void NewLine(); // undo a SameLine()
IMGUI_API void Spacing(); // add spacing
IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size
IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels
@ -249,7 +253,7 @@ namespace ImGui
IMGUI_API void BulletText(const char* fmt, ...) IM_PRINTFARGS(1);
IMGUI_API void BulletTextV(const char* fmt, va_list args);
IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0));
IMGUI_API bool SmallButton(const char* label);
IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0)
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size);
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
@ -1030,7 +1034,18 @@ struct ImGuiTextEditCallbackData
bool HasSelection() const { return SelectionStart != SelectionEnd; }
};
// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraint(). Callback is called during the next Begin().
// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraint() parameters are enough.
struct ImGuiSizeConstraintCallbackData
{
void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraint()
ImVec2 Pos; // Read-only. Window position, for reference.
ImVec2 CurrentSize; // Read-only. Current window size.
ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing.
};
// ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
// Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API.
// Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class.
// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats.
struct ImColor
@ -1051,36 +1066,33 @@ struct ImColor
};
// Helper: Manually clip large list of items.
// If you are displaying thousands of even spaced items and you have a random access to the list, you can perform clipping yourself to save on CPU.
// If you are submitting lots of evenly spaced items and you have a random access to the list, you can perform coarse clipping based on visibility to save yourself from processing those items at all.
// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped.
// ImGui already clip items based on their bounds but it needs to measure text size to do so. Coarse clipping before submission makes this cost and your own data fetching/submission cost null.
// Usage:
// ImGuiListClipper clipper(count, ImGui::GetTextLineHeightWithSpacing());
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) // display only visible items
// ImGui::Text("line number %d", i);
// clipper.End();
// NB: 'count' is only used to clamp the result, if you don't know your count you can use INT_MAX
// ImGuiListClipper clipper(1000); // we have 1000 elements, evenly spaced.
// while (clipper.Step())
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
// ImGui::Text("line number %d", i);
// - Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height (step skipped if we passed a known height as second arg to constructor).
// - 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.
// - (Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 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.
struct ImGuiListClipper
{
float StartPosY;
float ItemsHeight;
int ItemsCount, DisplayStart, DisplayEnd;
int ItemsCount, StepNo, DisplayStart, DisplayEnd;
ImGuiListClipper() { ItemsHeight = 0.0f; ItemsCount = DisplayStart = DisplayEnd = -1; }
ImGuiListClipper(int count, float height) { ItemsCount = -1; Begin(count, height); }
~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // user forgot to call End()
// items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step).
// items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetItemsLineHeightWithSpacing().
// If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step().
ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want).
~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false.
void Begin(int count, float height) // items_height: generally pass GetTextLineHeightWithSpacing() or GetItemsLineHeightWithSpacing()
{
IM_ASSERT(ItemsCount == -1);
ItemsCount = count;
ItemsHeight = height;
ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + DisplayStart * ItemsHeight); // advance cursor
}
void End()
{
IM_ASSERT(ItemsCount >= 0);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ItemsCount - DisplayEnd) * ItemsHeight); // advance cursor
ItemsCount = -1;
}
IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items.
IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1.
IMGUI_API void End(); // Automatically called on the last call of Step() that returns false.
};
//-----------------------------------------------------------------------------
@ -1096,12 +1108,8 @@ struct ImGuiListClipper
// Draw callbacks for advanced uses.
// 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, if you want to render a complex 3D scene inside a UI element, change your GPU render state, etc.
// The expected behavior from your rendering loop is:
// if (cmd.UserCallback != NULL)
// cmd.UserCallback(parent_list, cmd);
// else
// RenderTriangles()
// Draw callback may be useful for example, A) Change your GPU render state, B) render a complex 3D scene inside a UI element (without an intermediate texture/render target), etc.
// The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) cmd.UserCallback(parent_list, cmd); else RenderTriangles()'
typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd);
// Typically, 1 command = 1 gpu draw call (unless command is a callback)
@ -1117,7 +1125,7 @@ struct ImDrawCmd
ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; ViewId = 0; }
};
// Vertex index (override with, e.g. '#define ImDrawIdx unsigned int' in ImConfig)
// Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h)
#ifndef ImDrawIdx
typedef unsigned short ImDrawIdx;
#endif

View File

@ -46,6 +46,7 @@
#endif
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
#define IM_MAX(_A,_B) (((_A) >= (_B)) ? (_A) : (_B))
//-----------------------------------------------------------------------------
// DEMO CODE
@ -59,6 +60,7 @@ static void ShowExampleAppLayout(bool* p_open);
static void ShowExampleAppPropertyEditor(bool* p_open);
static void ShowExampleAppLongText(bool* p_open);
static void ShowExampleAppAutoResize(bool* p_open);
static void ShowExampleAppConstrainedResize(bool* p_open);
static void ShowExampleAppFixedOverlay(bool* p_open);
static void ShowExampleAppManipulatingWindowTitle(bool* p_open);
static void ShowExampleAppCustomRendering(bool* p_open);
@ -105,6 +107,7 @@ void ImGui::ShowTestWindow(bool* p_open)
static bool show_app_property_editor = false;
static bool show_app_long_text = false;
static bool show_app_auto_resize = false;
static bool show_app_constrained_resize = false;
static bool show_app_fixed_overlay = false;
static bool show_app_manipulating_window_title = false;
static bool show_app_custom_rendering = false;
@ -120,6 +123,7 @@ void ImGui::ShowTestWindow(bool* p_open)
if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor);
if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text);
if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize);
if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize);
if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay);
if (show_app_manipulating_window_title) ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title);
if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering);
@ -183,6 +187,7 @@ void ImGui::ShowTestWindow(bool* p_open)
ImGui::MenuItem("Property editor", NULL, &show_app_property_editor);
ImGui::MenuItem("Long text display", NULL, &show_app_long_text);
ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize);
ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize);
ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay);
ImGui::MenuItem("Manipulating window title", NULL, &show_app_manipulating_window_title);
ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering);
@ -384,14 +389,14 @@ void ImGui::ShowTestWindow(bool* p_open)
static int pressed_count = 0;
for (int i = 0; i < 8; i++)
{
if (i > 0)
ImGui::SameLine();
ImGui::PushID(i);
int frame_padding = -1 + i; // -1 = uses default padding
if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding, ImColor(0,0,0,255)))
pressed_count += 1;
ImGui::PopID();
ImGui::SameLine();
}
ImGui::NewLine();
ImGui::Text("Pressed %d times.", pressed_count);
ImGui::TreePop();
}
@ -704,7 +709,7 @@ void ImGui::ShowTestWindow(bool* p_open)
if (i > 0) ImGui::SameLine();
ImGui::PushID(i);
ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40);
ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f");
ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f\nsec");
ImGui::PopStyleVar();
ImGui::PopID();
}
@ -1793,6 +1798,43 @@ static void ShowExampleAppAutoResize(bool* p_open)
ImGui::End();
}
static void ShowExampleAppConstrainedResize(bool* p_open)
{
struct CustomConstraints // Helper functions to demonstrate programmatic constraints
{
static void Square(ImGuiSizeConstraintCallbackData* data) { data->DesiredSize = ImVec2(IM_MAX(data->DesiredSize.x, data->DesiredSize.y), IM_MAX(data->DesiredSize.x, data->DesiredSize.y)); }
static void Step(ImGuiSizeConstraintCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); }
};
static int type = 0;
if (type == 0) ImGui::SetNextWindowSizeConstraint(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only
if (type == 1) ImGui::SetNextWindowSizeConstraint(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only
if (type == 2) ImGui::SetNextWindowSizeConstraint(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100
if (type == 3) ImGui::SetNextWindowSizeConstraint(ImVec2(300, 0), ImVec2(400, FLT_MAX)); // Width 300-400
if (type == 4) ImGui::SetNextWindowSizeConstraint(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square
if (type == 5) ImGui::SetNextWindowSizeConstraint(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step
if (ImGui::Begin("Example: Constrained Resize", p_open))
{
const char* desc[] =
{
"Resize vertical only",
"Resize horizontal only",
"Width > 100, Height > 100",
"Width 300-400",
"Custom: Always Square",
"Custom: Fixed Steps (100)",
};
ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc));
if (ImGui::Button("200x200")) ImGui::SetWindowSize(ImVec2(200,200)); ImGui::SameLine();
if (ImGui::Button("500x500")) ImGui::SetWindowSize(ImVec2(500,500)); ImGui::SameLine();
if (ImGui::Button("800x200")) ImGui::SetWindowSize(ImVec2(800,200));
for (int i = 0; i < 10; i++)
ImGui::Text("Hello, sailor! Making this line long enough for the example.");
}
ImGui::End();
}
static void ShowExampleAppFixedOverlay(bool* p_open)
{
ImGui::SetNextWindowPos(ImVec2(10,10));
@ -1807,10 +1849,8 @@ static void ShowExampleAppFixedOverlay(bool* p_open)
ImGui::End();
}
static void ShowExampleAppManipulatingWindowTitle(bool* p_open)
static void ShowExampleAppManipulatingWindowTitle(bool*)
{
(void)p_open;
// By default, Windows are uniquely identified by their title.
// You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file!
@ -2002,7 +2042,8 @@ struct ExampleAppConsole
if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine();
if (ImGui::SmallButton("Clear")) ClearLog();
if (ImGui::SmallButton("Clear")) ClearLog(); ImGui::SameLine();
if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true;
//static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
ImGui::Separator();
@ -2013,24 +2054,33 @@ struct ExampleAppConsole
ImGui::PopStyleVar();
ImGui::Separator();
// Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
// NB- if you have thousands of entries this approach may be too inefficient. You can seek and display only the lines that are visible - CalcListClipping() is a helper to compute this information.
// If your items are of variable size you may want to implement code similar to what CalcListClipping() does. Or split your data into fixed height items to allow random-seeking into your list.
ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar);
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::Selectable("Clear")) ClearLog();
ImGui::EndPopup();
}
// Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
// NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping to only process visible items.
// You can seek and display only the lines that are visible using the ImGuiListClipper helper, if your elements are evenly spaced and you have cheap random access to the elements.
// To use the clipper we could replace the 'for (int i = 0; i < Items.Size; i++)' loop with:
// ImGuiListClipper clipper(Items.Size);
// while (clipper.Step())
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
// However take note that you can not use this code as is if a filter is active because it breaks the 'cheap random-access' property. We would need random-access on the post-filtered list.
// A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices that passed the filtering test, recomputing this array when user changes the filter,
// and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code!
// If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list.
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing
for (int i = 0; i < Items.Size; i++)
{
const char* item = Items[i];
if (!filter.PassFilter(item))
continue;
ImVec4 col = ImColor(255,255,255); // A better implementation may store a type per-item. For the sample let's just parse the text.
if (strstr(item, "[error]")) col = ImColor(255,100,100);
else if (strncmp(item, "# ", 2) == 0) col = ImColor(255,200,150);
ImVec4 col = ImVec4(1.0f,1.0f,1.0f,1.0f); // A better implementation may store a type per-item. For the sample let's just parse the text.
if (strstr(item, "[error]")) col = ImColor(1.0f,0.4f,0.4f,1.0f);
else if (strncmp(item, "# ", 2) == 0) col = ImColor(1.0f,0.78f,0.58f,1.0f);
ImGui::PushStyleColor(ImGuiCol_Text, col);
ImGui::TextUnformatted(item);
ImGui::PopStyleColor();
@ -2440,10 +2490,10 @@ static void ShowExampleAppLongText(bool* p_open)
{
// Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper.
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
ImGuiListClipper clipper(lines, ImGui::GetTextLineHeightWithSpacing()); // Here we changed spacing is zero anyway so we could use GetTextLineHeight(), but _WithSpacing() is typically more correct
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i);
clipper.End();
ImGuiListClipper clipper(lines);
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
ImGui::PopStyleVar();
break;
}
@ -2451,7 +2501,7 @@ static void ShowExampleAppLongText(bool* p_open)
// Multiple calls to Text(), not clipped (slow)
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
for (int i = 0; i < lines; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i);
ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
ImGui::PopStyleVar();
break;
}

View File

@ -1143,7 +1143,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
ConfigData.push_back(*font_cfg);
ImFontConfig& new_font_cfg = ConfigData.back();
new_font_cfg.DstFont = Fonts.back();
if (!new_font_cfg.DstFont)
new_font_cfg.DstFont = Fonts.back();
if (!new_font_cfg.FontDataOwnedByAtlas)
{
new_font_cfg.FontData = ImGui::MemAlloc(new_font_cfg.FontDataSize);
@ -1153,7 +1154,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
// Invalidate texture
ClearTexData();
return Fonts.back();
return new_font_cfg.DstFont;
}
// Default font TTF is compressed with stb_compress then base85 encoded (see extra_fonts/binary_to_compressed_c.cpp for encoder)

View File

@ -373,6 +373,7 @@ struct ImGuiContext
bool ActiveIdIsAlive;
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdAllowOverlap; // Set only by active widget
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
ImGuiWindow* ActiveIdWindow;
ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window.
ImGuiID MovedWindowMoveId; // == MovedWindow->RootWindow->MoveId
@ -393,6 +394,10 @@ struct ImGuiContext
ImGuiSetCond SetNextWindowSizeCond;
ImGuiSetCond SetNextWindowContentSizeCond;
ImGuiSetCond SetNextWindowCollapsedCond;
ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true
ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback;
void* SetNextWindowSizeConstraintCallbackUserData;
bool SetNextWindowSizeConstraint;
bool SetNextWindowFocus;
bool SetNextTreeNodeOpenVal;
ImGuiSetCond SetNextTreeNodeOpenCond;
@ -410,7 +415,6 @@ struct ImGuiContext
ImFont InputTextPasswordFont;
ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode
ImVec2 ActiveClickDeltaToCenter;
float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings
ImVec2 DragLastMouseDelta;
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
@ -458,6 +462,7 @@ struct ImGuiContext
ActiveIdIsAlive = false;
ActiveIdIsJustActivated = false;
ActiveIdAllowOverlap = false;
ActiveIdClickOffset = ImVec2(-1,-1);
ActiveIdWindow = NULL;
MovedWindow = NULL;
MovedWindowMoveId = 0;
@ -471,11 +476,12 @@ struct ImGuiContext
SetNextWindowContentSizeCond = 0;
SetNextWindowCollapsedCond = 0;
SetNextWindowFocus = false;
SetNextWindowSizeConstraintCallback = NULL;
SetNextWindowSizeConstraintCallbackUserData = NULL;
SetNextTreeNodeOpenVal = false;
SetNextTreeNodeOpenCond = 0;
ScalarAsInputTextId = 0;
ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f);
DragCurrentValue = 0.0f;
DragLastMouseDelta = ImVec2(0.0f, 0.0f);
DragSpeedDefaultRatio = 0.01f;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -279,32 +279,26 @@ void calcMinBoundingSphere(Sphere& _sphere, const void* _vertices, uint32_t _num
void calcPlaneUv(const Plane& _plane, float* _udir, float* _vdir)
{
const uint8_t axis =
bx::fabsolute(_plane.m_normal[0]) > 0.6f ? 0
: (bx::fabsolute(_plane.m_normal[1]) > 0.6f ? 1
: 2
);
const uint8_t* index = (uint8_t*)&"\x1\x2\x0\x2\x0\x1"[axis*2];
const uint8_t idx0 = *(index );
const uint8_t idx1 = *(index+1);
const float nx = _plane.m_normal[0];
const float ny = _plane.m_normal[1];
const float nz = _plane.m_normal[2];
_udir[0] = 0.0f;
_udir[1] = 0.0f;
_udir[2] = 0.0f;
_udir[idx0] = 1.0f;
if (bx::fabsolute(nx) > bx::fabsolute(nz) )
{
float invLen = 1.0f / bx::fsqrt(nx*nx + nz*nz);
_udir[0] = -nz * invLen;
_udir[1] = 0.0f;
_udir[2] = nx * invLen;
}
else
{
float invLen = 1.0f / bx::fsqrt(ny*ny + nz*nz);
_udir[0] = 0.0f;
_udir[1] = nz * invLen;
_udir[2] = -ny * invLen;
}
_vdir[0] = 0.0f;
_vdir[1] = 0.0f;
_vdir[2] = 0.0f;
_vdir[idx1] = 1.0f;
const float invPlaneAxis = 1.0f / _plane.m_normal[axis];
_udir[axis] -= bx::vec3Dot(_udir, _plane.m_normal) * invPlaneAxis;
bx::vec3Norm(_udir, _udir);
_vdir[axis] -= bx::vec3Dot(_vdir, _plane.m_normal) * invPlaneAxis;
bx::vec3Norm(_vdir, _vdir);
bx::vec3Cross(_vdir, _plane.m_normal, _udir);
}
void buildFrustumPlanes(Plane* _result, const float* _viewProj)

View File

@ -110,7 +110,7 @@ namespace entry
const char* argv[1] = { "android.so" };
m_mte.m_argc = 1;
m_mte.m_argv = const_cast<char**>(argv);
while (0 == m_app->destroyRequested)
{
int32_t num;
@ -140,7 +140,7 @@ namespace entry
// Command from main thread: a new ANativeWindow is ready for use. Upon
// receiving this command, android_app->window will contain the new window
// surface.
if (m_window == NULL)
if (m_window != m_app->window)
{
m_window = m_app->window;
bgfx::androidSetWindow(m_window);
@ -152,7 +152,10 @@ namespace entry
WindowHandle defaultWindow = { 0 };
m_eventQueue.postSizeEvent(defaultWindow, width, height);
m_thread.init(MainThreadEntry::threadFunc, &m_mte);
if (!m_thread.isRunning() )
{
m_thread.init(MainThreadEntry::threadFunc, &m_mte);
}
}
break;

View File

@ -285,6 +285,7 @@ namespace bgfx
static bool s_renderFrameCalled = false;
InternalData g_internalData;
PlatformData g_platformData;
bool g_platformDataChangedSinceReset = false;
void AllocatorStub::checkLeaks()
{
@ -305,13 +306,13 @@ namespace bgfx
{
BGFX_FATAL(true
&& g_platformData.ndt == _data.ndt
&& g_platformData.nwh == _data.nwh
&& g_platformData.context == _data.context
, Fatal::UnableToInitialize
, "Only backbuffer pointer can be changed after initialization!"
, "Only backbuffer pointer and native window handle can be changed after initialization!"
);
}
memcpy(&g_platformData, &_data, sizeof(PlatformData) );
g_platformDataChangedSinceReset = true;
}
const InternalData* getInternalData()

View File

@ -264,6 +264,7 @@ namespace bgfx
{
extern InternalData g_internalData;
extern PlatformData g_platformData;
extern bool g_platformDataChangedSinceReset;
#if BGFX_CONFIG_MAX_DRAW_CALLS < (64<<10)
typedef uint16_t RenderItemCount;
@ -2134,7 +2135,11 @@ namespace bgfx
BX_WARN(0 != _width && 0 != _height, "Frame buffer resolution width or height cannot be 0 (width %d, height %d).", _width, _height);
m_resolution.m_width = bx::uint32_max(1, _width);
m_resolution.m_height = bx::uint32_max(1, _height);
m_resolution.m_flags = _flags;
m_resolution.m_flags = 0
| _flags
| (g_platformDataChangedSinceReset ? BGFX_RESET_INTERNAL_FORCE : 0)
;
g_platformDataChangedSinceReset = false;
m_flipAfterRender = !!(_flags & BGFX_RESET_FLIP_AFTER_RENDER);

View File

@ -343,6 +343,14 @@ EGL_IMPORT
# if BX_PLATFORM_ANDROID
if (NULL != m_display)
{
EGLNativeWindowType nwh = (EGLNativeWindowType )g_platformData.nwh;
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(m_display, m_surface);
m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL);
BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");
EGLBoolean success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
BGFX_FATAL(success, Fatal::UnableToInitialize, "Failed to set context.");
EGLint format;
eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry( (ANativeWindow*)g_platformData.nwh, _width, _height, format);

View File

@ -2112,7 +2112,7 @@ namespace bgfx
{ 8, 0, 8, 0 },
{ 4, 4, 4, 4 },
{ 4, 4, 0, 0 },
{ 4, 4, 4, 4 },
{ 0, 8, 0, 8 },
};
@ -2247,7 +2247,7 @@ namespace bgfx
*_r += bitRangeConvert( (_block >> 10) & 0x1f, 5, 8) * _factor;
*_g += bitRangeConvert( (_block >> 5) & 0x1f, 5, 8) * _factor;
*_b += bitRangeConvert( (_block >> 1) & 0x0f, 4, 8) * _factor;
*_a += 255;
*_a += 255 * _factor;
}
else
{
@ -2265,7 +2265,7 @@ namespace bgfx
*_r += bitRangeConvert( (_block >> 26) & 0x1f, 5, 8) * _factor;
*_g += bitRangeConvert( (_block >> 21) & 0x1f, 5, 8) * _factor;
*_b += bitRangeConvert( (_block >> 16) & 0x1f, 5, 8) * _factor;
*_a += 255;
*_a += 255 * _factor;
}
else
{
@ -3191,7 +3191,7 @@ namespace bgfx
_imageContainer.m_height = height;
_imageContainer.m_depth = depth;
_imageContainer.m_format = format;
_imageContainer.m_numMips = uint8_t(numMips);
_imageContainer.m_numMips = uint8_t(bx::uint32_max(numMips, 1) );
_imageContainer.m_hasAlpha = hasAlpha;
_imageContainer.m_cubeMap = numFaces > 1;
_imageContainer.m_ktx = false;
@ -3248,6 +3248,7 @@ namespace bgfx
return true;
}
BX_TRACE("Unrecognized image format (magic: 0x%08x)!", magic);
return false;
}

View File

@ -6198,7 +6198,15 @@ namespace bgfx { namespace gl
}
else
{
GL_CHECK(glDisable(GL_DEPTH_TEST) );
if (BGFX_STATE_DEPTH_WRITE & newFlags)
{
GL_CHECK(glEnable(GL_DEPTH_TEST) );
GL_CHECK(glDepthFunc(GL_ALWAYS) );
}
else
{
GL_CHECK(glDisable(GL_DEPTH_TEST) );
}
}
}

View File

@ -80,6 +80,11 @@ static const InputBinding s_bindingView[] =
{ entry::Key::PageUp, entry::Modifier::None, 1, NULL, "view file-pgup" },
{ entry::Key::PageDown, entry::Modifier::None, 1, NULL, "view file-pgdown" },
{ entry::Key::KeyR, entry::Modifier::None, 1, NULL, "view rgb r" },
{ entry::Key::KeyG, entry::Modifier::None, 1, NULL, "view rgb g" },
{ entry::Key::KeyB, entry::Modifier::None, 1, NULL, "view rgb b" },
{ entry::Key::KeyA, entry::Modifier::None, 1, NULL, "view rgb a" },
{ entry::Key::KeyH, entry::Modifier::None, 1, NULL, "view help" },
INPUT_BINDING_END
@ -105,8 +110,10 @@ struct View
: m_fileIndex(0)
, m_scaleFn(0)
, m_mip(0)
, m_abgr(UINT32_MAX)
, m_zoom(1.0f)
, m_filter(true)
, m_alpha(false)
, m_help(false)
{
}
@ -191,6 +198,33 @@ struct View
++m_fileIndex;
m_fileIndex = bx::uint32_min(m_fileIndex, numFiles);
}
else if (0 == strcmp(_argv[1], "rgb") )
{
if (_argc >= 3)
{
if (_argv[2][0] == 'r')
{
m_abgr ^= 0x000000ff;
}
else if (_argv[2][0] == 'g')
{
m_abgr ^= 0x0000ff00;
}
else if (_argv[2][0] == 'b')
{
m_abgr ^= 0x00ff0000;
}
else if (_argv[2][0] == 'a')
{
m_alpha ^= true;
}
}
else
{
m_abgr = UINT32_MAX;
m_alpha = false;
}
}
else if (0 == strcmp(_argv[1], "help") )
{
m_help ^= true;
@ -260,8 +294,10 @@ struct View
uint32_t m_fileIndex;
uint32_t m_scaleFn;
uint32_t m_mip;
uint32_t m_abgr;
float m_zoom;
bool m_filter;
bool m_alpha;
bool m_help;
};
@ -294,7 +330,7 @@ struct PosUvColorVertex
bgfx::VertexDecl PosUvColorVertex::ms_decl;
bool screenQuad(int32_t _x, int32_t _y, int32_t _width, uint32_t _height, bool _originBottomLeft = false)
bool screenQuad(int32_t _x, int32_t _y, int32_t _width, uint32_t _height, uint32_t _abgr, bool _originBottomLeft = false)
{
if (bgfx::checkAvailTransientVertexBuffer(6, PosUvColorVertex::ms_decl) )
{
@ -349,12 +385,12 @@ bool screenQuad(int32_t _x, int32_t _y, int32_t _width, uint32_t _height, bool _
vertex[5].m_u = minu;
vertex[5].m_v = minv;
vertex[0].m_abgr = UINT32_MAX;
vertex[1].m_abgr = UINT32_MAX;
vertex[2].m_abgr = UINT32_MAX;
vertex[3].m_abgr = UINT32_MAX;
vertex[4].m_abgr = UINT32_MAX;
vertex[5].m_abgr = UINT32_MAX;
vertex[0].m_abgr = _abgr;
vertex[1].m_abgr = _abgr;
vertex[2].m_abgr = _abgr;
vertex[3].m_abgr = _abgr;
vertex[4].m_abgr = _abgr;
vertex[5].m_abgr = _abgr;
bgfx::setVertexBuffer(&vb);
@ -697,22 +733,26 @@ int _main_(int _argc, char** _argv)
ImGui::Text("Key bindings:\n\n");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "ESC"); ImGui::SameLine(64); ImGui::Text("Exit.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "h"); ImGui::SameLine(64); ImGui::Text("Toggle help screen.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "f"); ImGui::SameLine(64); ImGui::Text("Toggle full-screen.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "ESC"); ImGui::SameLine(64); ImGui::Text("Exit.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "h"); ImGui::SameLine(64); ImGui::Text("Toggle help screen.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "f"); ImGui::SameLine(64); ImGui::Text("Toggle full-screen.");
ImGui::NextLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "-"); ImGui::SameLine(64); ImGui::Text("Zoom out.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "="); ImGui::SameLine(64); ImGui::Text("Zoom in.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "-"); ImGui::SameLine(64); ImGui::Text("Zoom out.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "="); ImGui::SameLine(64); ImGui::Text("Zoom in.");
ImGui::NextLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), ","); ImGui::SameLine(64); ImGui::Text("MIP level up.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "."); ImGui::SameLine(64); ImGui::Text("MIP level down.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "/"); ImGui::SameLine(64); ImGui::Text("Toggle linear/point texture sampling.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), ","); ImGui::SameLine(64); ImGui::Text("MIP level up.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "."); ImGui::SameLine(64); ImGui::Text("MIP level down.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "/"); ImGui::SameLine(64); ImGui::Text("Toggle linear/point texture sampling.");
ImGui::NextLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "up"); ImGui::SameLine(64); ImGui::Text("Previous texture.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "down"); ImGui::SameLine(64); ImGui::Text("Next texture.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "up"); ImGui::SameLine(64); ImGui::Text("Previous texture.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "down"); ImGui::SameLine(64); ImGui::Text("Next texture.");
ImGui::NextLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "r/g/b"); ImGui::SameLine(64); ImGui::Text("Toggle R, G, or B color channel.");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "a"); ImGui::SameLine(64); ImGui::Text("Toggle alpha blending.");
ImGui::NextLine();
ImGui::Dummy(ImVec2(0.0f, 0.0f) );
@ -797,6 +837,7 @@ int _main_(int _argc, char** _argv)
, int(height - view.m_info.height * ss)/2
, int(view.m_info.width * ss)
, int(view.m_info.height * ss)
, view.m_abgr
);
float mtx[16];
@ -821,6 +862,7 @@ int _main_(int _argc, char** _argv)
bgfx::setState(0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| (view.m_alpha ? BGFX_STATE_BLEND_ALPHA : BGFX_STATE_NONE)
);
bgfx::submit(0, view.m_info.cubeMap ? textureCubeProgram : textureProgram);

View File

@ -374,7 +374,7 @@ namespace bx
switch (_whence)
{
case Whence::Begin:
m_pos = _offset;
m_pos = int64_clamp(_offset, 0, m_top);
break;
case Whence::Current:
@ -434,7 +434,7 @@ namespace bx
switch (_whence)
{
case Whence::Begin:
m_pos = _offset;
m_pos = int64_clamp(_offset, 0, m_top);
break;
case Whence::Current:
@ -506,7 +506,7 @@ namespace bx
switch (_whence)
{
case Whence::Begin:
m_pos = _offset;
m_pos = int64_clamp(_offset, 0, m_top);
break;
case Whence::Current:

View File

@ -8,6 +8,9 @@
#if BX_PLATFORM_POSIX
# include <pthread.h>
# if BX_PLATFORM_BSD
# include <pthread_np.h>
# endif
# if defined(__GLIBC__) && !( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12) ) )
# include <sys/prctl.h>
# endif // defined(__GLIBC__) ...
@ -164,7 +167,7 @@ namespace bx
#ifdef __NetBSD__
pthread_setname_np(m_handle, "%s", (void *)_name);
#else
pthread_setname_np(m_handle, _name);
pthread_set_name_np(m_handle, _name);
#endif
#elif BX_PLATFORM_WINDOWS && BX_COMPILER_MSVC
# pragma pack(push, 8)

Binary file not shown.

Binary file not shown.

Binary file not shown.